Index: /tags/2.0.2/about.php
===================================================================
--- /tags/2.0.2/about.php	(revision 3278)
+++ /tags/2.0.2/about.php	(revision 3278)
@@ -0,0 +1,70 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+//----------------------------------------------------------- include
+define('PHPWG_ROOT_PATH','./');
+include_once( PHPWG_ROOT_PATH.'include/common.inc.php' );
+
+// +-----------------------------------------------------------------------+
+// | Check Access and exit when user status is not ok                      |
+// +-----------------------------------------------------------------------+
+check_status(ACCESS_GUEST);
+
+//----------------------------------------------------- template initialization
+//
+// Start output of page
+//
+$title= l10n('about_page_title');
+$page['body_id'] = 'theAboutPage';
+include(PHPWG_ROOT_PATH.'include/page_header.php');
+
+/**
+ * set in ./language/en_UK.iso-8859-1/local.lang.php (maybe to create)
+ * for example for clear theme:
+  $lang['Theme: clear'] = 'This is the clear theme based on yoga template. '.
+  ' A standard template/theme of PhpWebgallery.';
+ *
+ * Don't forget php tags !!!
+ *
+ * Another way is to code it thru the theme itself in ./themeconf.inc.php
+ */
+@include(PHPWG_ROOT_PATH.'template/'.$user['template'].
+  '/theme/'.$user['theme'].'/themeconf.inc.php');
+
+$template->set_filenames(
+  array(
+    'about'=>'about.tpl',
+    )
+  );
+if ( isset($lang['Theme: '.$user['theme']]) )
+{
+  $template->assign(
+    'THEME_ABOUT',l10n('Theme: '.$user['theme'])
+    );
+}
+
+$template->assign('ABOUT_MESSAGE', load_language('about.html','', array('return'=>true)) );
+
+$template->pparse('about');
+include(PHPWG_ROOT_PATH.'include/page_tail.php');
+?>
Index: /tags/2.0.2/action.php
===================================================================
--- /tags/2.0.2/action.php	(revision 3278)
+++ /tags/2.0.2/action.php	(revision 3278)
@@ -0,0 +1,203 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+define('PHPWG_ROOT_PATH','./');
+include_once(PHPWG_ROOT_PATH.'include/common.inc.php');
+
+// Check Access and exit when user status is not ok
+check_status(ACCESS_GUEST);
+
+function guess_mime_type($ext)
+{
+  switch ( strtolower($ext) )
+  {
+    case "jpe": case "jpeg":
+    case "jpg": $ctype="image/jpeg"; break;
+    case "png": $ctype="image/png"; break;
+    case "gif": $ctype="image/gif"; break;
+    case "tiff":
+    case "tif": $ctype="image/tiff"; break;
+    case "txt": $ctype="text/plain"; break;
+    case "html":
+    case "htm": $ctype="text/html"; break;
+    case "xml": $ctype="text/xml"; break;
+    case "pdf": $ctype="application/pdf"; break;
+    case "zip": $ctype="application/zip"; break;
+    case "ogg": $ctype="application/ogg"; break;
+    default: $ctype="application/octet-stream";
+  }
+  return $ctype;
+}
+
+function do_error( $code, $str )
+{
+  set_status_header( $code );
+  echo $str ;
+  exit();
+}
+
+
+if (!isset($_GET['id'])
+    or !is_numeric($_GET['id'])
+    or !isset($_GET['part'])
+    or !in_array($_GET['part'], array('t','e','i','h') ) )
+{
+  do_error(400, 'Invalid request - id/part');
+}
+
+$query = '
+SELECT * FROM '. IMAGES_TABLE.'
+  WHERE id='.$_GET['id'].'
+;';
+
+$result = pwg_query($query);
+$element_info = mysql_fetch_assoc($result);
+if ( empty($element_info) )
+{
+  do_error(404, 'Requested id not found');
+}
+
+// $filter['visible_categories'] and $filter['visible_images']
+// are not used because it's not necessary (filter <> restriction)
+$query='
+SELECT id
+  FROM '.CATEGORIES_TABLE.'
+    INNER JOIN '.IMAGE_CATEGORY_TABLE.' ON category_id = id
+  WHERE image_id = '.$_GET['id'].'
+'.get_sql_condition_FandF(
+  array(
+      'forbidden_categories' => 'category_id',
+      'forbidden_images' => 'image_id',
+    ),
+  '    AND'
+  ).'
+  LIMIT 1
+;';
+if ( mysql_num_rows(pwg_query($query))<1 )
+{
+  do_error(401, 'Access denied');
+}
+
+include_once(PHPWG_ROOT_PATH.'include/functions_picture.inc.php');
+$file='';
+switch ($_GET['part'])
+{
+  case 't':
+    $file = get_thumbnail_path($element_info);
+    break;
+  case 'e':
+    $file = get_element_path($element_info);
+    break;
+  case 'i':
+    $file = get_image_path($element_info);
+    break;
+  case 'h':
+    if ( $user['enabled_high']!='true' )
+    {
+      do_error(401, 'Access denied h');
+    }
+    $file = get_high_path($element_info);
+    break;
+}
+
+if ( empty($file) )
+{
+  do_error(404, 'Requested file not found');
+}
+
+if ($_GET['part'] == 'h') {
+  pwg_log($_GET['id'], 'high');
+}
+else if ($_GET['part'] == 'e')
+{
+  pwg_log($_GET['id'], 'other');
+}
+
+$http_headers = array();
+
+$ctype = null;
+if (!url_is_remote($file))
+{
+  if ( !@is_readable($file) )
+  {
+    do_error(404, "Requested file not found - $file");
+  }
+  $http_headers[] = 'Content-Length: '.@filesize($file);
+  if ( function_exists('mime_content_type') )
+  {
+    $ctype = mime_content_type($file);
+  }
+
+  $gmt_mtime = gmdate('D, d M Y H:i:s', filemtime($file)).' GMT';
+  $http_headers[] = 'Last-Modified: '.$gmt_mtime;
+
+  // following lines would indicate how the client should handle the cache
+  /* $max_age=300;
+  $http_headers[] = 'Expires: '.gmdate('D, d M Y H:i:s', time()+$max_age).' GMT';
+  // HTTP/1.1 only
+  $http_headers[] = 'Cache-Control: private, must-revalidate, max-age='.$max_age;*/
+
+  if ( isset( $_SERVER['HTTP_IF_MODIFIED_SINCE'] ) )
+  {
+    set_status_header(304);
+    foreach ($http_headers as $header)
+    {
+      header( $header );
+    }
+    exit();
+  }
+}
+
+if (!isset($ctype))
+{ // give it a guess
+  $ctype = guess_mime_type( get_extension($file) );
+}
+
+$http_headers[] = 'Content-Type: '.$ctype;
+
+if (!isset($_GET['view']))
+{
+  $http_headers[] = 'Content-Disposition: attachment; filename="'
+            .basename($file).'";';
+  $http_headers[] = 'Content-Transfer-Encoding: binary';
+}
+else
+{
+  $http_headers[] = 'Content-Disposition: inline; filename="'
+            .basename($file).'";';
+}
+
+foreach ($http_headers as $header)
+{
+  header( $header );
+}
+
+// Looking at the safe_mode configuration for execution time
+if (ini_get('safe_mode') == 0)
+{
+  @set_time_limit(0);
+}
+
+@readfile($file);
+
+?>
Index: /tags/2.0.2/admin.php
===================================================================
--- /tags/2.0.2/admin.php	(revision 3278)
+++ /tags/2.0.2/admin.php	(revision 3278)
@@ -0,0 +1,164 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+//----------------------------------------------------------- include
+define('PHPWG_ROOT_PATH','./');
+define('IN_ADMIN', true);
+include_once( PHPWG_ROOT_PATH.'include/common.inc.php' );
+
+include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+include_once(PHPWG_ROOT_PATH.'admin/include/functions_plugins.inc.php');
+
+// +-----------------------------------------------------------------------+
+// | Check Access and exit when user status is not ok                      |
+// +-----------------------------------------------------------------------+
+check_status(ACCESS_ADMINISTRATOR);
+
+// +-----------------------------------------------------------------------+
+// |                    synchronize user informations                      |
+// +-----------------------------------------------------------------------+
+
+sync_users();
+
+// +-----------------------------------------------------------------------+
+// |                            variables init                             |
+// +-----------------------------------------------------------------------+
+
+if (isset($_GET['page'])
+    and preg_match('/^[a-z_]*$/', $_GET['page'])
+    and is_file(PHPWG_ROOT_PATH.'admin/'.$_GET['page'].'.php'))
+{
+  $page['page'] = $_GET['page'];
+}
+else
+{
+  $page['page'] = 'intro';
+}
+
+$page['errors'] = array();
+$page['infos']  = array();
+
+$link_start = PHPWG_ROOT_PATH.'admin.php?page=';
+$conf_link = $link_start.'configuration&amp;section=';
+//----------------------------------------------------- template initialization
+$title = l10n('Piwigo Administration'); // for include/page_header.php
+$page['page_banner'] = '<h1>'.l10n('Piwigo Administration').'</h1>';
+$page['body_id'] = 'theAdminPage';
+
+$template->set_filenames(array('admin' => 'admin.tpl'));
+
+$template->assign(
+  array(
+    'U_SITE_MANAGER'=> $link_start.'site_manager',
+    'U_HISTORY_STAT'=> $link_start.'stats',
+    'U_FAQ'=> $link_start.'help',
+    'U_SITES'=> $link_start.'remote_site',
+    'U_MAINTENANCE'=> $link_start.'maintenance',
+    'U_NOTIFICATION_BY_MAIL'=> $link_start.'notification_by_mail',
+    'U_ADVANCED_FEATURE'=> $link_start.'advanced_feature',
+    'U_CONFIG_GENERAL'=> $link_start.'configuration',
+    'U_CONFIG_DISPLAY'=> $conf_link.'default',
+    'U_CONFIG_EXTENTS'=> $link_start.'extend_for_templates',
+    'U_CONFIG_MENUBAR'=> $link_start.'menubar',
+    'U_CATEGORIES'=> $link_start.'cat_list',
+    'U_MOVE'=> $link_start.'cat_move',
+    'U_CAT_OPTIONS'=> $link_start.'cat_options',
+    'U_CAT_UPDATE'=> $link_start.'site_update&amp;site=1',
+    'U_WAITING'=> $link_start.'comments',
+    'U_RATING'=> $link_start.'rating',
+    'U_CADDIE'=> $link_start.'element_set&amp;cat=caddie',
+    'U_RECENT_SET'=> $link_start.'element_set&amp;cat=recent',
+    'U_TAGS'=> $link_start.'tags',
+    'U_THUMBNAILS'=> $link_start.'thumbnail',
+    'U_USERS'=> $link_start.'user_list',
+    'U_GROUPS'=> $link_start.'group_list',
+    'U_PERMALINKS'=> $link_start.'permalinks',
+    'U_RETURN'=> make_index_url(),
+    'U_ADMIN'=> PHPWG_ROOT_PATH.'admin.php',
+    'U_PLUGINS'=> $link_start.'plugins_list',
+    )
+  );
+
+//---------------------------------------------------------------- plugin menus
+$plugin_menu_links = trigger_event('get_admin_plugin_menu_links', array() );
+
+function UC_name_compare($a, $b)
+{
+  return strcmp(strtolower($a['NAME']), strtolower($b['NAME']));
+}
+usort($plugin_menu_links, 'UC_name_compare');
+$template->assign('plugin_menu_items', $plugin_menu_links);
+
+include(PHPWG_ROOT_PATH.'admin/'.$page['page'].'.php');
+
+//------------------------------------------------------------- content display
+
+// +-----------------------------------------------------------------------+
+// |                            errors & infos                             |
+// +-----------------------------------------------------------------------+
+
+if (count($page['errors']) != 0)
+{
+  $template->assign('errors', $page['errors']);
+}
+
+if (count($page['infos']) != 0)
+{
+  $template->assign('infos', $page['infos']);
+}
+
+// Add the Piwigo Official menu
+  $template->assign( 'pwgmenu', pwg_URL() );
+
+include(PHPWG_ROOT_PATH.'include/page_header.php');
+$template->pparse('admin');
+
+// +-----------------------------------------------------------------------+
+// |                     order permission refreshment                      |
+// +-----------------------------------------------------------------------+
+// Only for pages witch change permissions
+if (
+    in_array($page['page'],
+      array(
+        'site_manager', // delete site
+        'site_update',  // ?only POST
+        'cat_list',     // delete cat
+        'cat_modify',   // delete cat; public/private; lock/unlock
+        'cat_move',     // ?only POST
+        'cat_options',  // ?only POST; public/private; lock/unlock
+        'cat_perm',     // ?only POST
+        'element_set',  // ?only POST; associate/dissociate
+        'picture_modify', // ?only POST; associate/dissociate
+        'user_list',    // ?only POST; group assoc
+        'user_perm',
+        'group_perm',
+        'group_list',   // delete group
+      )
+    )
+  )
+{
+  invalidate_user_cache();
+}
+
+include(PHPWG_ROOT_PATH.'include/page_tail.php');
+?>
Index: /tags/2.0.2/admin/advanced_feature.php
===================================================================
--- /tags/2.0.2/admin/advanced_feature.php	(revision 3278)
+++ /tags/2.0.2/admin/advanced_feature.php	(revision 3278)
@@ -0,0 +1,108 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die ("Hacking attempt!");
+}
+
+// +-----------------------------------------------------------------------+
+// | Check Access and exit when user status is not ok                      |
+// +-----------------------------------------------------------------------+
+check_status(ACCESS_ADMINISTRATOR);
+
+// +-----------------------------------------------------------------------+
+// | Actions                                                               |
+// +-----------------------------------------------------------------------+
+
+/*$action = (isset($_GET['action']) and !is_adviser()) ? $_GET['action'] : '';
+
+switch ($action)
+{
+  case '???' :
+  {
+    break;
+  }
+  default :
+  {
+    break;
+  }
+}*/
+
+// +-----------------------------------------------------------------------+
+// | Define advanced features                                              |
+// +-----------------------------------------------------------------------+
+
+$advanced_features = array();
+
+// Add advanced features
+/*array_push($advanced_features,
+  array
+  (
+    'CAPTION' => l10n('???'),
+    'URL' => $start_url.'???'
+  ));*/
+
+array_push($advanced_features,
+  array
+  (
+    'CAPTION' => l10n('Elements_not_linked'),
+    'URL' => get_root_url().'admin.php?page=element_set&amp;cat=not_linked'
+  ));
+
+array_push($advanced_features,
+  array
+  (
+    'CAPTION' => l10n('Duplicates'),
+    'URL' => get_root_url().'admin.php?page=element_set&amp;cat=duplicates'
+  ));
+
+//$advanced_features is array of array composed of CAPTION & URL
+$advanced_features = 
+    trigger_event('get_admin_advanced_features_links', $advanced_features);
+
+// +-----------------------------------------------------------------------+
+// |  Template init                                                        |
+// +-----------------------------------------------------------------------+
+
+$template->set_filename('advanced_feature', 'advanced_feature.tpl');
+
+$start_url = get_root_url().'admin.php?page=advanced_feature&amp;action=';
+
+$template->assign(
+  array
+  (
+    'U_HELP' => get_root_url().'popuphelp.php?page=advanced_feature',
+    'U_ACTIVE_MENU' => 5
+  ));
+
+// advanced_features
+$template->assign('advanced_features', $advanced_features);
+
+// +-----------------------------------------------------------------------+
+// | Sending html code                                                     |
+// +-----------------------------------------------------------------------+
+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'advanced_feature');
+
+?>
Index: /tags/2.0.2/admin/cat_list.php
===================================================================
--- /tags/2.0.2/admin/cat_list.php	(revision 3278)
+++ /tags/2.0.2/admin/cat_list.php	(revision 3278)
@@ -0,0 +1,258 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+
+// +-----------------------------------------------------------------------+
+// | Check Access and exit when user status is not ok                      |
+// +-----------------------------------------------------------------------+
+check_status(ACCESS_ADMINISTRATOR);
+
+// +-----------------------------------------------------------------------+
+// |                               functions                               |
+// +-----------------------------------------------------------------------+
+
+/**
+ * save the rank depending on given categories order
+ *
+ * The list of ordered categories id is supposed to be in the same parent
+ * category
+ *
+ * @param array categories
+ * @return void
+ */
+function save_categories_order($categories)
+{
+  $current_rank = 0;
+  $datas = array();
+  foreach ($categories as $id)
+  {
+    array_push($datas, array('id' => $id, 'rank' => ++$current_rank));
+  }
+  $fields = array('primary' => array('id'), 'update' => array('rank'));
+  mass_updates(CATEGORIES_TABLE, $fields, $datas);
+
+  update_global_rank();
+}
+
+// +-----------------------------------------------------------------------+
+// |                            initialization                             |
+// +-----------------------------------------------------------------------+
+
+$categories = array();
+
+$base_url = get_root_url().'admin.php?page=cat_list';
+$navigation = '<a href="'.$base_url.'">';
+$navigation.= l10n('home');
+$navigation.= '</a>';
+
+// +-----------------------------------------------------------------------+
+// |                    virtual categories management                      |
+// +-----------------------------------------------------------------------+
+// request to delete a virtual category / not for an adviser
+if (isset($_GET['delete']) and is_numeric($_GET['delete']) and !is_adviser())
+{
+  delete_categories(array($_GET['delete']));
+  array_push($page['infos'], l10n('cat_virtual_deleted'));
+  update_global_rank();
+}
+// request to add a virtual category
+else if (isset($_POST['submitAdd']))
+{
+  $output_create = create_virtual_category(
+    $_POST['virtual_name'],
+    @$_GET['parent_id']
+    );
+
+  if (isset($output_create['error']))
+  {
+    array_push($page['errors'], $output_create['error']);
+  }
+  else
+  {
+    array_push($page['infos'], $output_create['info']);
+  }
+}
+// save manual category ordering
+else if (isset($_POST['submitOrder']))
+{
+  asort($_POST['catOrd'], SORT_NUMERIC);
+  save_categories_order(array_keys($_POST['catOrd']));
+
+  array_push(
+    $page['infos'],
+    l10n('Categories manual order was saved')
+    );
+}
+// sort categories alpha-numerically
+else if (isset($_POST['submitOrderAlphaNum']))
+{
+  $query = '
+SELECT id, name
+  FROM '.CATEGORIES_TABLE.'
+  WHERE id_uppercat '.
+    (!isset($_GET['parent_id']) ? 'IS NULL' : '= '.$_GET['parent_id']).'
+;';
+  $result = pwg_query($query);
+  while ($row = mysql_fetch_assoc($result))
+  {
+    $categories[ $row['id'] ] = strtolower($row['name']);
+  }
+
+  asort($categories, SORT_REGULAR);
+  save_categories_order(array_keys($categories));
+
+  array_push(
+    $page['infos'],
+    l10n('Categories ordered alphanumerically')
+    );
+}
+
+// +-----------------------------------------------------------------------+
+// |                            Navigation path                            |
+// +-----------------------------------------------------------------------+
+
+if (isset($_GET['parent_id']))
+{
+  $navigation.= $conf['level_separator'];
+
+  $navigation.= get_cat_display_name_from_id(
+    $_GET['parent_id'],
+    $base_url.'&amp;parent_id=',
+    false
+    );
+}
+// +-----------------------------------------------------------------------+
+// |                       template initialization                         |
+// +-----------------------------------------------------------------------+
+$template->set_filename('categories', 'cat_list.tpl');
+
+$form_action = PHPWG_ROOT_PATH.'admin.php?page=cat_list';
+if (isset($_GET['parent_id']))
+{
+  $form_action.= '&amp;parent_id='.$_GET['parent_id'];
+}
+
+$template->assign(array(
+  'CATEGORIES_NAV'=>$navigation,
+  'F_ACTION'=>$form_action,
+ ));
+
+// +-----------------------------------------------------------------------+
+// |                          Categories display                           |
+// +-----------------------------------------------------------------------+
+
+$categories = array();
+
+$query = '
+SELECT id, name, permalink, dir, rank, status
+  FROM '.CATEGORIES_TABLE;
+if (!isset($_GET['parent_id']))
+{
+  $query.= '
+  WHERE id_uppercat IS NULL';
+}
+else
+{
+  $query.= '
+  WHERE id_uppercat = '.$_GET['parent_id'];
+}
+$query.= '
+  ORDER BY rank ASC
+;';
+$categories = hash_from_query($query, 'id');
+
+// get the categories containing images directly 
+$categories_with_images = array();
+if ( count($categories) )
+{
+  $query = '
+SELECT DISTINCT category_id 
+  FROM '.IMAGE_CATEGORY_TABLE.'
+  WHERE category_id IN ('.implode(',', array_keys($categories)).')';
+  $categories_with_images = array_flip( array_from_query($query, 'category_id') );
+}
+
+$template->assign('categories', array());
+$base_url = get_root_url().'admin.php?page=';
+foreach ($categories as $category)
+{
+  $cat_list_url = $base_url.'cat_list';
+
+  $self_url = $cat_list_url;
+  if (isset($_GET['parent_id']))
+  {
+    $self_url.= '&amp;parent_id='.$_GET['parent_id'];
+  }
+
+  $tpl_cat =
+    array(
+      'NAME'       => 
+        trigger_event(
+          'render_category_name',
+          $category['name'],
+          'admin_cat_list'
+          ),
+      'ID'         => $category['id'],
+      'RANK'       => $category['rank']*10,
+
+      'U_JUMPTO'   => make_index_url(
+        array(
+          'category' => $category
+          )
+        ),
+
+      'U_CHILDREN' => $cat_list_url.'&amp;parent_id='.$category['id'],
+      'U_EDIT'     => $base_url.'cat_modify&amp;cat_id='.$category['id'],
+
+      'IS_VIRTUAL' => empty($category['dir'])
+    );
+
+  if (empty($category['dir']))
+  {
+    $tpl_cat['U_DELETE'] = $self_url.'&amp;delete='.$category['id'];
+  }
+
+  if ( array_key_exists($category['id'], $categories_with_images) )
+  {
+    $tpl_cat['U_MANAGE_ELEMENTS']=
+      $base_url.'element_set&amp;cat='.$category['id'];
+  }
+
+  if ('private' == $category['status'])
+  {
+    $tpl_cat['U_MANAGE_PERMISSIONS']=
+      $base_url.'cat_perm&amp;cat='.$category['id'];
+  }
+  $template->append('categories', $tpl_cat);
+}
+// +-----------------------------------------------------------------------+
+// |                          sending html code                            |
+// +-----------------------------------------------------------------------+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'categories');
+?>
Index: /tags/2.0.2/admin/cat_modify.php
===================================================================
--- /tags/2.0.2/admin/cat_modify.php	(revision 3278)
+++ /tags/2.0.2/admin/cat_modify.php	(revision 3278)
@@ -0,0 +1,561 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+include_once(PHPWG_ROOT_PATH.'include/functions_mail.inc.php');
+
+// +-----------------------------------------------------------------------+
+// | Check Access and exit when user status is not ok                      |
+// +-----------------------------------------------------------------------+
+check_status(ACCESS_ADMINISTRATOR);
+
+//---------------------------------------------------------------- verification
+if ( !isset( $_GET['cat_id'] ) || !is_numeric( $_GET['cat_id'] ) )
+{
+  trigger_error( 'missing cat_id param', E_USER_ERROR);
+}
+
+//--------------------------------------------------------- form criteria check
+if (isset($_POST['submit']))
+{
+  $image_order = null;
+  if ( !isset($_POST['image_order_default']) )
+  {
+    for ($i=1; $i<=3; $i++)
+    {
+      if ( !empty($_POST['order_field_'.$i]) )
+      {
+        if (! empty($image_order) )
+        {
+          $image_order .= ',';
+        }
+        $image_order .= $_POST['order_field_'.$i];
+        if ($_POST['order_direction_'.$i]=='DESC')
+        {
+          $image_order .= ' DESC';
+        }
+      }
+    }
+  }
+
+  $data =
+    array(
+      'id' => $_GET['cat_id'],
+      'name' => @$_POST['name'],
+      'commentable' => $_POST['commentable'],
+      'uploadable' =>
+        isset($_POST['uploadable']) ? $_POST['uploadable'] : 'false',
+      'comment' =>
+        $conf['allow_html_descriptions'] ?
+          @$_POST['comment'] : strip_tags(@$_POST['comment']),
+      'image_order' => $image_order,
+      );
+
+  mass_updates(
+    CATEGORIES_TABLE,
+    array(
+      'primary' => array('id'),
+      'update' => array_diff(array_keys($data), array('id'))
+      ),
+    array($data)
+    );
+
+  // retrieve cat infos before continuing (following updates are expensive)
+  $cat_info = get_cat_info($_GET['cat_id']);
+
+  if (isset($_POST['image_order_subcats']))
+  {
+    $query = '
+UPDATE '.CATEGORIES_TABLE.' SET image_order='.(isset($image_order) ? 'NULL':"'$image_order'").'
+  WHERE uppercats LIKE "'.$cat_info['uppercats'].',%"';
+    pwg_query($query);
+  }
+
+  if ($cat_info['visible'] != get_boolean( $_POST['visible'] ) )
+  {
+    set_cat_visible(array($_GET['cat_id']), $_POST['visible']);
+  }
+  if ($cat_info['status'] != $_POST['status'] )
+  {
+    set_cat_status(array($_GET['cat_id']), $_POST['status']);
+  }
+
+  if (isset($_POST['parent']) and $cat_info['id_uppercat'] != $_POST['parent'])
+  {
+    move_categories( array($_GET['cat_id']), $_POST['parent'] );
+  }
+
+  array_push($page['infos'], l10n('editcat_confirm'));
+}
+elseif (isset($_POST['set_random_representant']))
+{
+  set_random_representant(array($_GET['cat_id']));
+}
+elseif (isset($_POST['delete_representant']))
+{
+  $query = '
+UPDATE '.CATEGORIES_TABLE.'
+  SET representative_picture_id = NULL
+  WHERE id = '.$_GET['cat_id'].'
+;';
+  pwg_query($query);
+}
+elseif (isset($_POST['submitAdd']))
+{
+  $output_create = create_virtual_category(
+    $_POST['virtual_name'],
+    (0 == $_POST['parent'] ? null : $_POST['parent'])
+    );
+
+  if (isset($output_create['error']))
+  {
+    array_push($page['errors'], $output_create['error']);
+  }
+  else
+  {
+    // Virtual category creation succeeded
+    //
+    // Add the information in the information list
+    array_push($page['infos'], $output_create['info']);
+
+    // Link the new category to the current category
+    associate_categories_to_categories(
+      array($_GET['cat_id']),
+      array($output_create['id'])
+      );
+
+    // information
+    array_push(
+      $page['infos'],
+      sprintf(
+        l10n('Category elements associated to the following categories: %s'),
+        '<ul><li>'
+        .get_cat_display_name_from_id($output_create['id'])
+        .'</li></ul>'
+        )
+      );
+  }
+}
+elseif (isset($_POST['submitDestinations'])
+         and isset($_POST['destinations'])
+         and count($_POST['destinations']) > 0)
+{
+  associate_categories_to_categories(
+    array($_GET['cat_id']),
+    $_POST['destinations']
+    );
+
+  $category_names = array();
+  foreach ($_POST['destinations'] as $category_id)
+  {
+    array_push(
+      $category_names,
+      get_cat_display_name_from_id($category_id)
+      );
+  }
+
+  array_push(
+    $page['infos'],
+    sprintf(
+      l10n('Category elements associated to the following categories: %s'),
+      '<ul><li>'.implode('</li><li>', $category_names).'</li></ul>'
+      )
+    );
+}
+
+$query = '
+SELECT *
+  FROM '.CATEGORIES_TABLE.'
+  WHERE id = '.$_GET['cat_id'].'
+;';
+$category = mysql_fetch_array( pwg_query( $query ) );
+// nullable fields
+foreach (array('comment','dir','site_id', 'id_uppercat') as $nullable)
+{
+  if (!isset($category[$nullable]))
+  {
+    $category[$nullable] = '';
+  }
+}
+
+$category['is_virtual'] = empty($category['dir']) ? true : false;
+
+$query = 'SELECT DISTINCT category_id
+  FROM '.IMAGE_CATEGORY_TABLE.'
+  WHERE category_id = '.$_GET['cat_id'].'
+  LIMIT 1';
+$result = pwg_query($query);
+$category['has_images'] = mysql_num_rows($result)>0 ? true : false;
+
+// Navigation path
+$navigation = get_cat_display_name_cache(
+  $category['uppercats'],
+  get_root_url().'admin.php?page=cat_modify&amp;cat_id='
+  );
+
+$form_action = get_root_url().'admin.php?page=cat_modify&amp;cat_id='.$_GET['cat_id'];
+
+//----------------------------------------------------- template initialization
+$template->set_filename( 'categories', 'cat_modify.tpl');
+
+$base_url = get_root_url().'admin.php?page=';
+$cat_list_url = $base_url.'cat_list';
+
+$self_url = $cat_list_url;
+if (!empty($category['id_uppercat']))
+{
+  $self_url.= '&amp;parent_id='.$category['id_uppercat'];
+}
+
+$template->assign(
+  array(
+    'CATEGORIES_NAV'     => $navigation,
+    'CAT_ID'             => $category['id'],
+    'CAT_NAME'           => @htmlspecialchars($category['name']),
+    'CAT_COMMENT'        => @htmlspecialchars($category['comment']),
+
+    'status_values'     => array('public','private'),
+
+    'CAT_STATUS'        => $category['status'],
+    'CAT_VISIBLE'       => $category['visible'],
+    'CAT_COMMENTABLE'   => $category['commentable'],
+    'CAT_UPLOADABLE'    => $category['uploadable'],
+
+    'IMG_ORDER_DEFAULT'  => empty($category['image_order']) ?
+                              'checked="checked"' : '',
+
+    'U_JUMPTO' => make_index_url(
+      array(
+        'category' => $category
+        )
+      ),
+
+    'MAIL_CONTENT' => empty($_POST['mail_content'])
+        ? '' : stripslashes($_POST['mail_content']),
+    'U_CHILDREN' => $cat_list_url.'&amp;parent_id='.$category['id'],
+    'U_HELP' => get_root_url().'popuphelp.php?page=cat_modify',
+
+    'F_ACTION' => $form_action,
+    )
+  );
+
+
+if ('private' == $category['status'])
+{
+  $template->assign( 'U_MANAGE_PERMISSIONS',
+      $base_url.'cat_perm&amp;cat='.$category['id']
+    );
+}
+
+// manage category elements link
+if ($category['has_images'])
+{
+  $template->assign(
+    'U_MANAGE_ELEMENTS',
+    $base_url.'element_set&amp;cat='.$category['id']
+    );
+  $template->assign(
+    'U_MANAGE_RANKS',
+    $base_url.'element_set_ranks&amp;cat_id='.$category['id']
+    );
+}
+
+if ($category['is_virtual'])
+{
+  $template->assign(
+    array(
+      'U_DELETE' => $self_url.'&amp;delete='.$category['id'],
+      )
+    );
+}
+else
+{
+  $category['cat_full_dir'] = get_complete_dir($_GET['cat_id']);
+  $template->assign(
+    array(
+      'CAT_FULL_DIR'       => preg_replace('/\/$/',
+                                    '',
+                                    $category['cat_full_dir'] )
+      )
+    );
+  if (!url_is_remote($category['cat_full_dir']) )
+  {
+    $template->assign('SHOW_UPLOADABLE', true);
+  }
+}
+
+// image order management
+
+$sort_fields = array(
+  '' => '',
+  'date_creation' => l10n('Creation date'),
+  'date_available' => l10n('Post date'),
+  'average_rate' => l10n('Average rate'),
+  'hit' => l10n('most_visited_cat'),
+  'file' => l10n('File name'),
+  'id' => 'Id',
+  'rank' => l10n('Rank'),
+  );
+
+$sort_directions = array(
+  'ASC' => l10n('ascending'),
+  'DESC' => l10n('descending'),
+  );
+
+$template->assign( 'image_order_field_options', $sort_fields);
+$template->assign( 'image_order_direction_options', $sort_directions);
+
+$matches = array();
+if ( !empty( $category['image_order'] ) )
+{
+  preg_match_all('/([a-z_]+) *(?:(asc|desc)(?:ending)?)? *(?:, *|$)/i',
+    $category['image_order'], $matches);
+}
+
+for ($i=0; $i<3; $i++) // 3 fields
+{
+  $tpl_image_order_select = array(
+      'ID' => $i+1,
+      'FIELD' => array(''),
+      'DIRECTION' => array('ASC'),
+    );
+  
+  if ( isset($matches[1][$i]) )
+  {
+    $tpl_image_order_select['FIELD'] = array($matches[1][$i]);
+  }
+  
+  if (isset($matches[2][$i]) and strcasecmp($matches[2][$i],'DESC')==0)
+  {
+    $tpl_image_order_select['DIRECTION'] = array('DESC');
+  }
+  $template->append( 'image_orders', $tpl_image_order_select);
+}
+
+
+// representant management
+if ($category['has_images']
+    or !empty($category['representative_picture_id']))
+{
+  $tpl_representant = array();
+
+  // picture to display : the identified representant or the generic random
+  // representant ?
+  if (!empty($category['representative_picture_id']))
+  {
+    $query = '
+SELECT id,tn_ext,path
+  FROM '.IMAGES_TABLE.'
+  WHERE id = '.$category['representative_picture_id'].'
+;';
+    $row = mysql_fetch_array(pwg_query($query));
+    $src = get_thumbnail_url($row);
+    $url = get_root_url().'admin.php?page=picture_modify';
+    $url.= '&amp;image_id='.$category['representative_picture_id'];
+
+    $tpl_representant['picture'] =
+      array(
+        'SRC' => $src,
+        'URL' => $url
+      );
+  }
+
+  // can the admin choose to set a new random representant ?
+  $tpl_representant['ALLOW_SET_RANDOM'] = ($category['has_images']) ? true : false;
+
+  // can the admin delete the current representant ?
+  if (
+    ($category['has_images']
+     and $conf['allow_random_representative'])
+    or
+    (!$category['has_images']
+     and !empty($category['representative_picture_id'])))
+  {
+    $tpl_representant['ALLOW_DELETE'] = true;
+  }
+  $template->assign('representant', $tpl_representant);
+}
+
+if ($category['is_virtual'])
+{
+  // the category can be moved in any category but in itself, in any
+  // sub-category
+  $unmovables = get_subcat_ids(array($category['id']));
+
+  $query = '
+SELECT id,name,uppercats,global_rank
+  FROM '.CATEGORIES_TABLE.'
+  WHERE id NOT IN ('.implode(',', $unmovables).')
+;';
+
+  display_select_cat_wrapper(
+    $query,
+    empty($category['id_uppercat']) ? array() : array($category['id_uppercat']),
+    'move_cat_options'
+    );
+}
+
+
+// create virtual in parent and link
+$query = '
+SELECT id,name,uppercats,global_rank
+  FROM '.CATEGORIES_TABLE.'
+;';
+display_select_cat_wrapper(
+  $query,
+  array(),
+  'create_new_parent_options'
+  );
+
+
+// destination categories
+$query = '
+SELECT id,name,uppercats,global_rank
+  FROM '.CATEGORIES_TABLE.'
+  WHERE id != '.$category['id'].'
+;';
+display_select_cat_wrapper(
+  $query,
+  array(),
+  'category_destination_options'
+  );
+
+// info by email to an access granted group of category informations
+if (isset($_POST['submitEmail']) and !empty($_POST['group']))
+{
+  set_make_full_url();
+
+  /* TODO: if $category['representative_picture_id'] 
+    is empty find child representative_picture_id */
+  if (!empty($category['representative_picture_id']))
+  {
+    $query = '
+SELECT id, file, path, tn_ext
+  FROM '.IMAGES_TABLE.'
+  WHERE id = '.$category['representative_picture_id'].'
+;';
+
+    $result = pwg_query($query);
+    if (mysql_num_rows($result) > 0)
+    {
+      $element = mysql_fetch_assoc($result);
+
+      $img_url  = '<a href="'.
+                      make_picture_url(array(
+                          'image_id' => $element['id'],
+                          'image_file' => $element['file'],
+                          'category' => $category
+                        ))
+                      .'" class="thumblnk"><img src="'.get_thumbnail_url($element).'"/></a>';
+    }
+  }
+  
+  if (!isset($img_url))
+  {
+    $img_url = '';
+  }
+
+  // TODO Mettre un array pour traduction subjet
+  pwg_mail_group(
+    $_POST['group'],
+    get_str_email_format(true), /* TODO add a checkbox in order to choose format*/
+    get_l10n_args('[%s] Come to visit the category %s',
+      array($conf['gallery_title'], $category['name'])),
+    'cat_group_info',
+    array
+    (
+      'IMG_URL' => $img_url,
+      'CAT_NAME' => $category['name'],
+      'LINK' => make_index_url(
+          array(
+            'category' => array(
+              'id' => $category['id'],
+              'name' => $category['name'],
+              'permalink' => $category['permalink']
+              ))),
+      'CPL_CONTENT' => empty($_POST['mail_content'])
+                          ? '' : stripslashes($_POST['mail_content'])
+    ),
+    '' /* TODO Add listbox in order to choose Language selected */);
+
+  unset_make_full_url();
+
+  $query = '
+SELECT
+    name
+  FROM '.GROUPS_TABLE.'
+  WHERE id = '.$_POST['group'].'
+;';
+  list($group_name) = mysql_fetch_row(pwg_query($query));
+  
+  array_push(
+    $page['infos'],
+    sprintf(
+      l10n('An information email was sent to group "%s"'),
+      $group_name
+      )
+    );
+}
+
+if ('private' == $category['status'])
+{
+  $query = '
+SELECT
+    group_id
+  FROM '.GROUP_ACCESS_TABLE.'
+  WHERE cat_id = '.$category['id'].'
+;';
+}
+else
+{
+  $query = '
+SELECT
+    id AS group_id
+  FROM '.GROUPS_TABLE.'
+;';
+}
+$group_ids = array_from_query($query, 'group_id');
+
+if (count($group_ids) > 0)
+{
+  $query = '
+SELECT
+    id,
+    name
+  FROM '.GROUPS_TABLE.'
+  WHERE id IN ('.implode(',', $group_ids).')
+  ORDER BY name ASC
+;';
+  $template->assign('group_mail_options',
+      simple_hash_from_query($query, 'id', 'name')
+    );
+}
+
+//----------------------------------------------------------- sending html code
+$template->assign_var_from_handle('ADMIN_CONTENT', 'categories');
+?>
Index: /tags/2.0.2/admin/cat_move.php
===================================================================
--- /tags/2.0.2/admin/cat_move.php	(revision 3278)
+++ /tags/2.0.2/admin/cat_move.php	(revision 3278)
@@ -0,0 +1,104 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+
+// +-----------------------------------------------------------------------+
+// | Check Access and exit when user status is not ok                      |
+// +-----------------------------------------------------------------------+
+check_status(ACCESS_ADMINISTRATOR);
+
+// +-----------------------------------------------------------------------+
+// |                               functions                               |
+// +-----------------------------------------------------------------------+
+
+
+// +-----------------------------------------------------------------------+
+// |                          categories movement                          |
+// +-----------------------------------------------------------------------+
+
+if (isset($_POST['submit']))
+{
+  if (count($_POST['selection']) > 0)
+  {
+    // TODO: tests
+    move_categories($_POST['selection'], $_POST['parent']);
+  }
+  else
+  {
+    array_push(
+      $page['errors'],
+      l10n('Select at least one category')
+      );
+  }
+}
+
+// +-----------------------------------------------------------------------+
+// |                       template initialization                         |
+// +-----------------------------------------------------------------------+
+$template->set_filename('cat_move', 'cat_move.tpl');
+
+$template->assign(
+  array(
+    'U_HELP' => PHPWG_ROOT_PATH.'popuphelp.php?page=cat_move',
+    'F_ACTION' => PHPWG_ROOT_PATH.'admin.php?page=cat_move',
+    )
+  );
+  
+// +-----------------------------------------------------------------------+
+// |                          Categories display                           |
+// +-----------------------------------------------------------------------+
+
+$query = '
+SELECT id,name,uppercats,global_rank
+  FROM '.CATEGORIES_TABLE.'
+  WHERE dir IS NULL
+;';
+display_select_cat_wrapper(
+  $query,
+  array(),
+  'category_to_move_options'
+  );
+
+$query = '
+SELECT id,name,uppercats,global_rank
+  FROM '.CATEGORIES_TABLE.'
+;';
+
+display_select_cat_wrapper(
+  $query,
+  array(),
+  'category_parent_options'
+  );
+
+// +-----------------------------------------------------------------------+
+// |                          sending html code                            |
+// +-----------------------------------------------------------------------+
+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'cat_move');
+?>
Index: /tags/2.0.2/admin/cat_options.php
===================================================================
--- /tags/2.0.2/admin/cat_options.php	(revision 3278)
+++ /tags/2.0.2/admin/cat_options.php	(revision 3278)
@@ -0,0 +1,312 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die ("Hacking attempt!");
+}
+
+include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+include_once(PHPWG_ROOT_PATH.'admin/include/tabsheet.class.php');
+
+// +-----------------------------------------------------------------------+
+// | Check Access and exit when user status is not ok                      |
+// +-----------------------------------------------------------------------+
+check_status(ACCESS_ADMINISTRATOR);
+
+// +-----------------------------------------------------------------------+
+// |                       modification registration                       |
+// +-----------------------------------------------------------------------+
+
+// print '<pre>';
+// print_r($_POST);
+// print '</pre>';
+if (isset($_POST['falsify'])
+    and isset($_POST['cat_true'])
+    and count($_POST['cat_true']) > 0)
+{
+  switch ($_GET['section'])
+  {
+    case 'upload' :
+    {
+      $query = '
+UPDATE '.CATEGORIES_TABLE.'
+  SET uploadable = \'false\'
+  WHERE id IN ('.implode(',', $_POST['cat_true']).')
+;';
+      pwg_query($query);
+      break;
+    }
+    case 'comments' :
+    {
+      $query = '
+UPDATE '.CATEGORIES_TABLE.'
+  SET commentable = \'false\'
+  WHERE id IN ('.implode(',', $_POST['cat_true']).')
+;';
+      pwg_query($query);
+      break;
+    }
+    case 'visible' :
+    {
+      set_cat_visible($_POST['cat_true'], 'false');
+      break;
+    }
+    case 'status' :
+    {
+      set_cat_status($_POST['cat_true'], 'private');
+      break;
+    }
+    case 'representative' :
+    {
+      $query = '
+UPDATE '.CATEGORIES_TABLE.'
+  SET representative_picture_id = NULL
+  WHERE id IN ('.implode(',', $_POST['cat_true']).')
+;';
+      pwg_query($query);
+      break;
+    }
+  }
+}
+else if (isset($_POST['trueify'])
+         and isset($_POST['cat_false'])
+         and count($_POST['cat_false']) > 0)
+{
+  switch ($_GET['section'])
+  {
+    case 'upload' :
+    {
+      $query = '
+UPDATE '.CATEGORIES_TABLE.'
+  SET uploadable = \'true\'
+  WHERE id IN ('.implode(',', $_POST['cat_false']).')
+;';
+      pwg_query($query);
+      break;
+    }
+    case 'comments' :
+    {
+      $query = '
+UPDATE '.CATEGORIES_TABLE.'
+  SET commentable = \'true\'
+  WHERE id IN ('.implode(',', $_POST['cat_false']).')
+;';
+      pwg_query($query);
+      break;
+    }
+    case 'visible' :
+    {
+      set_cat_visible($_POST['cat_false'], 'true');
+      break;
+    }
+    case 'status' :
+    {
+      set_cat_status($_POST['cat_false'], 'public');
+      break;
+    }
+    case 'representative' :
+    {
+      // theoretically, all categories in $_POST['cat_false'] contain at
+      // least one element, so Piwigo can find a representant.
+      set_random_representant($_POST['cat_false']);
+      break;
+    }
+  }
+}
+
+// +-----------------------------------------------------------------------+
+// |                             template init                             |
+// +-----------------------------------------------------------------------+
+
+$template->set_filenames(
+  array(
+    'cat_options' => 'cat_options.tpl',
+    'double_select' => 'double_select.tpl'
+    )
+  );
+
+$page['section'] = isset($_GET['section']) ? $_GET['section'] : 'status';
+$base_url = PHPWG_ROOT_PATH.'admin.php?page=cat_options&amp;section=';
+
+$template->assign(
+  array(
+    'U_HELP' => PHPWG_ROOT_PATH.'/popuphelp.php?page=cat_options',
+    'F_ACTION'=>$base_url.$page['section']
+   )
+ );
+
+// TabSheet
+$tabsheet = new tabsheet();
+// TabSheet initialization
+$opt_link = $link_start.'cat_options&amp;section=';
+$tabsheet->add('status', l10n('cat_security'), $opt_link.'status');
+$tabsheet->add('visible', l10n('lock'), $opt_link.'visible');
+$tabsheet->add('upload', l10n('upload'), $opt_link.'upload');
+$tabsheet->add('comments', l10n('comments'), $opt_link.'comments');
+if ($conf['allow_random_representative'])
+{
+  $tabsheet->add('representative', l10n('Representative'), $opt_link.'representative');
+}
+// TabSheet selection
+$tabsheet->select($page['section']);
+// Assign tabsheet to template
+$tabsheet->assign();
+
+// +-----------------------------------------------------------------------+
+// |                              form display                             |
+// +-----------------------------------------------------------------------+
+
+// for each section, categories in the multiselect field can be :
+//
+// - true : uploadable for upload section
+// - false : un-uploadable for upload section
+// - NA : (not applicable) for virtual categories
+//
+// for true and false status, we associates an array of category ids,
+// function display_select_categories will use the given CSS class for each
+// option
+$cats_true = array();
+$cats_false = array();
+switch ($page['section'])
+{
+  case 'upload' :
+  {
+    $query_true = '
+SELECT id,name,uppercats,global_rank
+  FROM '.CATEGORIES_TABLE.'
+  WHERE uploadable = \'true\'
+    AND dir IS NOT NULL
+    AND site_id = 1
+;';
+    $query_false = '
+SELECT id,name,uppercats,global_rank
+  FROM '.CATEGORIES_TABLE.'
+  WHERE uploadable = \'false\'
+    AND dir IS NOT NULL
+    AND site_id = 1
+;';
+    $template->assign(
+      array(
+        'L_SECTION' => l10n('cat_upload_title'),
+        'L_CAT_OPTIONS_TRUE' => l10n('authorized'),
+        'L_CAT_OPTIONS_FALSE' => l10n('forbidden'),
+        )
+      );
+    break;
+  }
+  case 'comments' :
+  {
+    $query_true = '
+SELECT id,name,uppercats,global_rank
+  FROM '.CATEGORIES_TABLE.'
+  WHERE commentable = \'true\'
+;';
+    $query_false = '
+SELECT id,name,uppercats,global_rank
+  FROM '.CATEGORIES_TABLE.'
+  WHERE commentable = \'false\'
+;';
+    $template->assign(
+      array(
+        'L_SECTION' => l10n('cat_comments_title'),
+        'L_CAT_OPTIONS_TRUE' => l10n('authorized'),
+        'L_CAT_OPTIONS_FALSE' => l10n('forbidden'),
+        )
+      );
+    break;
+  }
+  case 'visible' :
+  {
+    $query_true = '
+SELECT id,name,uppercats,global_rank
+  FROM '.CATEGORIES_TABLE.'
+  WHERE visible = \'true\'
+;';
+    $query_false = '
+SELECT id,name,uppercats,global_rank
+  FROM '.CATEGORIES_TABLE.'
+  WHERE visible = \'false\'
+;';
+    $template->assign(
+      array(
+        'L_SECTION' => l10n('cat_lock_title'),
+        'L_CAT_OPTIONS_TRUE' => l10n('unlocked'),
+        'L_CAT_OPTIONS_FALSE' => l10n('locked'),
+        )
+      );
+    break;
+  }
+  case 'status' :
+  {
+    $query_true = '
+SELECT id,name,uppercats,global_rank
+  FROM '.CATEGORIES_TABLE.'
+  WHERE status = \'public\'
+;';
+    $query_false = '
+SELECT id,name,uppercats,global_rank
+  FROM '.CATEGORIES_TABLE.'
+  WHERE status = \'private\'
+;';
+    $template->assign(
+      array(
+        'L_SECTION' => l10n('cat_status_title'),
+        'L_CAT_OPTIONS_TRUE' => l10n('cat_public'),
+        'L_CAT_OPTIONS_FALSE' => l10n('cat_private'),
+        )
+      );
+    break;
+  }
+  case 'representative' :
+  {
+    $query_true = '
+SELECT id,name,uppercats,global_rank
+  FROM '.CATEGORIES_TABLE.'
+  WHERE representative_picture_id IS NOT NULL
+;';
+    $query_false = '
+SELECT DISTINCT id,name,uppercats,global_rank
+  FROM '.CATEGORIES_TABLE.' INNER JOIN '.IMAGE_CATEGORY_TABLE.' ON id=category_id
+  WHERE representative_picture_id IS NULL
+;';
+    $template->assign(
+      array(
+        'L_SECTION' => l10n('Representative'),
+        'L_CAT_OPTIONS_TRUE' => l10n('singly represented'),
+        'L_CAT_OPTIONS_FALSE' => l10n('randomly represented')
+        )
+      );
+    break;
+  }
+}
+display_select_cat_wrapper($query_true,array(),'category_option_true');
+display_select_cat_wrapper($query_false,array(),'category_option_false');
+
+// +-----------------------------------------------------------------------+
+// |                           sending html code                           |
+// +-----------------------------------------------------------------------+
+
+$template->assign_var_from_handle('DOUBLE_SELECT', 'double_select');
+$template->assign_var_from_handle('ADMIN_CONTENT', 'cat_options');
+?>
Index: /tags/2.0.2/admin/cat_perm.php
===================================================================
--- /tags/2.0.2/admin/cat_perm.php	(revision 3278)
+++ /tags/2.0.2/admin/cat_perm.php	(revision 3278)
@@ -0,0 +1,330 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die ("Hacking attempt!");
+}
+
+include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+
+// +-----------------------------------------------------------------------+
+// | Check Access and exit when user status is not ok                      |
+// +-----------------------------------------------------------------------+
+check_status(ACCESS_ADMINISTRATOR);
+
+// +-----------------------------------------------------------------------+
+// |                       variable initialization                         |
+// +-----------------------------------------------------------------------+
+
+// if the category is not correct (not numeric, not private)
+if (isset($_GET['cat']) and is_numeric($_GET['cat']))
+{
+  $query = '
+SELECT status
+  FROM '.CATEGORIES_TABLE.'
+  WHERE id = '.$_GET['cat'].'
+;';
+  list($status) = mysql_fetch_array(pwg_query($query));
+  
+  if ('private' == $status)
+  {
+    $page['cat'] = $_GET['cat'];
+  }
+}
+
+if (!isset($page['cat']))
+{
+  $query = '
+SELECT id
+  FROM '.CATEGORIES_TABLE.'
+  WHERE status = \'private\'
+  LIMIT 0,1
+;';
+
+  list($page['cat']) = mysql_fetch_array(pwg_query($query));
+}
+
+// +-----------------------------------------------------------------------+
+// |                           form submission                             |
+// +-----------------------------------------------------------------------+
+
+
+if (isset($_POST['deny_groups_submit'])
+         and isset($_POST['deny_groups'])
+         and count($_POST['deny_groups']) > 0)
+{
+  // if you forbid access to a category, all sub-categories become
+  // automatically forbidden
+  $query = '
+DELETE
+  FROM '.GROUP_ACCESS_TABLE.'
+  WHERE group_id IN ('.implode(',', $_POST['deny_groups']).')
+    AND cat_id IN ('.implode(',', get_subcat_ids(array($page['cat']))).')
+;';
+  pwg_query($query);
+}
+else if (isset($_POST['grant_groups_submit'])
+         and isset($_POST['grant_groups'])
+         and count($_POST['grant_groups']) > 0)
+{
+  $query = '
+SELECT id
+  FROM '.CATEGORIES_TABLE.'
+  WHERE id IN ('.implode(',', get_uppercat_ids(array($page['cat']))).')
+  AND status = \'private\'
+;';
+  $private_uppercats = array_from_query($query, 'id');
+
+  // We must not reinsert already existing lines in group_access table
+  $granteds = array();
+  foreach ($private_uppercats as $cat_id)
+  {
+    $granteds[$cat_id] = array();
+  }
+  
+  $query = '
+SELECT group_id, cat_id
+  FROM '.GROUP_ACCESS_TABLE.'
+  WHERE cat_id IN ('.implode(',', $private_uppercats).')
+    AND group_id IN ('.implode(',', $_POST['grant_groups']).')
+;';
+  $result = pwg_query($query);
+  while ($row = mysql_fetch_array($result))
+  {
+    array_push($granteds[$row['cat_id']], $row['group_id']);
+  }
+
+  $inserts = array();
+  
+  foreach ($private_uppercats as $cat_id)
+  {
+    $group_ids = array_diff($_POST['grant_groups'], $granteds[$cat_id]);
+    foreach ($group_ids as $group_id)
+    {
+      array_push($inserts, array('group_id' => $group_id,
+                                 'cat_id' => $cat_id));
+    }
+  }
+
+  mass_inserts(GROUP_ACCESS_TABLE, array('group_id','cat_id'), $inserts);
+}
+else if (isset($_POST['deny_users_submit'])
+         and isset($_POST['deny_users'])
+         and count($_POST['deny_users']) > 0)
+{
+  // if you forbid access to a category, all sub-categories become
+  // automatically forbidden
+  $query = '
+DELETE
+  FROM '.USER_ACCESS_TABLE.'
+  WHERE user_id IN ('.implode(',', $_POST['deny_users']).')
+    AND cat_id IN ('.implode(',', get_subcat_ids(array($page['cat']))).')
+;';
+  pwg_query($query);
+}
+else if (isset($_POST['grant_users_submit'])
+         and isset($_POST['grant_users'])
+         and count($_POST['grant_users']) > 0)
+{
+  $query = '
+SELECT id
+  FROM '.CATEGORIES_TABLE.'
+  WHERE id IN ('.implode(',', get_uppercat_ids(array($page['cat']))).')
+  AND status = \'private\'
+;';
+  $private_uppercats = array_from_query($query, 'id');
+
+  // We must not reinsert already existing lines in user_access table
+  $granteds = array();
+  foreach ($private_uppercats as $cat_id)
+  {
+    $granteds[$cat_id] = array();
+  }
+  
+  $query = '
+SELECT user_id, cat_id
+  FROM '.USER_ACCESS_TABLE.'
+  WHERE cat_id IN ('.implode(',', $private_uppercats).')
+    AND user_id IN ('.implode(',', $_POST['grant_users']).')
+;';
+  $result = pwg_query($query);
+  while ($row = mysql_fetch_array($result))
+  {
+    array_push($granteds[$row['cat_id']], $row['user_id']);
+  }
+
+  $inserts = array();
+  
+  foreach ($private_uppercats as $cat_id)
+  {
+    $user_ids = array_diff($_POST['grant_users'], $granteds[$cat_id]);
+    foreach ($user_ids as $user_id)
+    {
+      array_push($inserts, array('user_id' => $user_id,
+                                 'cat_id' => $cat_id));
+    }
+  }
+
+  mass_inserts(USER_ACCESS_TABLE, array('user_id','cat_id'), $inserts);
+}
+
+// +-----------------------------------------------------------------------+
+// |                       template initialization                         |
+// +-----------------------------------------------------------------------+
+
+$template->set_filename('cat_perm', 'cat_perm.tpl');
+
+$template->assign(
+  array(
+    'CATEGORIES_NAV' =>
+      get_cat_display_name_from_id(
+        $page['cat'],
+        'admin.php?page=cat_modify&amp;cat_id='
+        ),
+    'U_HELP' => get_root_url().'popuphelp.php?page=cat_perm',
+    'F_ACTION' => get_root_url().'admin.php?page=cat_perm&amp;cat='.$page['cat']
+    )
+  );
+
+// +-----------------------------------------------------------------------+
+// |                          form construction                            |
+// +-----------------------------------------------------------------------+
+
+// groups denied are the groups not granted. So we need to find all groups
+// minus groups granted to find groups denied.
+
+$groups = array();
+
+$query = '
+SELECT id, name
+  FROM '.GROUPS_TABLE.'
+  ORDER BY name ASC
+;';
+$groups = simple_hash_from_query($query, 'id', 'name');
+$template->assign('all_groups', $groups);
+
+// groups granted to access the category
+$query = '
+SELECT group_id
+  FROM '.GROUP_ACCESS_TABLE.'
+  WHERE cat_id = '.$page['cat'].'
+;';
+$group_granted_ids = array_from_query($query, 'group_id');
+$group_granted_ids = order_by_name($group_granted_ids, $groups);
+$template->assign('group_granted_ids', $group_granted_ids);
+
+
+// groups denied
+$template->assign('group_denied_ids',
+    order_by_name(array_diff(array_keys($groups), $group_granted_ids), $groups)
+  );
+
+// users...
+$users = array();
+
+$query = '
+SELECT '.$conf['user_fields']['id'].' AS id,
+       '.$conf['user_fields']['username'].' AS username
+  FROM '.USERS_TABLE.'
+;';
+$users = simple_hash_from_query($query, 'id', 'username');
+$template->assign('all_users', $users);
+
+
+$query = '
+SELECT user_id
+  FROM '.USER_ACCESS_TABLE.'
+  WHERE cat_id = '.$page['cat'].'
+;';
+$user_granted_direct_ids = array_from_query($query, 'user_id');
+$user_granted_direct_ids = order_by_name($user_granted_direct_ids, $users);
+$template->assign('user_granted_direct_ids', $user_granted_direct_ids);
+
+
+
+$user_granted_indirect_ids = array();
+if (count($group_granted_ids) > 0)
+{
+  $granted_groups = array();
+
+  $query = '
+SELECT user_id, group_id
+  FROM '.USER_GROUP_TABLE.'
+  WHERE group_id IN ('.implode(',', $group_granted_ids).') 
+';
+  $result = pwg_query($query);
+  while ($row = mysql_fetch_array($result))
+  {
+    if (!isset($granted_groups[$row['group_id']]))
+    {
+      $granted_groups[$row['group_id']] = array();
+    }
+    array_push($granted_groups[$row['group_id']], $row['user_id']);
+  }
+
+  $user_granted_by_group_ids = array();
+
+  foreach ($granted_groups as $group_users)
+  {
+    $user_granted_by_group_ids = array_merge($user_granted_by_group_ids,
+                                             $group_users);
+  }
+  $user_granted_by_group_ids = array_unique($user_granted_by_group_ids);
+  
+  
+  $user_granted_indirect_ids = array_diff($user_granted_by_group_ids,
+                                          $user_granted_direct_ids);
+  $user_granted_indirect_ids = 
+    order_by_name($user_granted_indirect_ids, $users);  
+  foreach ($user_granted_indirect_ids as $user_id)
+  {
+    foreach ($granted_groups as $group_id => $group_users)
+    {
+      if (in_array($user_id, $group_users))
+      {
+        $template->append(
+          'user_granted_indirects',
+          array(
+            'USER'=>$users[$user_id],
+            'GROUP'=>$groups[$group_id]
+            )
+          );
+        break;
+      }
+    }
+  }
+}
+
+$user_denied_ids = array_diff(array_keys($users),
+                              $user_granted_indirect_ids,
+                              $user_granted_direct_ids);
+$user_denied_ids = order_by_name($user_denied_ids, $users);
+$template->assign('user_denied_ids', $user_denied_ids);
+
+
+// +-----------------------------------------------------------------------+
+// |                           sending html code                           |
+// +-----------------------------------------------------------------------+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'cat_perm');
+?>
Index: /tags/2.0.2/admin/comments.php
===================================================================
--- /tags/2.0.2/admin/comments.php	(revision 3278)
+++ /tags/2.0.2/admin/comments.php	(revision 3278)
@@ -0,0 +1,179 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die ("Hacking attempt!");
+}
+
+include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+include_once(PHPWG_ROOT_PATH.'admin/include/functions_waiting.inc.php');
+
+// +-----------------------------------------------------------------------+
+// | Check Access and exit when user status is not ok                      |
+// +-----------------------------------------------------------------------+
+check_status(ACCESS_ADMINISTRATOR);
+
+// +-----------------------------------------------------------------------+
+// |                                actions                                |
+// +-----------------------------------------------------------------------+
+
+if (isset($_POST))
+{
+  $to_validate = array();
+  $to_reject = array();
+
+  if (isset($_POST['submit']) and !is_adviser())
+  {
+    foreach (explode(',', $_POST['list']) as $comment_id)
+    {
+      if (isset($_POST['action-'.$comment_id]))
+      {
+        switch ($_POST['action-'.$comment_id])
+        {
+          case 'reject' :
+          {
+            array_push($to_reject, $comment_id);
+            break;
+          }
+          case 'validate' :
+          {
+            array_push($to_validate, $comment_id);
+            break;
+          }
+        }
+      }
+    }
+  }
+  else if (isset($_POST['validate-all']) and !empty($_POST['list']) and !is_adviser())
+  {
+    $to_validate = explode(',', $_POST['list']);
+  }
+  else if (isset($_POST['reject-all']) and !empty($_POST['list']) and !is_adviser())
+  {
+    $to_reject = explode(',', $_POST['list']);
+  }
+
+  if (count($to_validate) > 0)
+  {
+    $query = '
+UPDATE '.COMMENTS_TABLE.'
+  SET validated = \'true\'
+    , validation_date = NOW()
+  WHERE id IN ('.implode(',', $to_validate).')
+;';
+    pwg_query($query);
+
+    array_push(
+      $page['infos'],
+      l10n_dec(
+        '%d user comment validated', '%d user comments validated',
+        count($to_validate)
+        )
+      );
+  }
+
+  if (count($to_reject) > 0)
+  {
+    $query = '
+DELETE
+  FROM '.COMMENTS_TABLE.'
+  WHERE id IN ('.implode(',', $to_reject).')
+;';
+    pwg_query($query);
+
+    array_push(
+      $page['infos'],
+      l10n_dec(
+        '%d user comment rejected', '%d user comments rejected',
+        count($to_reject)
+        )
+      );
+  }
+}
+
+// +-----------------------------------------------------------------------+
+// |                             template init                             |
+// +-----------------------------------------------------------------------+
+
+$template->set_filenames(array('comments'=>'comments.tpl'));
+
+// TabSheet initialization
+waiting_tabsheet();
+
+$template->assign(
+  array(
+    'F_ACTION' => get_root_url().'admin.php?page=comments'
+    )
+  );
+
+// +-----------------------------------------------------------------------+
+// |                           comments display                            |
+// +-----------------------------------------------------------------------+
+
+$list = array();
+
+$query = '
+SELECT c.id, c.image_id, c.date, c.author, c.content, i.path, i.tn_ext
+  FROM '.COMMENTS_TABLE.' AS c
+    INNER JOIN '.IMAGES_TABLE.' AS i
+      ON i.id = c.image_id
+  WHERE validated = \'false\'
+  ORDER BY c.date DESC
+;';
+$result = pwg_query($query);
+while ($row = mysql_fetch_assoc($result))
+{
+  $thumb = get_thumbnail_url(
+      array(
+        'id'=>$row['image_id'],
+        'path'=>$row['path'],
+        'tn_ext'=>@$row['tn_ext']
+        )
+     );
+  $template->append(
+    'comments',
+    array(
+      'U_PICTURE' =>
+          PHPWG_ROOT_PATH.'admin.php?page=picture_modify'.
+          '&amp;image_id='.$row['image_id'],
+      'ID' => $row['id'],
+      'TN_SRC' => $thumb,
+      'AUTHOR' => trigger_event('render_comment_author', $row['author']),
+      'DATE' => format_date($row['date'], true),
+      'CONTENT' => trigger_event('render_comment_content',$row['content'])
+      )
+    );
+
+  array_push($list, $row['id']);
+}
+
+$template->assign('LIST', implode(',', $list) );
+
+// +-----------------------------------------------------------------------+
+// |                           sending html code                           |
+// +-----------------------------------------------------------------------+
+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'comments');
+
+?>
Index: /tags/2.0.2/admin/configuration.php
===================================================================
--- /tags/2.0.2/admin/configuration.php	(revision 3278)
+++ /tags/2.0.2/admin/configuration.php	(revision 3278)
@@ -0,0 +1,301 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if( !defined("PHPWG_ROOT_PATH") )
+{
+  die ("Hacking attempt!");
+}
+
+include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+include_once(PHPWG_ROOT_PATH.'admin/include/tabsheet.class.php');
+
+// +-----------------------------------------------------------------------+
+// | Check Access and exit when user status is not ok                      |
+// +-----------------------------------------------------------------------+
+check_status(ACCESS_ADMINISTRATOR);
+
+//-------------------------------------------------------- sections definitions
+if (!isset($_GET['section']))
+{
+  $page['section'] = 'main';
+}
+else
+{
+  $page['section'] = $_GET['section'];
+}
+
+$main_checkboxes = array(
+    'gallery_locked',
+    'allow_user_registration',
+    'obligatory_user_mail_address',
+    'rate',
+    'rate_anonymous',
+    'email_admin_on_new_user',
+   );
+
+$history_checkboxes = array(
+    'log',
+    'history_admin',
+    'history_guest'
+   );
+
+$upload_checkboxes = array(
+    'upload_link_everytime',
+    'email_admin_on_picture_uploaded',
+   );
+
+$comments_checkboxes = array(
+    'comments_forall',
+    'comments_validation',
+    'email_admin_on_comment',
+    'email_admin_on_comment_validation',
+  );
+
+//------------------------------ verification and registration of modifications
+if (isset($_POST['submit']) and !is_adviser())
+{
+  $int_pattern = '/^\d+$/';
+
+  switch ($page['section'])
+  {
+    case 'main' :
+    {
+      if ( !url_is_remote($_POST['gallery_url']) )
+      {
+        array_push($page['errors'], l10n('conf_gallery_url_error'));
+      }
+      foreach( $main_checkboxes as $checkbox)
+      {
+        $_POST[$checkbox] = empty($_POST[$checkbox])?'false':'true';
+      }
+      break;
+    }
+    case 'history' :
+    {
+      foreach( $history_checkboxes as $checkbox)
+      {
+        $_POST[$checkbox] = empty($_POST[$checkbox])?'false':'true';
+      }
+      break;
+    }
+    case 'comments' :
+    {
+      // the number of comments per page must be an integer between 5 and 50
+      // included
+      if (!preg_match($int_pattern, $_POST['nb_comment_page'])
+           or $_POST['nb_comment_page'] < 5
+           or $_POST['nb_comment_page'] > 50)
+      {
+        array_push($page['errors'], l10n('conf_nb_comment_page_error'));
+      }
+      foreach( $comments_checkboxes as $checkbox)
+      {
+        $_POST[$checkbox] = empty($_POST[$checkbox])?'false':'true';
+      }
+      break;
+    }
+    case 'upload' :
+    {
+      foreach( $upload_checkboxes as $checkbox)
+      {
+        $_POST[$checkbox] = empty($_POST[$checkbox])?'false':'true';
+      }
+      break;
+    }
+    case 'default' :
+    {
+      // Never go here
+      break;
+    }
+  }
+
+  // updating configuration if no error found
+  if (count($page['errors']) == 0)
+  {
+    //echo '<pre>'; print_r($_POST); echo '</pre>';
+    $result = pwg_query('SELECT param FROM '.CONFIG_TABLE);
+    while ($row = mysql_fetch_array($result))
+    {
+      if (isset($_POST[$row['param']]))
+      {
+        $value = $_POST[$row['param']];
+
+        if ('gallery_title' == $row['param'])
+        {
+          if (!$conf['allow_html_descriptions'])
+          {
+            $value = strip_tags($value);
+          }
+        }
+
+        $query = '
+UPDATE '.CONFIG_TABLE.'
+SET value = \''. str_replace("\'", "''", $value).'\'
+WHERE param = \''.$row['param'].'\'
+;';
+        pwg_query($query);
+      }
+    }
+    array_push($page['infos'], l10n('conf_confirmation'));
+  }
+
+  //------------------------------------------------------ $conf reinitialization
+  load_conf_from_db();
+}
+
+//----------------------------------------------------- template initialization
+$template->set_filename('config', 'configuration.tpl');
+
+// TabSheet
+$tabsheet = new tabsheet();
+// TabSheet initialization
+$tabsheet->add('main', l10n('conf_main_title'), $conf_link.'main');
+$tabsheet->add('history', l10n('conf_history_title'), $conf_link.'history');
+$tabsheet->add('comments', l10n('conf_comments_title'), $conf_link.'comments');
+$tabsheet->add('upload', l10n('conf_upload_title'), $conf_link.'upload');
+$tabsheet->add('default', l10n('conf_display'), $conf_link.'default');
+// TabSheet selection
+$tabsheet->select($page['section']);
+// Assign tabsheet to template
+$tabsheet->assign();
+
+$action = get_root_url().'admin.php?page=configuration';
+$action.= '&amp;section='.$page['section'];
+
+$template->assign(
+  array(
+    'U_HELP' => get_root_url().'popuphelp.php?page=configuration',
+    'F_ACTION'=>$action
+    ));
+
+switch ($page['section'])
+{
+  case 'main' :
+  {
+    $template->assign(
+      'main',
+      array(
+        'CONF_GALLERY_TITLE' => htmlspecialchars($conf['gallery_title']),
+        'CONF_PAGE_BANNER' => htmlspecialchars($conf['page_banner']),
+        'CONF_GALLERY_URL' => $conf['gallery_url'],
+        ));
+
+    foreach ($main_checkboxes as $checkbox)
+    {
+      $template->append(
+          'main',
+          array(
+            $checkbox => $conf[$checkbox]
+            ),
+          true
+        );
+    }
+    break;
+  }
+  case 'history' :
+  {
+    //Necessary for merge_block_vars
+    foreach ($history_checkboxes as $checkbox)
+    {
+      $template->append(
+          'history',
+          array(
+            $checkbox => $conf[$checkbox]
+            ),
+          true
+        );
+    }
+    break;
+  }
+  case 'comments' :
+  {
+    $template->assign(
+      'comments',
+      array(
+        'NB_COMMENTS_PAGE'=>$conf['nb_comment_page'],
+        ));
+
+    foreach ($comments_checkboxes as $checkbox)
+    {
+      $template->append(
+          'comments',
+          array(
+            $checkbox => $conf[$checkbox]
+            ),
+          true
+        );
+    }
+    break;
+  }
+  case 'upload' :
+  {
+    $template->assign(
+      'upload',
+      array(
+        'upload_user_access_options'=> get_user_access_level_html_options(ACCESS_GUEST),
+        'upload_user_access_options_selected' => array($conf['upload_user_access'])
+        )
+      );
+    //Necessary for merge_block_vars
+    foreach ($upload_checkboxes as $checkbox)
+    {
+      $template->append(
+          'upload',
+          array(
+            $checkbox => $conf[$checkbox]
+            ),
+          true
+        );
+    }
+    break;
+  }
+  case 'default' :
+  {
+    $edit_user = build_user($conf['default_user_id'], false);
+    include_once(PHPWG_ROOT_PATH.'profile.php');
+
+    $errors = array();
+    if ( !is_adviser() )
+    {
+      if (save_profile_from_post($edit_user, $errors))
+      {
+        // Reload user
+        $edit_user = build_user($conf['default_user_id'], false);
+        array_push($page['infos'], l10n('conf_confirmation'));
+      }
+    }
+    $page['errors'] = array_merge($page['errors'], $errors);
+
+    load_profile_in_template(
+      $action,
+      '',
+      $edit_user
+      );
+    $template->assign('default', array());
+    break;
+  }
+}
+
+//----------------------------------------------------------- sending html code
+$template->assign_var_from_handle('ADMIN_CONTENT', 'config');
+?>
Index: /tags/2.0.2/admin/element_set.php
===================================================================
--- /tags/2.0.2/admin/element_set.php	(revision 3278)
+++ /tags/2.0.2/admin/element_set.php	(revision 3278)
@@ -0,0 +1,243 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+/**
+ * Management of elements set. Elements can belong to a category or to the
+ * user caddie.
+ *
+ */
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+
+// +-----------------------------------------------------------------------+
+// | Check Access and exit when user status is not ok                      |
+// +-----------------------------------------------------------------------+
+check_status(ACCESS_ADMINISTRATOR);
+
+// +-----------------------------------------------------------------------+
+// |                          caddie management                            |
+// +-----------------------------------------------------------------------+
+
+if (isset($_POST['submit_caddie']))
+{
+  if (isset($_POST['caddie_action']))
+  {
+    switch ($_POST['caddie_action'])
+    {
+      case 'empty_all' :
+      {
+          $query = '
+DELETE FROM '.CADDIE_TABLE.'
+  WHERE user_id = '.$user['id'].'
+;';
+          pwg_query($query);
+          break;
+      }
+      case 'empty_selected' :
+      {
+        if (isset($_POST['selection']) and count($_POST['selection']) > 0)
+        {
+          $query = '
+DELETE
+  FROM '.CADDIE_TABLE.'
+  WHERE element_id IN ('.implode(',', $_POST['selection']).')
+    AND user_id = '.$user['id'].'
+;';
+          pwg_query($query);
+        }
+        else
+        {
+          // TODO : add error
+        }
+        break;
+      }
+      case 'add_selected' :
+      {
+        if (isset($_POST['selection']) and count($_POST['selection']) > 0)
+        {
+          fill_caddie($_POST['selection']);
+        }
+        else
+        {
+          // TODO : add error
+        }
+        break;
+      }
+    }
+  }
+  else
+  {
+    // TODO : add error
+  }
+}
+
+// +-----------------------------------------------------------------------+
+// |                    initialize info about category                     |
+// +-----------------------------------------------------------------------+
+
+// To element_set_(global|unit).php, we must provide the elements id of the
+// managed category in $page['cat_elements_id'] array.
+$page['cat_elements_id'] = array();
+if (is_numeric($_GET['cat']))
+{
+  $page['title'] =
+    get_cat_display_name_from_id(
+      $_GET['cat'],
+      PHPWG_ROOT_PATH.'admin.php?page=cat_modify&amp;cat_id=',
+      false
+      );
+
+  $query = '
+SELECT image_id
+  FROM '.IMAGE_CATEGORY_TABLE.'
+  WHERE category_id = '.$_GET['cat'].'
+;';
+  $page['cat_elements_id'] = array_from_query($query, 'image_id');
+}
+else if ('caddie' == $_GET['cat'])
+{
+  $page['title'] = l10n('caddie');
+
+  $query = '
+SELECT element_id
+  FROM '.CADDIE_TABLE.'
+  WHERE user_id = '.$user['id'].'
+;';
+  $page['cat_elements_id'] = array_from_query($query, 'element_id');
+}
+else if ('not_linked' == $_GET['cat'])
+{
+  $page['title'] = l10n('Elements_not_linked');
+  $template->assign(array('U_ACTIVE_MENU' => 5 ));
+
+  // we are searching elements not linked to any virtual category
+  $query = '
+SELECT id
+  FROM '.CATEGORIES_TABLE.'
+  WHERE dir IS NULL
+;';
+  $virtual_categories = array_from_query($query, 'id');
+
+  if (!empty($virtual_categories))
+  {
+    $query = '
+SELECT DISTINCT(image_id)
+  FROM '.IMAGE_CATEGORY_TABLE.'
+;';
+    $all_elements = array_from_query($query, 'image_id');
+
+    $query = '
+SELECT DISTINCT(image_id)
+  FROM '.IMAGE_CATEGORY_TABLE.'
+  WHERE category_id IN ('.implode(',', $virtual_categories).')
+;';
+    $linked_to_virtual = array_from_query($query, 'image_id');
+
+    $page['cat_elements_id'] = array_diff($all_elements, $linked_to_virtual);
+  }
+}
+else if ('duplicates' == $_GET['cat'])
+{
+  $page['title'] = l10n('Duplicates');
+  $template->assign(array('U_ACTIVE_MENU' => 5 ));
+
+  // we are searching related elements twice or more to physical categories
+  // 1 - Retrieve Files
+  $query = '
+SELECT DISTINCT(file)
+  FROM '.IMAGES_TABLE.'
+ GROUP BY file
+HAVING COUNT(DISTINCT storage_category_id) > 1
+;';
+
+  $duplicate_files = array_from_query($query, 'file');
+  $duplicate_files[]='Nofiles';
+  // 2 - Retrives related picture ids
+  $query = '
+SELECT id, file
+  FROM '.IMAGES_TABLE.'
+WHERE file IN (\''.implode("','", $duplicate_files).'\')
+ORDER BY file, id
+;';
+
+  $page['cat_elements_id'] = array_from_query($query, 'id');
+}
+elseif ('recent'== $_GET['cat'])
+{
+  $page['title'] = l10n('recent_pics_cat');
+  $query = 'SELECT MAX(date_available) AS date
+  FROM '.IMAGES_TABLE;
+  if ($row=mysql_fetch_array( pwg_query($query) ) )
+  {
+    $query = 'SELECT id
+  FROM '.IMAGES_TABLE.'
+  WHERE date_available BETWEEN DATE_SUB("'.$row['date'].'", INTERVAL 1 DAY) AND "'.$row['date'].'"';
+    $page['cat_elements_id'] = array_from_query($query, 'id');
+  }
+}
+
+// +-----------------------------------------------------------------------+
+// |                       first element to display                        |
+// +-----------------------------------------------------------------------+
+
+// $page['start'] contains the number of the first element in its
+// category. For exampe, $page['start'] = 12 means we must show elements #12
+// and $page['nb_images'] next elements
+
+if (!isset($_GET['start'])
+    or !is_numeric($_GET['start'])
+    or $_GET['start'] < 0
+    or (isset($_GET['display']) and 'all' == $_GET['display']))
+{
+  $page['start'] = 0;
+}
+else
+{
+  $page['start'] = $_GET['start'];
+}
+
+// +-----------------------------------------------------------------------+
+// |                         open specific mode                            |
+// +-----------------------------------------------------------------------+
+
+$_GET['mode'] = !empty($_GET['mode']) ? $_GET['mode'] : 'global';
+
+switch ($_GET['mode'])
+{
+  case 'global' :
+  {
+    include(PHPWG_ROOT_PATH.'admin/element_set_global.php');
+    break;
+  }
+  case 'unit' :
+  {
+    include(PHPWG_ROOT_PATH.'admin/element_set_unit.php');
+    break;
+  }
+}
+?>
Index: /tags/2.0.2/admin/element_set_global.php
===================================================================
--- /tags/2.0.2/admin/element_set_global.php	(revision 3278)
+++ /tags/2.0.2/admin/element_set_global.php	(revision 3278)
@@ -0,0 +1,503 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+/**
+ * Management of elements set. Elements can belong to a category or to the
+ * user caddie.
+ *
+ */
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+
+// +-----------------------------------------------------------------------+
+// | Check Access and exit when user status is not ok                      |
+// +-----------------------------------------------------------------------+
+check_status(ACCESS_ADMINISTRATOR);
+
+// +-----------------------------------------------------------------------+
+// |                         deletion form submission                      |
+// +-----------------------------------------------------------------------+
+
+if (isset($_POST['delete']))
+{
+  if (isset($_POST['confirm_deletion']) and 1 == $_POST['confirm_deletion'])
+  {
+    $collection = array();
+
+    switch ($_POST['target_deletion'])
+    {
+      case 'all' :
+      {
+        $collection = $page['cat_elements_id'];
+        break;
+      }
+      case 'selection' :
+      {
+        if (!isset($_POST['selection']) or count($_POST['selection']) == 0)
+        {
+          array_push($page['errors'], l10n('Select at least one picture'));
+        }
+        else
+        {
+          $collection = $_POST['selection'];
+        }
+        break;
+      }
+    }
+
+    // filter selection on photos that have no storage_category_id (ie that
+    // were added via pLoader)
+    if (count($collection) > 0)
+    {
+      $query = '
+SELECT
+    id
+  FROM '.IMAGES_TABLE.'
+  WHERE id IN ('.implode(',', $collection).')
+    AND storage_category_id IS NULL
+;';
+      $deletables = array_from_query($query, 'id');
+
+      if (count($deletables) > 0)
+      {
+        // what will be the categories to update? (to avoid orphan on
+        // representative_picture_id)
+        $query = '
+SELECT
+    category_id
+  FROM '.IMAGE_CATEGORY_TABLE.'
+  WHERE image_id IN ('.implode(',', $deletables).')
+;';
+        $categories_to_update = array_from_query($query, 'category_id');
+          
+        $physical_deletion = true;
+        delete_elements($deletables, $physical_deletion);
+
+        update_category($categories_to_update);
+
+        array_push(
+          $page['infos'],
+          sprintf(
+            l10n_dec(
+              '%d photo was deleted',
+              '%d photos were deleted',
+              count($deletables)
+              ),
+            count($deletables)
+            )
+          );
+      }
+      else
+      {
+        array_push($page['errors'], l10n('No photo can be deleted'));
+      }
+    }
+  }
+  else
+  {
+    array_push($page['errors'], l10n('You need to confirm deletion'));
+  }
+}
+
+// +-----------------------------------------------------------------------+
+// |                       global mode form submission                     |
+// +-----------------------------------------------------------------------+
+
+if (isset($_POST['submit']))
+{
+  $collection = array();
+
+//   echo '<pre>';
+//   print_r($_POST);
+//   echo '</pre>';
+//   exit();
+
+  switch ($_POST['target'])
+  {
+    case 'all' :
+    {
+      $collection = $page['cat_elements_id'];
+      break;
+    }
+    case 'selection' :
+    {
+      if (!isset($_POST['selection']) or count($_POST['selection']) == 0)
+      {
+        array_push($page['errors'], l10n('Select at least one picture'));
+      }
+      else
+      {
+        $collection = $_POST['selection'];
+      }
+      break;
+    }
+  }
+
+  if (isset($_POST['add_tags']) and count($collection) > 0)
+  {
+    add_tags($_POST['add_tags'], $collection);
+  }
+
+  if (isset($_POST['del_tags']) and count($collection) > 0)
+  {
+    $query = '
+DELETE
+  FROM '.IMAGE_TAG_TABLE.'
+  WHERE image_id IN ('.implode(',', $collection).')
+    AND tag_id IN ('.implode(',', $_POST['del_tags']).')
+;';
+    pwg_query($query);
+  }
+
+  if ($_POST['associate'] != 0 and count($collection) > 0)
+  {
+    associate_images_to_categories(
+      $collection,
+      array($_POST['associate'])
+      );
+  }
+
+  if ($_POST['dissociate'] != 0 and count($collection) > 0)
+  {
+    // physical links must not be broken, so we must first retrieve image_id
+    // which create virtual links with the category to "dissociate from".
+    $query = '
+SELECT id
+  FROM '.IMAGE_CATEGORY_TABLE.'
+    INNER JOIN '.IMAGES_TABLE.' ON image_id = id
+  WHERE category_id = '.$_POST['dissociate'].'
+    AND id IN ('.implode(',', $collection).')
+    AND (
+      category_id != storage_category_id
+      OR storage_category_id IS NULL
+    )
+;';
+    $dissociables = array_from_query($query, 'id');
+
+    if (!empty($dissociables))
+    {
+      $query = '
+DELETE
+  FROM '.IMAGE_CATEGORY_TABLE.'
+  WHERE category_id = '.$_POST['dissociate'].'
+    AND image_id IN ('.implode(',', $dissociables).')
+';
+      pwg_query($query);
+
+      // we remove the dissociated images if we are currently displaying the
+      // category to dissociate from.
+      if (is_numeric($_GET['cat']) and $_POST['dissociate'] == $_GET['cat'])
+      {
+        $page['cat_elements_id'] = array_diff(
+          $page['cat_elements_id'],
+          $dissociables
+          );
+      }
+    }
+
+    update_category($_POST['dissociate']);
+  }
+
+  $datas = array();
+  $dbfields = array('primary' => array('id'), 'update' => array());
+
+  $formfields = array('author', 'name', 'date_creation', 'level');
+  foreach ($formfields as $formfield)
+  {
+    if ($_POST[$formfield.'_action'] != 'leave')
+    {
+      array_push($dbfields['update'], $formfield);
+    }
+  }
+
+  // updating elements is useful only if needed...
+  if (count($dbfields['update']) > 0 and count($collection) > 0)
+  {
+    $query = '
+SELECT id
+  FROM '.IMAGES_TABLE.'
+  WHERE id IN ('.implode(',', $collection).')
+;';
+    $result = pwg_query($query);
+
+    while ($row = mysql_fetch_array($result))
+    {
+      $data = array();
+      $data['id'] = $row['id'];
+
+      if ('set' == $_POST['author_action'])
+      {
+        $data['author'] = $_POST['author'];
+        if ('' == $data['author'])
+        {
+          unset($data['author']);
+        }
+      }
+
+      if ('set' == $_POST['name_action'])
+      {
+        $data['name'] = $_POST['name'];
+        if ('' == $data['name'])
+        {
+          unset($data['name']);
+        }
+      }
+
+      if ('set' == $_POST['date_creation_action'])
+      {
+        $data['date_creation'] =
+          $_POST['date_creation_year']
+          .'-'.$_POST['date_creation_month']
+          .'-'.$_POST['date_creation_day']
+          ;
+      }
+
+      if ('set' == $_POST['level_action'])
+      {
+        $data['level'] = $_POST['level'];
+      }
+
+      array_push($datas, $data);
+    }
+    // echo '<pre>'; print_r($datas); echo '</pre>';
+    mass_updates(IMAGES_TABLE, $dbfields, $datas);
+  }
+}
+
+// +-----------------------------------------------------------------------+
+// |                             template init                             |
+// +-----------------------------------------------------------------------+
+$template->set_filenames(
+  array('element_set_global' => 'element_set_global.tpl'));
+
+$base_url = get_root_url().'admin.php';
+
+// $form_action = $base_url.'?page=element_set_global';
+
+$template->assign(
+  array(
+    'CATEGORIES_NAV'=>$page['title'],
+
+    'U_DISPLAY'=>$base_url.get_query_string_diff(array('display')),
+
+    'U_UNIT_MODE'
+    =>
+    $base_url
+    .get_query_string_diff(array('mode','display'))
+    .'&amp;mode=unit',
+
+    'F_ACTION'=>$base_url.get_query_string_diff(array()),
+   )
+ );
+
+// +-----------------------------------------------------------------------+
+// |                            caddie options                             |
+// +-----------------------------------------------------------------------+
+
+$template->assign('IN_CADDIE', 'caddie' == $_GET['cat'] ? true : false );
+
+// +-----------------------------------------------------------------------+
+// |                            deletion form                              |
+// +-----------------------------------------------------------------------+
+
+// we can only remove photos that have no storage_category_id, in other
+// word, it currently (Butterfly) means that the photo was added with
+// pLoader
+if (count($page['cat_elements_id']) > 0)
+{
+  $query = '
+SELECT
+    COUNT(*)
+  FROM '.IMAGES_TABLE.'
+  WHERE id IN ('.implode(',', $page['cat_elements_id']).')
+    AND storage_category_id IS NULL
+;';
+  list($counter) = mysql_fetch_row(pwg_query($query));
+
+  if ($counter > 0)
+  {
+    $template->assign('show_delete_form', true);
+  }
+}
+
+// +-----------------------------------------------------------------------+
+// |                           global mode form                            |
+// +-----------------------------------------------------------------------+
+
+// Virtualy associate a picture to a category
+$query = '
+SELECT id,name,uppercats,global_rank
+  FROM '.CATEGORIES_TABLE.'
+;';
+display_select_cat_wrapper($query, array(), 'associate_options', true);
+
+// Dissociate from a category : categories listed for dissociation can
+// only represent virtual links. Links to physical categories can't be
+// broken
+if (count($page['cat_elements_id']) > 0)
+{
+  $query = '
+SELECT
+    DISTINCT(category_id) AS id,
+    c.name,
+    c.uppercats,
+    c.global_rank
+  FROM '.IMAGE_CATEGORY_TABLE.' AS ic
+    JOIN '.CATEGORIES_TABLE.' AS c ON c.id = ic.category_id
+    JOIN '.IMAGES_TABLE.' AS i ON i.id = ic.image_id
+  WHERE ic.image_id IN ('.implode(',', $page['cat_elements_id']).')
+    AND (
+      ic.category_id != i.storage_category_id
+      OR i.storage_category_id IS NULL
+    )
+;';
+  display_select_cat_wrapper($query, array(), 'dissociate_options', true);
+}
+
+$all_tags = get_all_tags();
+
+if (count($all_tags) > 0)
+{// add tags
+  $template->assign(
+    array(
+      'ADD_TAG_SELECTION' => get_html_tag_selection(
+                              $all_tags,
+                              'add_tags'
+                              ),
+      )
+    );
+}
+
+if (count($page['cat_elements_id']) > 0)
+{
+  // remove tags
+  $tags = get_common_tags($page['cat_elements_id'], -1);
+
+  $template->assign(
+    array(
+      'DEL_TAG_SELECTION' => get_html_tag_selection($tags, 'del_tags'),
+      )
+    );
+}
+
+// creation date
+$day =
+empty($_POST['date_creation_day']) ? date('j') : $_POST['date_creation_day'];
+
+$month =
+empty($_POST['date_creation_month']) ? date('n') : $_POST['date_creation_month'];
+
+$year =
+empty($_POST['date_creation_year']) ? date('Y') : $_POST['date_creation_year'];
+
+$month_list = $lang['month'];
+$month_list[0]='------------';
+ksort($month_list);
+$template->assign( array(
+      'month_list'         => $month_list,
+      'DATE_CREATION_DAY'  => (int)$day,
+      'DATE_CREATION_MONTH'=> (int)$month,
+      'DATE_CREATION_YEAR' => (int)$year,
+    )
+  );
+
+// image level options
+$tpl_options = array();
+foreach ($conf['available_permission_levels'] as $level)
+{
+  $tpl_options[$level] = l10n( sprintf('Level %d', $level) );
+}
+$template->assign(
+    array(
+      'level_options'=> $tpl_options,
+    )
+  );
+
+// +-----------------------------------------------------------------------+
+// |                        global mode thumbnails                         |
+// +-----------------------------------------------------------------------+
+
+// how many items to display on this page
+if (!empty($_GET['display']))
+{
+  if ('all' == $_GET['display'])
+  {
+    $page['nb_images'] = count($page['cat_elements_id']);
+  }
+  else
+  {
+    $page['nb_images'] = intval($_GET['display']);
+  }
+}
+else
+{
+  $page['nb_images'] = 20;
+}
+
+if (count($page['cat_elements_id']) > 0)
+{
+  $nav_bar = create_navigation_bar(
+    $base_url.get_query_string_diff(array('start')),
+    count($page['cat_elements_id']),
+    $page['start'],
+    $page['nb_images']
+    );
+  $template->assign('NAV_BAR', $nav_bar);
+
+  $query = '
+SELECT id,path,tn_ext,file,filesize,level
+  FROM '.IMAGES_TABLE.'
+  WHERE id IN ('.implode(',', $page['cat_elements_id']).')
+  '.$conf['order_by'].'
+  LIMIT '.$page['start'].', '.$page['nb_images'].'
+;';
+  //echo '<pre>'.$query.'</pre>';
+  $result = pwg_query($query);
+
+  // template thumbnail initialization
+
+  while ($row = mysql_fetch_assoc($result))
+  {
+    $src = get_thumbnail_url($row);
+
+    $template->append(
+      'thumbnails',
+      array(
+        'ID' => $row['id'],
+        'TN_SRC' => $src,
+        'FILE' => $row['file'],
+        'TITLE' => get_thumbnail_title($row),
+        'LEVEL' => $row['level']
+        )
+      );
+  }
+}
+
+//----------------------------------------------------------- sending html code
+$template->assign_var_from_handle('ADMIN_CONTENT', 'element_set_global');
+?>
Index: /tags/2.0.2/admin/element_set_ranks.php
===================================================================
--- /tags/2.0.2/admin/element_set_ranks.php	(revision 3278)
+++ /tags/2.0.2/admin/element_set_ranks.php	(revision 3278)
@@ -0,0 +1,174 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+/**
+ * Change rank of images inside a category
+ *
+ */
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+
+// +-----------------------------------------------------------------------+
+// | Check Access and exit when user status is not ok                      |
+// +-----------------------------------------------------------------------+
+check_status(ACCESS_ADMINISTRATOR);
+
+if (!isset($_GET['cat_id']) or !is_numeric($_GET['cat_id']))
+{
+  trigger_error('missing cat_id param', E_USER_ERROR);
+}
+
+$page['category_id'] = $_GET['cat_id'];
+
+// +-----------------------------------------------------------------------+
+// |                               functions                               |
+// +-----------------------------------------------------------------------+
+
+/**
+ * save the rank depending on given images order
+ *
+ * The list of ordered images id is supposed to be in the same parent
+ * category
+ *
+ * @param array categories
+ * @return void
+ */
+function save_images_order($category_id, $images)
+{
+  $current_rank = 0;
+  $datas = array();
+  foreach ($images as $id)
+  {
+    array_push(
+      $datas,
+      array(
+        'category_id' => $category_id,
+        'image_id' => $id,
+        'rank' => ++$current_rank,
+        )
+      );
+  }
+  $fields = array(
+    'primary' => array('image_id', 'category_id'),
+    'update' => array('rank')
+    );
+  mass_updates(IMAGE_CATEGORY_TABLE, $fields, $datas);
+}
+
+// +-----------------------------------------------------------------------+
+// |                       global mode form submission                     |
+// +-----------------------------------------------------------------------+
+
+if (isset($_POST['submit']))
+{
+  asort($_POST['rank_of_image'], SORT_NUMERIC);
+  
+  save_images_order(
+    $page['category_id'],
+    array_keys($_POST['rank_of_image'])
+    );
+
+  array_push(
+    $page['infos'],
+    l10n('Images manual order was saved')
+    );
+}
+
+// +-----------------------------------------------------------------------+
+// |                             template init                             |
+// +-----------------------------------------------------------------------+
+$template->set_filenames(
+  array('element_set_ranks' => 'element_set_ranks.tpl')
+  );
+
+$base_url = get_root_url().'admin.php';
+
+// $form_action = $base_url.'?page=element_set_global';
+
+$query = '
+SELECT uppercats
+  FROM '.CATEGORIES_TABLE.'
+  WHERE id = '.$page['category_id'].'
+;';
+$category = mysql_fetch_array(pwg_query($query));
+
+// Navigation path
+$navigation = get_cat_display_name_cache(
+  $category['uppercats'],
+  get_root_url().'admin.php?page=cat_modify&amp;cat_id='
+  );
+
+$template->assign(
+  array(
+    'CATEGORIES_NAV' => $navigation,
+    'F_ACTION' => $base_url.get_query_string_diff(array()),
+   )
+ );
+
+// +-----------------------------------------------------------------------+
+// |                              thumbnails                               |
+// +-----------------------------------------------------------------------+
+
+$query = '
+SELECT
+    id,
+    path,
+    tn_ext,
+    rank
+  FROM '.IMAGES_TABLE.'
+    JOIN '.IMAGE_CATEGORY_TABLE.' ON image_id = id
+  WHERE category_id = '.$page['category_id'].'
+  ORDER BY rank
+;';
+$result = pwg_query($query);
+
+// template thumbnail initialization
+$current_rank = 1;
+
+while ($row = mysql_fetch_assoc($result))
+{
+  $src = get_thumbnail_url($row);
+  
+  $template->append(
+    'thumbnails',
+    array(
+      'ID' => $row['id'],
+      'TN_SRC' => $src,
+      'RANK' => $current_rank * 10,
+      )
+    );
+
+  $current_rank++;
+}
+
+// +-----------------------------------------------------------------------+
+// |                          sending html code                            |
+// +-----------------------------------------------------------------------+
+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'element_set_ranks');
+?>
Index: /tags/2.0.2/admin/element_set_unit.php
===================================================================
--- /tags/2.0.2/admin/element_set_unit.php	(revision 3278)
+++ /tags/2.0.2/admin/element_set_unit.php	(revision 3278)
@@ -0,0 +1,274 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+/**
+ * Management of elements set. Elements can belong to a category or to the
+ * user caddie.
+ *
+ */
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+
+// +-----------------------------------------------------------------------+
+// | Check Access and exit when user status is not ok                      |
+// +-----------------------------------------------------------------------+
+check_status(ACCESS_ADMINISTRATOR);
+
+// +-----------------------------------------------------------------------+
+// |                        unit mode form submission                      |
+// +-----------------------------------------------------------------------+
+
+if (isset($_POST['submit']))
+{
+  $collection = explode(',', $_POST['element_ids']);
+
+  $datas = array();
+
+  $query = '
+SELECT id, date_creation
+  FROM '.IMAGES_TABLE.'
+  WHERE id IN ('.implode(',', $collection).')
+;';
+  $result = pwg_query($query);
+
+  while ($row = mysql_fetch_array($result))
+  {
+    $data = array();
+
+    $data{'id'} = $row['id'];
+    $data{'name'} = $_POST['name-'.$row['id']];
+    $data{'author'} = $_POST['author-'.$row['id']];
+
+    foreach (array('name', 'author') as $field)
+    {
+      if (!empty($_POST[$field.'-'.$row['id']]))
+      {
+        $data{$field} = strip_tags($_POST[$field.'-'.$row['id']]);
+      }
+    }
+
+    if ($conf['allow_html_descriptions'])
+    {
+      $data{'comment'} = @$_POST['description-'.$row['id']];
+    }
+    else
+    {
+      $data{'comment'} = strip_tags(@$_POST['description-'.$row['id']]);
+    }
+
+    if (isset($_POST['date_creation_action-'.$row['id']]))
+    {
+      if ('set' == $_POST['date_creation_action-'.$row['id']])
+      {
+        $data{'date_creation'} =
+          $_POST['date_creation_year-'.$row['id']]
+            .'-'.$_POST['date_creation_month-'.$row['id']]
+            .'-'.$_POST['date_creation_day-'.$row['id']];
+      }
+      else if ('unset' == $_POST['date_creation_action-'.$row['id']])
+      {
+        $data{'date_creation'} = '';
+      }
+    }
+    else
+    {
+      $data{'date_creation'} = $row['date_creation'];
+    }
+
+    array_push($datas, $data);
+
+    // tags management
+    if (isset($_POST[ 'tags-'.$row['id'] ]))
+    {
+      set_tags($_POST[ 'tags-'.$row['id'] ], $row['id']);
+    }
+  }
+
+  mass_updates(
+    IMAGES_TABLE,
+    array(
+      'primary' => array('id'),
+      'update' => array('name','author','comment','date_creation')
+      ),
+    $datas
+    );
+
+  array_push($page['infos'], l10n('Picture informations updated'));
+}
+
+// +-----------------------------------------------------------------------+
+// |                             template init                             |
+// +-----------------------------------------------------------------------+
+
+$template->set_filenames(
+  array('element_set_unit' => 'element_set_unit.tpl'));
+
+$base_url = PHPWG_ROOT_PATH.'admin.php';
+
+$month_list = $lang['month'];
+$month_list[0]='------------';
+ksort($month_list);
+
+$template->assign(
+  array(
+    'CATEGORIES_NAV'=>$page['title'],
+
+    'U_ELEMENTS_PAGE'
+    =>$base_url.get_query_string_diff(array('display','start')),
+
+    'U_GLOBAL_MODE'
+    =>
+    $base_url
+    .get_query_string_diff(array('mode','display'))
+    .'&amp;mode=global',
+
+    'F_ACTION'=>$base_url.get_query_string_diff(array()),
+    
+    'month_list' => $month_list
+    )
+  );
+
+// +-----------------------------------------------------------------------+
+// |                        global mode thumbnails                         |
+// +-----------------------------------------------------------------------+
+
+// how many items to display on this page
+if (!empty($_GET['display']))
+{
+  if ('all' == $_GET['display'])
+  {
+    $page['nb_images'] = count($page['cat_elements_id']);
+  }
+  else
+  {
+    $page['nb_images'] = intval($_GET['display']);
+  }
+}
+else
+{
+  $page['nb_images'] = 5;
+}
+
+
+
+if (count($page['cat_elements_id']) > 0)
+{
+  $nav_bar = create_navigation_bar(
+    $base_url.get_query_string_diff(array('start')),
+    count($page['cat_elements_id']),
+    $page['start'],
+    $page['nb_images']
+    );
+  $template->assign(array('NAV_BAR' => $nav_bar));
+
+  // tags
+  $all_tags = get_all_tags();
+
+  $element_ids = array();
+
+  $query = '
+SELECT id,path,tn_ext,name,date_creation,comment,author,file
+  FROM '.IMAGES_TABLE.'
+  WHERE id IN ('.implode(',', $page['cat_elements_id']).')
+  '.$conf['order_by'].'
+  LIMIT '.$page['start'].', '.$page['nb_images'].'
+;';
+  $result = pwg_query($query);
+
+  while ($row = mysql_fetch_assoc($result))
+  {
+    // echo '<pre>'; print_r($row); echo '</pre>';
+    array_push($element_ids, $row['id']);
+
+    $src = get_thumbnail_url($row);
+
+    $query = '
+SELECT tag_id
+  FROM '.IMAGE_TAG_TABLE.'
+  WHERE image_id = '.$row['id'].'
+;';
+    $selected_tags = array_from_query($query, 'tag_id');
+
+    // creation date
+    if (!empty($row['date_creation']))
+    {
+      list($year,$month,$day) = explode('-', $row['date_creation']);
+    }
+    else
+    {
+      list($year,$month,$day) = array('',0,0);
+    }
+
+    if (count($all_tags) > 0)
+    {
+      $tag_selection = get_html_tag_selection(
+        $all_tags,
+        'tags-'.$row['id'],
+        $selected_tags
+        );
+    }
+    else
+    {
+      $tag_selection =
+        '<p>'.
+        l10n('No tag defined. Use Administration>Pictures>Tags').
+        '</p>';
+    }
+
+    $template->append(
+      'elements',
+      array(
+        'ID' => $row['id'],
+        'TN_SRC' => $src,
+        'LEGEND' =>
+          !empty($row['name']) ?
+            $row['name'] : get_name_from_file($row['file']),
+        'U_EDIT' =>
+            PHPWG_ROOT_PATH.'admin.php?page=picture_modify'.
+            '&amp;image_id='.$row['id'],
+        'NAME' => @$row['name'],
+        'AUTHOR' => @$row['author'],
+        'DESCRIPTION' => @$row['comment'],
+        'DATE_CREATION_YEAR' => $year,
+        'DATE_CREATION_MONTH' => (int)$month,
+        'DATE_CREATION_DAY' => (int)$day,
+
+        'TAG_SELECTION' => $tag_selection,
+        )
+      );
+  }
+
+  $template->assign('ELEMENT_IDS', implode(',', $element_ids));
+}
+
+// +-----------------------------------------------------------------------+
+// |                           sending html code                           |
+// +-----------------------------------------------------------------------+
+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'element_set_unit');
+?>
Index: /tags/2.0.2/admin/extend_for_templates.php
===================================================================
--- /tags/2.0.2/admin/extend_for_templates.php	(revision 3278)
+++ /tags/2.0.2/admin/extend_for_templates.php	(revision 3278)
@@ -0,0 +1,199 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+/**
+ * Define replacement conditions for each template from template-extension
+ * (template called "replacer").
+ *
+ * "original template" from ./template/yoga (or any other than yoga)
+ * will be replaced by a "replacer" if the replacer is linked to this "original template"
+ * (and optionally, when the requested URL contains an "optional URL keyword").
+ *
+ * "Optional URL keywords" are those you can find after the module name in URLs.
+ *
+ * Therefore "Optional URL keywords" can be an active "permalink" 
+ * (see permalinks in our documentation for further explanation).
+ */
+
+// +-----------------------------------------------------------------------+
+//                            initialization                              |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH')) { die('Hacking attempt!'); }
+include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+check_status(ACCESS_ADMINISTRATOR);
+
+$tpl_extension = isset($conf['extents_for_templates']) ?
+      unserialize($conf['extents_for_templates']) : array();
+$new_extensions = get_extents(); 
+
+/* Selective URLs keyword */
+$relevant_parameters = array(
+    '----------',
+    'category',
+    'favorites',
+    'most_visited',
+    'best_rated',
+    'recent_pics',
+    'recent_cats',
+    'created-monthly-calendar',
+    'posted-monthly-calendar',
+    'search',
+    'flat',
+    'list', /* <=> Random */
+    'tags',
+    ); 
+  $query = '
+SELECT permalink
+  FROM '.CATEGORIES_TABLE.'
+  WHERE permalink IS NOT NULL
+';
+
+/* Add active permalinks */ 
+$permalinks = array_from_query($query, 'permalink');
+$relevant_parameters = array_merge($relevant_parameters, $permalinks);
+
+/* Link all supported templates to their respective handle */
+$eligible_templates = array(
+    '----------'                 => 'N/A',
+    'about.tpl'                  => 'about',
+    'footer.tpl'                 => 'tail',
+    'header.tpl'                 => 'header',
+    'identification.tpl'         => 'identification',
+    'index.tpl'                  => 'index',
+    'mainpage_categories.tpl'    => 'index_category_thumbnails',
+    'menubar.tpl'                => 'menubar',
+    'menubar_categories.tpl'     => 'mbCategories',
+    'menubar_identification.tpl' => 'mbIdentification',
+    'menubar_links.tpl'          => 'mbLinks',
+    'menubar_menu.tpl'           => 'mbMenu',
+    'menubar_specials.tpl'       => 'mbSpecials',
+    'menubar_tags.tpl'           => 'mbTags',
+    'nbm.tpl'                    => 'nbm',
+    'notification.tpl'           => 'notification',
+    'picture.tpl'                => 'picture',
+    'picture_content.tpl'        => 'default_content',
+    'popuphelp.tpl'              => 'popuphelp',
+    'profile.tpl'                => 'profile',
+    'profile_content.tpl'        => 'profile_content',
+    'redirect.tpl'               => 'redirect',
+    'register.tpl'               => 'register',
+    'search.tpl'                 => 'search',
+    'search_rules.tpl'           => 'search_rules',
+    'slideshow.tpl'              => 'slideshow',
+    'tags.tpl'                   => 'tags',
+    'thumbnails.tpl'             => 'index_thumbnails',
+    'upload.tpl'                 => 'upload',);
+
+$flip_templates = array_flip($eligible_templates);
+
+$available_templates = array_merge(
+  array('N/A' => '----------'),
+  get_dirs(PHPWG_ROOT_PATH.'template'));
+
+// +-----------------------------------------------------------------------+
+// |                            selected templates                         |
+// +-----------------------------------------------------------------------+
+
+if (isset($_POST['submit']) and !is_adviser())
+{
+  $replacements = array();
+  $i = 0;
+  while (isset($_POST['reptpl'][$i]))
+  {
+    $newtpl = $_POST['reptpl'][$i];
+    $original = $_POST['original'][$i];
+    $handle = $eligible_templates[$original];
+    $url_keyword = $_POST['url'][$i];
+    if ($url_keyword == '----------') $url_keyword = 'N/A';
+    $bound_tpl = $_POST['bound'][$i];
+    if ($bound_tpl == '----------') $bound_tpl = 'N/A';
+    if ($handle != 'N/A')
+    {
+      $replacements[$newtpl] = array($handle, $url_keyword, $bound_tpl);
+    }
+    $i++;
+  }
+  $conf['extents_for_templates'] = serialize($replacements);
+  $tpl_extension = $replacements;
+  /* ecrire la nouvelle conf */
+  $query = "
+UPDATE ".CONFIG_TABLE."
+  SET value = '". $conf['extents_for_templates'] ."'
+WHERE param = 'extents_for_templates';";
+  if (pwg_query($query))
+  {
+    array_push($page['infos'], 
+      l10n('Templates recorded.'));
+  }
+}
+
+// +-----------------------------------------------------------------------+
+// |                             template init                             |
+// +-----------------------------------------------------------------------+
+
+/* Clearing (remove old extents, add new ones) */
+foreach ($tpl_extension as $file => $conditions)
+{
+  if ( !in_array($file,$new_extensions) ) unset($tpl_extension[$file]);
+  else $new_extensions = array_diff($new_extensions,array($file)); 
+}
+foreach ($new_extensions as $file)
+{
+  $tpl_extension[$file] = array('N/A', 'N/A', 'N/A');
+}
+
+$template->set_filenames(array('extend_for_templates'
+     => 'extend_for_templates.tpl'));
+
+$base_url = PHPWG_ROOT_PATH.'admin.php?page=extend_for_templates';
+
+$template->assign(
+  array(
+    'U_HELP' => get_root_url().'popuphelp.php?page=extend_for_templates',
+    ));
+ksort($tpl_extension);
+foreach ($tpl_extension as $file => $conditions)    
+{
+  $handle = $conditions[0];
+  $url_keyword = $conditions[1];
+  $bound_tpl = $conditions[2];
+  {  
+  $template->append('extents',
+    array(
+      'replacer'       => $file,
+      'url_parameter'  => $relevant_parameters,
+      'original_tpl'   => array_keys($eligible_templates),
+      'bound_tpl'          => $available_templates,
+      'selected_tpl'   => $flip_templates[$handle],
+      'selected_url'   => $url_keyword,
+      'selected_bound' => $bound_tpl,)
+      );
+  }
+}
+// +-----------------------------------------------------------------------+
+// |                           html code display                           |
+// +-----------------------------------------------------------------------+
+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'extend_for_templates');
+?>
Index: /tags/2.0.2/admin/group_list.php
===================================================================
--- /tags/2.0.2/admin/group_list.php	(revision 3278)
+++ /tags/2.0.2/admin/group_list.php	(revision 3278)
@@ -0,0 +1,207 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if( !defined("PHPWG_ROOT_PATH") )
+{
+  die ("Hacking attempt!");
+}
+
+include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+
+// +-----------------------------------------------------------------------+
+// | Check Access and exit when user status is not ok                      |
+// +-----------------------------------------------------------------------+
+check_status(ACCESS_ADMINISTRATOR);
+
+// +-----------------------------------------------------------------------+
+// |                             delete a group                            |
+// +-----------------------------------------------------------------------+
+
+if (isset($_GET['delete']) and is_numeric($_GET['delete']) and !is_adviser())
+{
+  // destruction of the access linked to the group
+  $query = '
+DELETE
+  FROM '.GROUP_ACCESS_TABLE.'
+  WHERE group_id = '.$_GET['delete'].'
+;';
+  pwg_query($query);
+  
+  // destruction of the users links for this group
+  $query = '
+DELETE
+  FROM '.USER_GROUP_TABLE.'
+  WHERE group_id = '.$_GET['delete'].'
+;';
+  pwg_query($query);
+
+  $query = '
+SELECT name
+  FROM '.GROUPS_TABLE.'
+  WHERE id = '.$_GET['delete'].'
+;';
+  list($groupname) = mysql_fetch_row(pwg_query($query));
+  
+  // destruction of the group
+  $query = '
+DELETE
+  FROM '.GROUPS_TABLE.'
+  WHERE id = '.$_GET['delete'].'
+;';
+  pwg_query($query);
+
+  array_push(
+    $page['infos'],
+    sprintf(l10n('group "%s" deleted'), $groupname)
+    );
+}
+
+// +-----------------------------------------------------------------------+
+// |                              add a group                              |
+// +-----------------------------------------------------------------------+
+
+if (isset($_POST['submit_add']) and !is_adviser())
+{
+  if (empty($_POST['groupname']))
+  {
+    array_push($page['errors'], l10n('group_add_error1'));
+  }
+  if (count($page['errors']) == 0)
+  {
+    // is the group not already existing ?
+    $query = '
+SELECT COUNT(*)
+  FROM '.GROUPS_TABLE.'
+  WHERE name = \''.$_POST['groupname'].'\'
+;';
+    list($count) = mysql_fetch_row(pwg_query($query));
+    if ($count != 0)
+    {
+      array_push($page['errors'], l10n('group_add_error2'));
+    }
+  }
+  if (count($page['errors']) == 0)
+  {
+    // creating the group
+    $query = '
+INSERT INTO '.GROUPS_TABLE.'
+  (name)
+  VALUES
+  (\''.mysql_real_escape_string($_POST['groupname']).'\')
+;';
+    pwg_query($query);
+
+    array_push(
+      $page['infos'],
+      sprintf(l10n('group "%s" added'), $_POST['groupname'])
+      );
+  }
+}
+
+// +-----------------------------------------------------------------------+
+// | toggle is default group property                                      |
+// +-----------------------------------------------------------------------+
+
+if (isset($_GET['toggle_is_default']) and is_numeric($_GET['toggle_is_default']) and !is_adviser())
+{
+  $query = '
+SELECT name, is_default
+  FROM '.GROUPS_TABLE.'
+  WHERE id = '.$_GET['toggle_is_default'].'
+;';
+  list($groupname, $is_default) = mysql_fetch_row(pwg_query($query));
+  
+  // update of the group
+  $query = '
+UPDATE '.GROUPS_TABLE.'
+  SET is_default = \''.boolean_to_string(!get_boolean($is_default)).'\'
+  WHERE id = '.$_GET['toggle_is_default'].'
+;';
+  pwg_query($query);
+
+  array_push(
+    $page['infos'],
+    sprintf(l10n('group "%s" updated'), $groupname)
+    );
+}
+
+// +-----------------------------------------------------------------------+
+// |                             template init                             |
+// +-----------------------------------------------------------------------+
+
+$template->set_filenames(array('group_list' => 'group_list.tpl'));
+
+$template->assign(
+  array(
+    'F_ADD_ACTION' => get_root_url().'admin.php?page=group_list',
+    'U_HELP' => get_root_url().'popuphelp.php?page=group_list',
+    )
+  );
+
+// +-----------------------------------------------------------------------+
+// |                              group list                               |
+// +-----------------------------------------------------------------------+
+
+$query = '
+SELECT id, name, is_default
+  FROM '.GROUPS_TABLE.'
+  ORDER BY name ASC
+;';
+$result = pwg_query($query);
+
+$admin_url = get_root_url().'admin.php?page=';
+$perm_url    = $admin_url.'group_perm&amp;group_id=';
+$del_url     = $admin_url.'group_list&amp;delete=';
+$members_url = $admin_url.'user_list&amp;group=';
+$toggle_is_default_url     = $admin_url.'group_list&amp;toggle_is_default=';
+
+while ($row = mysql_fetch_array($result))
+{
+  $query = '
+SELECT COUNT(*)
+  FROM '.USER_GROUP_TABLE.'
+  WHERE group_id = '.$row['id'].'
+;';
+  list($counter) = mysql_fetch_row(pwg_query($query));
+  
+  $template->append(
+    'groups',
+    array(
+      'NAME' => $row['name'],
+      'IS_DEFAULT' => (get_boolean($row['is_default']) ? ' ['.l10n('is_default_group').']' : ''),
+      'MEMBERS' => l10n_dec('%d member', '%d members', $counter),
+      'U_MEMBERS' => $members_url.$row['id'],
+      'U_DELETE' => $del_url.$row['id'],
+      'U_PERM' => $perm_url.$row['id'],
+      'U_ISDEFAULT' => $toggle_is_default_url.$row['id']
+      )
+    );
+}
+
+// +-----------------------------------------------------------------------+
+// |                           sending html code                           |
+// +-----------------------------------------------------------------------+
+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'group_list');
+
+?>
Index: /tags/2.0.2/admin/group_perm.php
===================================================================
--- /tags/2.0.2/admin/group_perm.php	(revision 3278)
+++ /tags/2.0.2/admin/group_perm.php	(revision 3278)
@@ -0,0 +1,185 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if( !defined("PHPWG_ROOT_PATH") )
+{
+  die ("Hacking attempt!");
+}
+
+include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+
+// +-----------------------------------------------------------------------+
+// | Check Access and exit when user status is not ok                      |
+// +-----------------------------------------------------------------------+
+check_status(ACCESS_ADMINISTRATOR);
+
+// +-----------------------------------------------------------------------+
+// |                            variables init                             |
+// +-----------------------------------------------------------------------+
+
+if (isset($_GET['group_id']) and is_numeric($_GET['group_id']))
+{
+  $page['group'] = $_GET['group_id'];
+}
+else
+{
+  die('group_id URL parameter is missing');
+}
+
+// +-----------------------------------------------------------------------+
+// |                                updates                                |
+// +-----------------------------------------------------------------------+
+
+if (isset($_POST['falsify'])
+    and isset($_POST['cat_true'])
+    and count($_POST['cat_true']) > 0)
+{
+  // if you forbid access to a category, all sub-categories become
+  // automatically forbidden
+  $subcats = get_subcat_ids($_POST['cat_true']);
+  $query = '
+DELETE
+  FROM '.GROUP_ACCESS_TABLE.'
+  WHERE group_id = '.$page['group'].'
+  AND cat_id IN ('.implode(',', $subcats).')
+;';
+  pwg_query($query);
+}
+else if (isset($_POST['trueify'])
+         and isset($_POST['cat_false'])
+         and count($_POST['cat_false']) > 0)
+{
+  $uppercats = get_uppercat_ids($_POST['cat_false']);
+  $private_uppercats = array();
+
+  $query = '
+SELECT id
+  FROM '.CATEGORIES_TABLE.'
+  WHERE id IN ('.implode(',', $uppercats).')
+  AND status = \'private\'
+;';
+  $result = pwg_query($query);
+  while ($row = mysql_fetch_array($result))
+  {
+    array_push($private_uppercats, $row['id']);
+  }
+
+  // retrying to authorize a category which is already authorized may cause
+  // an error (in SQL statement), so we need to know which categories are
+  // accesible
+  $authorized_ids = array();
+
+  $query = '
+SELECT cat_id
+  FROM '.GROUP_ACCESS_TABLE.'
+  WHERE group_id = '.$page['group'].'
+;';
+  $result = pwg_query($query);
+
+  while ($row = mysql_fetch_array($result))
+  {
+    array_push($authorized_ids, $row['cat_id']);
+  }
+
+  $inserts = array();
+  $to_autorize_ids = array_diff($private_uppercats, $authorized_ids);
+  foreach ($to_autorize_ids as $to_autorize_id)
+  {
+    array_push(
+      $inserts,
+      array(
+        'group_id' => $page['group'],
+        'cat_id' => $to_autorize_id
+        )
+      );
+  }
+
+  mass_inserts(GROUP_ACCESS_TABLE, array('group_id','cat_id'), $inserts);
+}
+
+// +-----------------------------------------------------------------------+
+// |                             template init                             |
+// +-----------------------------------------------------------------------+
+
+$template->set_filenames(
+  array(
+    'group_perm' => 'group_perm.tpl',
+    'double_select' => 'double_select.tpl'
+    )
+  );
+
+$template->assign(
+  array(
+    'TITLE' =>
+      sprintf(
+        l10n('Manage permissions for group "%s"'),
+        get_groupname($page['group']
+          )
+        ),
+    'L_CAT_OPTIONS_TRUE'=>l10n('authorized'),
+    'L_CAT_OPTIONS_FALSE'=>l10n('forbidden'),
+
+    'F_ACTION' =>
+        get_root_url().
+        'admin.php?page=group_perm&amp;group_id='.
+        $page['group']
+    )
+  );
+
+// only private categories are listed
+$query_true = '
+SELECT id,name,uppercats,global_rank
+  FROM '.CATEGORIES_TABLE.' INNER JOIN '.GROUP_ACCESS_TABLE.' ON cat_id = id
+  WHERE status = \'private\'
+    AND group_id = '.$page['group'].'
+;';
+display_select_cat_wrapper($query_true,array(),'category_option_true');
+
+$result = pwg_query($query_true);
+$authorized_ids = array();
+while ($row = mysql_fetch_array($result))
+{
+  array_push($authorized_ids, $row['id']);
+}
+
+$query_false = '
+SELECT id,name,uppercats,global_rank
+  FROM '.CATEGORIES_TABLE.'
+  WHERE status = \'private\'';
+if (count($authorized_ids) > 0)
+{
+  $query_false.= '
+    AND id NOT IN ('.implode(',', $authorized_ids).')';
+}
+$query_false.= '
+;';
+display_select_cat_wrapper($query_false,array(),'category_option_false');
+
+// +-----------------------------------------------------------------------+
+// |                           html code display                           |
+// +-----------------------------------------------------------------------+
+
+$template->assign_var_from_handle('DOUBLE_SELECT', 'double_select');
+$template->assign_var_from_handle('ADMIN_CONTENT', 'group_perm');
+
+?>
Index: /tags/2.0.2/admin/help.php
===================================================================
--- /tags/2.0.2/admin/help.php	(revision 3278)
+++ /tags/2.0.2/admin/help.php	(revision 3278)
@@ -0,0 +1,32 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+
+// +-----------------------------------------------------------------------+
+// | Check Access and exit when user status is not ok                      |
+// +-----------------------------------------------------------------------+
+check_status(ACCESS_ADMINISTRATOR);
+
+$template->assign('ADMIN_CONTENT', load_language('help.html','',array('return'=>true)) );
+?>
Index: /tags/2.0.2/admin/history.php
===================================================================
--- /tags/2.0.2/admin/history.php	(revision 3278)
+++ /tags/2.0.2/admin/history.php	(revision 3278)
@@ -0,0 +1,686 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+/**
+ * Display filtered history lines
+ */
+
+// +-----------------------------------------------------------------------+
+// |                              functions                                |
+// +-----------------------------------------------------------------------+
+
+// +-----------------------------------------------------------------------+
+// |                           initialization                              |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+include_once(PHPWG_ROOT_PATH.'admin/include/functions_history.inc.php');
+
+if (isset($_GET['start']) and is_numeric($_GET['start']))
+{
+  $page['start'] = $_GET['start'];
+}
+else
+{
+  $page['start'] = 0;
+}
+
+$types = array('none', 'picture', 'high', 'other');
+$display_thumbnails = array('no_display_thumbnail', 'display_thumbnail_classic', 'display_thumbnail_hoverbox');
+
+// +-----------------------------------------------------------------------+
+// | Check Access and exit when user status is not ok                      |
+// +-----------------------------------------------------------------------+
+
+check_status(ACCESS_ADMINISTRATOR);
+
+// +-----------------------------------------------------------------------+
+// | Build search criteria and redirect to results                         |
+// +-----------------------------------------------------------------------+
+
+$page['errors'] = array();
+$search = array();
+
+if (isset($_POST['submit']))
+{
+  // dates
+  if (!empty($_POST['start_year']))
+  {
+    $search['fields']['date-after'] = sprintf(
+      '%d-%02d-%02d',
+      $_POST['start_year'],
+      $_POST['start_month'],
+      $_POST['start_day']
+      );
+  }
+
+  if (!empty($_POST['end_year']))
+  {
+    $search['fields']['date-before'] = sprintf(
+      '%d-%02d-%02d',
+      $_POST['end_year'],
+      $_POST['end_month'],
+      $_POST['end_day']
+      );
+  }
+
+  if (empty($_POST['types']))
+  {
+    $search['fields']['types'] = $types;
+  }
+  else
+  {
+    $search['fields']['types'] = $_POST['types'];
+  }
+
+  $search['fields']['user'] = $_POST['user'];
+
+  if (!empty($_POST['image_id']))
+  {
+    $search['fields']['image_id'] = intval($_POST['image_id']);
+  }
+
+  if (!empty($_POST['filename']))
+  {
+    $search['fields']['filename'] = str_replace(
+      '*',
+      '%',
+      mysql_real_escape_string($_POST['filename'])
+      );
+  }
+
+  $search['fields']['display_thumbnail'] = $_POST['display_thumbnail'];
+  // Display choise are also save to one cookie
+  $cookie_val = ($_POST['display_thumbnail']!=$display_thumbnails[2] and in_array($_POST['display_thumbnail'], $display_thumbnails)) ? $_POST['display_thumbnail']:null;
+  pwg_set_cookie_var('history_display_thumbnail', $cookie_val, strtotime('+1 month') );
+
+  // TODO manage inconsistency of having $_POST['image_id'] and
+  // $_POST['filename'] simultaneously
+
+  // echo '<pre>'; print_r($search); echo '</pre>';
+
+  if (!empty($search))
+  {
+    // register search rules in database, then they will be available on
+    // thumbnails page and picture page.
+    $query ='
+INSERT INTO '.SEARCH_TABLE.'
+  (rules)
+  VALUES
+  (\''.serialize($search).'\')
+;';
+    pwg_query($query);
+
+    $search_id = mysql_insert_id();
+
+    redirect(
+      PHPWG_ROOT_PATH.'admin.php?page=history&search_id='.$search_id
+      );
+  }
+  else
+  {
+    array_push($page['errors'], l10n('search_one_clause_at_least'));
+  }
+}
+
+// +-----------------------------------------------------------------------+
+// |                             template init                             |
+// +-----------------------------------------------------------------------+
+
+$template->set_filename('history', 'history.tpl');
+
+// TabSheet initialization
+history_tabsheet();
+
+$template->assign(
+  array(
+    'U_HELP' => PHPWG_ROOT_PATH.'popuphelp.php?page=history',
+    'F_ACTION' => get_root_url().'admin.php?page=history'
+    )
+  );
+
+// +-----------------------------------------------------------------------+
+// |                             history lines                             |
+// +-----------------------------------------------------------------------+
+
+if (isset($_GET['search_id'])
+    and $page['search_id'] = (int)$_GET['search_id'])
+{
+  // what are the lines to display in reality ?
+  $query = '
+SELECT rules
+  FROM '.SEARCH_TABLE.'
+  WHERE id = '.$page['search_id'].'
+;';
+  list($serialized_rules) = mysql_fetch_row(pwg_query($query));
+
+  $page['search'] = unserialize($serialized_rules);
+
+  if (isset($_GET['user_id']))
+  {
+    if (!is_numeric($_GET['user_id']))
+    {
+      die('user_id GET parameter must be an integer value');
+    }
+
+    $page['search']['fields']['user'] = $_GET['user_id'];
+
+    $query ='
+INSERT INTO '.SEARCH_TABLE.'
+  (rules)
+  VALUES
+  (\''.serialize($page['search']).'\')
+;';
+    pwg_query($query);
+
+    $search_id = mysql_insert_id();
+
+    redirect(
+      PHPWG_ROOT_PATH.'admin.php?page=history&search_id='.$search_id
+      );
+  }
+
+  $data = trigger_event('get_history', array(), $page['search'], $types);
+  usort($data, 'history_compare');
+
+  $page['nb_lines'] = count($data);
+
+  $history_lines = array();
+  $user_ids = array();
+  $username_of = array();
+  $category_ids = array();
+  $image_ids = array();
+  $tag_ids = array();
+
+  foreach ($data as $row)
+  {
+    $user_ids[$row['user_id']] = 1;
+
+    if (isset($row['category_id']))
+    {
+      $category_ids[$row['category_id']] = 1;
+    }
+
+    if (isset($row['image_id']))
+    {
+      $image_ids[$row['image_id']] = 1;
+    }
+
+    if (isset($row['tag_ids']))
+    {
+      foreach (explode(',', $row['tag_ids']) as $tag_id)
+      {
+        array_push($tag_ids, $tag_id);
+      }
+    }
+
+    array_push(
+      $history_lines,
+      $row
+      );
+  }
+
+  // prepare reference data (users, tags, categories...)
+  if (count($user_ids) > 0)
+  {
+    $query = '
+SELECT '.$conf['user_fields']['id'].' AS id
+     , '.$conf['user_fields']['username'].' AS username
+  FROM '.USERS_TABLE.'
+  WHERE id IN ('.implode(',', array_keys($user_ids)).')
+;';
+    $result = pwg_query($query);
+
+    $username_of = array();
+    while ($row = mysql_fetch_array($result))
+    {
+      $username_of[$row['id']] = $row['username'];
+    }
+  }
+
+  if (count($category_ids) > 0)
+  {
+    $query = '
+SELECT id, uppercats
+  FROM '.CATEGORIES_TABLE.'
+  WHERE id IN ('.implode(',', array_keys($category_ids)).')
+;';
+    $uppercats_of = simple_hash_from_query($query, 'id', 'uppercats');
+
+    $name_of_category = array();
+
+    foreach ($uppercats_of as $category_id => $uppercats)
+    {
+      $name_of_category[$category_id] = get_cat_display_name_cache(
+        $uppercats
+        );
+    }
+  }
+
+  if (count($image_ids) > 0)
+  {
+    $query = '
+SELECT
+    id,
+    IF(name IS NULL, file, name) AS label,
+    filesize,
+    high_filesize,
+    file,
+    path,
+    tn_ext
+  FROM '.IMAGES_TABLE.'
+  WHERE id IN ('.implode(',', array_keys($image_ids)).')
+;';
+    // $label_of_image = simple_hash_from_query($query, 'id', 'label');
+    $label_of_image = array();
+    $filesize_of_image = array();
+    $high_filesize_of_image = array();
+    $file_of_image = array();
+    $path_of_image = array();
+    $tn_ext_of_image = array();
+
+    $result = pwg_query($query);
+    while ($row = mysql_fetch_array($result))
+    {
+      $label_of_image[ $row['id'] ] = $row['label'];
+
+      if (isset($row['filesize']))
+      {
+        $filesize_of_image[ $row['id'] ] = $row['filesize'];
+      }
+
+      if (isset($row['high_filesize']))
+      {
+        $high_filesize_of_image[ $row['id'] ] = $row['high_filesize'];
+      }
+
+      $file_of_image[ $row['id'] ] = $row['file'];
+      $path_of_image[ $row['id'] ] = $row['path'];
+      $tn_ext_of_image[ $row['id'] ] = $row['tn_ext'];
+    }
+
+    // echo '<pre>'; print_r($high_filesize_of_image); echo '</pre>';
+  }
+
+  if (count($tag_ids) > 0)
+  {
+    $tag_ids = array_unique($tag_ids);
+
+    $query = '
+SELECT
+    id,
+    name
+  FROM '.TAGS_TABLE.'
+  WHERE id IN ('.implode(', ', $tag_ids).')
+;';
+    $name_of_tag = array();
+
+    $result = pwg_query($query);
+    while ($row = mysql_fetch_array($result))
+    {
+      $name_of_tag[ $row['id'] ] = $row['name'];
+    }
+  }
+
+  $i = 0;
+  $first_line = $page['start'] + 1;
+  $last_line = $page['start'] + $conf['nb_logs_page'];
+
+  $summary['total_filesize'] = 0;
+  $summary['guests_IP'] = array();
+
+  foreach ($history_lines as $line)
+  {
+    // FIXME when we watch the representative of a non image element, it is
+    // the not the representative filesize that is counted (as it is
+    // unknown) but the non image element filesize. Proposed solution: add
+    // #images.representative_filesize and add 'representative' in the
+    // choices of #history.image_type.
+
+    if (isset($line['image_type']))
+    {
+      if ($line['image_type'] == 'high')
+      {
+        if (isset($high_filesize_of_image[$line['image_id']]))
+        {
+          $summary['total_filesize']+=
+            $high_filesize_of_image[$line['image_id']];
+        }
+      }
+      else
+      {
+        if (isset($filesize_of_image[$line['image_id']]))
+        {
+          $summary['total_filesize']+=
+            $filesize_of_image[$line['image_id']];
+        }
+      }
+    }
+
+    if ($line['user_id'] == $conf['guest_id'])
+    {
+      if (!isset($summary['guests_IP'][ $line['IP'] ]))
+      {
+        $summary['guests_IP'][ $line['IP'] ] = 0;
+      }
+
+      $summary['guests_IP'][ $line['IP'] ]++;
+    }
+
+    $i++;
+
+    if ($i < $first_line or $i > $last_line)
+    {
+      continue;
+    }
+
+    $user_string = '';
+    if (isset($username_of[$line['user_id']]))
+    {
+      $user_string.= $username_of[$line['user_id']];
+    }
+    else
+    {
+      $user_string.= $line['user_id'];
+    }
+    $user_string.= '&nbsp;<a href="';
+    $user_string.= PHPWG_ROOT_PATH.'admin.php?page=history';
+    $user_string.= '&amp;search_id='.$page['search_id'];
+    $user_string.= '&amp;user_id='.$line['user_id'];
+    $user_string.= '">+</a>';
+
+    $tags_string = '';
+    if (isset($line['tag_ids']))
+    {
+      $tags_string = preg_replace(
+        '/(\d+)/e',
+        '$name_of_tag["$1"]',
+        str_replace(
+          ',',
+          ', ',
+          $line['tag_ids']
+          )
+        );
+    }
+
+    $image_string = '';
+    if (isset($line['image_id']))
+    {
+      $picture_url = make_picture_url(
+        array(
+          'image_id' => $line['image_id'],
+          )
+        );
+
+      $element = array(
+           'id' => $line['image_id'],
+           'file' => $file_of_image[$line['image_id']],
+           'path' => $path_of_image[$line['image_id']],
+           'tn_ext' => $tn_ext_of_image[$line['image_id']],
+           );
+
+      $image_title = '('.$line['image_id'].')';
+
+      if (isset($label_of_image[$line['image_id']]))
+      {
+        $image_title.= ' '.$label_of_image[$line['image_id']];
+      }
+      else
+      {
+        $image_title.= ' unknown filename';
+      }
+
+      $image_string = '';
+
+      switch ($page['search']['fields']['display_thumbnail'])
+      {
+        case 'no_display_thumbnail':
+        {
+          $image_string= '<a href="'.$picture_url.'">'.$image_title.'</a>';
+          break;
+        }
+        case 'display_thumbnail_classic':
+        {
+          $image_string =
+            '<a class="thumbnail" href="'.$picture_url.'">'
+            .'<span><img src="'.get_thumbnail_url($element)
+            .'" alt="'.$image_title.'" title="'.$image_title.'">'
+            .'</span></a>';
+          break;
+        }
+        case 'display_thumbnail_hoverbox':
+        {
+          $image_string =
+            '<a class="over" href="'.$picture_url.'">'
+            .'<span><img src="'.get_thumbnail_url($element)
+            .'" alt="'.$image_title.'" title="'.$image_title.'">'
+            .'</span>'.$image_title.'</a>';
+          break;
+        }
+      }
+    }
+
+    $template->append(
+      'search_results',
+      array(
+        'DATE'      => $line['date'],
+        'TIME'      => $line['time'],
+        'USER'      => $user_string,
+        'IP'        => $line['IP'],
+        'IMAGE'     => $image_string,
+        'TYPE'      => $line['image_type'],
+        'SECTION'   => $line['section'],
+        'CATEGORY'  => isset($line['category_id'])
+          ? ( isset($name_of_category[$line['category_id']])
+                ? $name_of_category[$line['category_id']]
+                : 'deleted '.$line['category_id'] )
+          : '',
+        'TAGS'       => $tags_string,
+        )
+      );
+  }
+
+  $summary['nb_guests'] = 0;
+  if (count(array_keys($summary['guests_IP'])) > 0)
+  {
+    $summary['nb_guests'] = count(array_keys($summary['guests_IP']));
+
+    // we delete the "guest" from the $username_of hash so that it is
+    // avoided in next steps
+    unset($username_of[ $conf['guest_id'] ]);
+  }
+
+  $summary['nb_members'] = count($username_of);
+
+  $member_strings = array();
+  foreach ($username_of as $user_id => $user_name)
+  {
+    $member_string = $user_name.'&nbsp;<a href="';
+    $member_string.= get_root_url().'admin.php?page=history';
+    $member_string.= '&amp;search_id='.$page['search_id'];
+    $member_string.= '&amp;user_id='.$user_id;
+    $member_string.= '">+</a>';
+
+    $member_strings[] = $member_string;
+  }
+
+  $template->assign(
+    'search_summary',
+    array(
+      'NB_LINES' => l10n_dec(
+        '%d line filtered', '%d lines filtered',
+        $page['nb_lines']
+        ),
+      'FILESIZE' => $summary['total_filesize'].' KB',
+      'USERS' => l10n_dec(
+        '%d user', '%d users',
+        $summary['nb_members'] + $summary['nb_guests']
+        ),
+      'MEMBERS' => sprintf(
+        l10n_dec('%d member', '%d members', $summary['nb_members']).': %s',
+        implode(
+          ', ',
+          $member_strings
+          )
+        ),
+      'GUESTS' => l10n_dec(
+        '%d guest', '%d guests',
+        $summary['nb_guests']
+        ),
+      )
+    );
+}
+
+// +-----------------------------------------------------------------------+
+// |                            navigation bar                             |
+// +-----------------------------------------------------------------------+
+
+if (isset($page['search_id']))
+{
+  $navbar = create_navigation_bar(
+    get_root_url().'admin.php'.get_query_string_diff(array('start')),
+    $page['nb_lines'],
+    $page['start'],
+    $conf['nb_logs_page']
+    );
+
+  $template->assign('NAV_BAR', $navbar);
+}
+
+// +-----------------------------------------------------------------------+
+// |                             filter form                               |
+// +-----------------------------------------------------------------------+
+
+$form = array();
+
+if (isset($page['search']))
+{
+  if (isset($page['search']['fields']['date-after']))
+  {
+    $tokens = explode('-', $page['search']['fields']['date-after']);
+
+    $form['start_year']  = (int)$tokens[0];
+    $form['start_month'] = (int)$tokens[1];
+    $form['start_day']   = (int)$tokens[2];
+  }
+
+  if (isset($page['search']['fields']['date-before']))
+  {
+    $tokens = explode('-', $page['search']['fields']['date-before']);
+
+    $form['end_year']  = (int)$tokens[0];
+    $form['end_month'] = (int)$tokens[1];
+    $form['end_day']   = (int)$tokens[2];
+  }
+
+  $form['types'] = $page['search']['fields']['types'];
+
+  if (isset($page['search']['fields']['user']))
+  {
+    $form['user'] = $page['search']['fields']['user'];
+  }
+  else
+  {
+    $form['user'] = null;
+  }
+
+  $form['image_id'] = @$page['search']['fields']['image_id'];
+  $form['filename'] = @$page['search']['fields']['filename'];
+
+  $form['display_thumbnail'] = @$page['search']['fields']['display_thumbnail'];
+}
+else
+{
+  // by default, at page load, we want the selected date to be the current
+  // date
+  $form['start_year']  = $form['end_year']  = date('Y');
+  $form['start_month'] = $form['end_month'] = date('n');
+  $form['start_day']   = $form['end_day']   = date('j');
+  $form['types'] = $types;
+  // Hoverbox by default
+  $form['display_thumbnail'] =
+    pwg_get_cookie_var('history_display_thumbnail', $display_thumbnails[2]);
+}
+
+
+$month_list = $lang['month'];
+$month_list[0]='------------';
+ksort($month_list);
+
+$template->assign(
+  array(
+    'IMAGE_ID' => @$form['image_id'],
+    'FILENAME' => @$form['filename'],
+
+    'month_list' => $month_list,
+
+    'START_DAY_SELECTED' => @$form['start_day'],
+    'START_MONTH_SELECTED' => @$form['start_month'],
+    'START_YEAR' => @$form['start_year'],
+
+    'END_DAY_SELECTED' => @$form['end_day'],
+    'END_MONTH_SELECTED' => @$form['end_month'],
+    'END_YEAR'   => @$form['end_year'],
+    )
+  );
+
+$template->assign(
+    array(
+      'type_option_values' => $types,
+      'type_option_selected' => $form['types']
+    )
+  );
+
+
+$query = '
+SELECT
+    '.$conf['user_fields']['id'].' AS id,
+    '.$conf['user_fields']['username'].' AS username
+  FROM '.USERS_TABLE.'
+  ORDER BY username ASC
+;';
+$template->assign(
+  array(
+    'user_options' => simple_hash_from_query($query, 'id','username'),
+    'user_options_selected' => array(@$form['user'])
+  )
+);
+
+$template->assign(
+  array(
+      'display_thumbnail_values' => $display_thumbnails,
+      'display_thumbnail_selected' => array($form['display_thumbnail']),
+    )
+  );
+
+// +-----------------------------------------------------------------------+
+// |                           html code display                           |
+// +-----------------------------------------------------------------------+
+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'history');
+?>
Index: /tags/2.0.2/admin/images/index.php
===================================================================
--- /tags/2.0.2/admin/images/index.php	(revision 3278)
+++ /tags/2.0.2/admin/images/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/admin/include/c13y_internal.class.php
===================================================================
--- /tags/2.0.2/admin/include/c13y_internal.class.php	(revision 3278)
+++ /tags/2.0.2/admin/include/c13y_internal.class.php	(revision 3278)
@@ -0,0 +1,249 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+class c13y_internal
+{
+  function c13y_internal()
+  {
+    add_event_handler('list_check_integrity', array(&$this, 'c13y_version'));
+    add_event_handler('list_check_integrity', array(&$this, 'c13y_exif'));
+    add_event_handler('list_check_integrity', array(&$this, 'c13y_user'));
+  }
+
+  /**
+   * Check version
+   *
+   * @param c13y object
+   * @return void
+   */
+  function c13y_version($c13y)
+  {
+    $check_list = array();
+
+    $check_list[] = array('type' => 'PHP', 'current' => phpversion(), 'required' => REQUIRED_PHP_VERSION);
+
+    list($mysql_version) = mysql_fetch_row(pwg_query('SELECT VERSION();'));
+    $check_list[] = array('type' => 'MySQL', 'current' => $mysql_version, 'required' => REQUIRED_MYSQL_VERSION);
+
+    foreach ($check_list as $elem)
+    {
+      if (version_compare($elem['current'], $elem['required'], '<'))
+      {
+        $c13y->add_anomaly(
+          sprintf(l10n('c13y_version_anomaly'), $elem['type'], $elem['current'], $elem['required']),
+          null,
+          null,
+          l10n('c13y_version_correction')
+          .'<BR />'.
+          $c13y->get_htlm_links_more_info());
+      }
+    }
+  }
+
+  /**
+   * Check exif
+   *
+   * @param c13y object
+   * @return void
+   */
+  function c13y_exif($c13y)
+  {
+    global $conf;
+
+    foreach (array('show_exif', 'use_exif') as $value)
+    {
+      if (($conf[$value]) and (!function_exists('read_exif_data')))
+      {
+        $c13y->add_anomaly(
+          sprintf(l10n('c13y_exif_anomaly'), '$conf[\''.$value.'\']'),
+          null,
+          null,
+          sprintf(l10n('c13y_exif_correction'), '$conf[\''.$value.'\']')
+          .'<BR />'.
+          $c13y->get_htlm_links_more_info());
+      }
+    }
+  }
+
+  /**
+   * Check user
+   *
+   * @param c13y object
+   * @return void
+   */
+  function c13y_user($c13y)
+  {
+    global $conf;
+
+    $c13y_users = array();
+    $c13y_users[$conf['guest_id']] = array(
+      'status' => 'guest',
+      'l10n_non_existent' => 'c13y_guest_non_existent',
+      'l10n_bad_status' => 'c13y_bad_guest_status');
+
+    if ($conf['guest_id'] != $conf['default_user_id'])
+    {
+      $c13y_users[$conf['default_user_id']] = array(
+        'password' => null,
+        'l10n_non_existent' => 'c13y_default_non_existent');
+    }
+
+    $c13y_users[$conf['webmaster_id']] = array(
+      'status' => 'webmaster',
+      'l10n_non_existent' => 'c13y_webmaster_non_existent',
+      'l10n_bad_status' => 'c13y_bad_webmaster_status');
+
+      $query = '
+  select u.'.$conf['user_fields']['id'].' as id, ui.status
+  from '.USERS_TABLE.' as u
+    left join '.USER_INFOS_TABLE.' as ui
+        on u.'.$conf['user_fields']['id'].' = ui.user_id
+  where
+    u.'.$conf['user_fields']['id'].' in ('.implode(',', array_keys($c13y_users)).')
+  ;';
+
+
+    $status = array();
+
+    $result = pwg_query($query);
+    while ($row = mysql_fetch_array($result))
+    {
+      $status[$row['id']] = $row['status'];
+    }
+
+    foreach ($c13y_users as $id => $data)
+    {
+      if (!array_key_exists($id, $status))
+      {
+        $c13y->add_anomaly(l10n($data['l10n_non_existent']), 'c13y_correction_user',
+          array('id' => $id, 'action' => 'creation'));
+      }
+      else
+      if (!empty($data['status']) and $status[$id] != $data['status'])
+      {
+        $c13y->add_anomaly(l10n($data['l10n_bad_status']), 'c13y_correction_user',
+          array('id' => $id, 'action' => 'status'));
+      }
+    }
+  }
+
+  /**
+   * Do correction user
+   *
+   * @param user_id, action
+   * @return boolean true if ok else false
+   */
+  function c13y_correction_user($id, $action)
+  {
+    global $conf, $page;
+
+    $result = false;
+
+    if (!empty($id))
+    {
+      switch ($action)
+      {
+        case 'creation':
+          if ($id == $conf['guest_id'])
+          {
+            $name = 'guest';
+            $password = null;
+          }
+          else if  ($id == $conf['default_user_id'])
+          {
+            $name = 'guest';
+            $password = null;
+          }
+          else if  ($id == $conf['webmaster_id'])
+          {
+            $name = 'webmaster';
+            $password = generate_key(6);
+          }
+
+          if (isset($name))
+          {
+            $name_ok = false;
+            while (!$name_ok)
+            {
+              $name_ok = (get_userid($name) === false);
+              if (!$name_ok)
+              {
+                $name .= generate_key(1);
+              }
+            }
+
+            $inserts = array(
+              array(
+                'id'       => $id,
+                'username' => $name,
+                'password' => $password
+                ),
+              );
+            mass_inserts(USERS_TABLE, array_keys($inserts[0]), $inserts);
+
+            create_user_infos($id);
+
+            $page['infos'][] = sprintf(l10n('c13y_user_created'), $name, $password);
+
+            $result = true;
+          }
+          break;
+        case 'status':
+          if ($id == $conf['guest_id'])
+          {
+            $status = 'guest';
+          }
+          else if  ($id == $conf['default_user_id'])
+          {
+            $status = 'guest';
+          }
+          else if  ($id == $conf['webmaster_id'])
+          {
+            $status = 'webmaster';
+          }
+
+          if (isset($status))
+          {
+            $updates = array(
+              array(
+                'user_id' => $id,
+                'status'  => $status
+                ),
+              );
+            mass_updates(USER_INFOS_TABLE,
+              array('primary' => array('user_id'),'update' => array('status')),
+              $updates);
+
+            $page['infos'][] = sprintf(l10n('c13y_user_status_updated'), get_username($id));
+
+            $result = true;
+          }
+          break;
+      }
+    }
+
+    return $result;
+  }
+}
+
+?>
Index: /tags/2.0.2/admin/include/check_integrity.class.php
===================================================================
--- /tags/2.0.2/admin/include/check_integrity.class.php	(revision 3278)
+++ /tags/2.0.2/admin/include/check_integrity.class.php	(revision 3278)
@@ -0,0 +1,345 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+class check_integrity
+{
+  var $ignore_list;
+  var $retrieve_list;
+  var $build_ignore_list;
+
+  function check_integrity()
+  {
+    $this->ignore_list = array();
+    $this->retrieve_list = array();
+    $this->build_ignore_list = array();
+  }
+
+  /**
+   * Check integrities
+   *
+   * @param void
+   * @return void
+   */
+  function check()
+  {
+    global $page, $header_notes, $conf;
+
+    // Ignore list
+    $conf_c13y_ignore = unserialize($conf['c13y_ignore']);
+    if (
+          is_array($conf_c13y_ignore) and
+          isset($conf_c13y_ignore['version']) and
+          ($conf_c13y_ignore['version'] == PHPWG_VERSION) and
+          is_array($conf_c13y_ignore['list'])
+        )
+    {
+      $ignore_list_changed = false;
+      $this->ignore_list = $conf_c13y_ignore['list'];
+    }
+    else
+    {
+      $ignore_list_changed = true;
+      $this->ignore_list = array();
+    }
+
+    // Retrieve list
+    $this->retrieve_list = array();
+    $this->build_ignore_list = array();
+
+    trigger_action('list_check_integrity', $this);
+
+    // Information
+    if (count($this->retrieve_list) > 0)
+    {
+      $header_notes[] =
+        l10n_dec('c13y_anomaly_count', 'c13y_anomalies_count',
+          count($this->retrieve_list));
+    }
+
+    // Treatments
+    if (!is_adviser())
+    {
+      if (isset($_POST['c13y_submit_correction']) and isset($_POST['c13y_selection']))
+      {
+        $corrected_count = 0;
+        $not_corrected_count = 0;
+
+        foreach ($this->retrieve_list as $i => $c13y)
+        {
+          if (!empty($c13y['correction_fct']) and
+              $c13y['is_callable'] and
+              in_array($c13y['id'], $_POST['c13y_selection']))
+          {
+            if (is_array($c13y['correction_fct_args']))
+            {
+              $args = $c13y['correction_fct_args'];
+            }
+            else
+            if (!is_null($c13y['correction_fct_args']))
+            {
+              $args = array($c13y['correction_fct_args']);
+            }
+            else
+            {
+              $args = array();
+            }
+            $this->retrieve_list[$i]['corrected'] = call_user_func_array($c13y['correction_fct'], $args);
+
+            if ($this->retrieve_list[$i]['corrected'])
+            {
+              $corrected_count += 1;
+            }
+            else
+            {
+              $not_corrected_count += 1;
+            }
+          }
+        }
+
+        if ($corrected_count > 0)
+        {
+          $page['infos'][] =
+            l10n_dec('c13y_anomaly_corrected_count', 'c13y_anomalies_corrected_count',
+              $corrected_count);
+        }
+        if ($not_corrected_count > 0)
+        {
+          $page['errors'][] =
+            l10n_dec('c13y_anomaly_not_corrected_count', 'c13y_anomalies_not_corrected_count',
+              $not_corrected_count);
+        }
+      }
+      else
+      {
+        if (isset($_POST['c13y_submit_ignore']) and isset($_POST['c13y_selection']))
+        {
+          $ignored_count = 0;
+
+          foreach ($this->retrieve_list as $i => $c13y)
+          {
+            if (in_array($c13y['id'], $_POST['c13y_selection']))
+            {
+              $this->build_ignore_list[] = $c13y['id'];
+              $this->retrieve_list[$i]['ignored'] = true;
+              $ignored_count += 1;
+            }
+          }
+
+          if ($ignored_count > 0)
+          {
+            $page['infos'][] =
+              l10n_dec('c13y_anomaly_ignored_count', 'c13y_anomalies_ignored_count',
+                $ignored_count);
+          }
+        }
+      }
+    }
+
+    $ignore_list_changed =
+      (
+        ($ignore_list_changed) or
+        (count(array_diff($this->ignore_list, $this->build_ignore_list)) > 0) or
+        (count(array_diff($this->build_ignore_list, $this->ignore_list)) > 0)
+        );
+
+    if ($ignore_list_changed)
+    {
+      $this->update_conf($this->build_ignore_list);
+    }
+  }
+
+  /**
+   * Display anomalies list
+   *
+   * @param void
+   * @return void
+   */
+  function display()
+  {
+    global $template;
+
+    $check_automatic_correction = false;
+    $submit_automatic_correction = false;
+    $submit_ignore = false;
+
+    if (isset($this->retrieve_list) and count($this->retrieve_list) > 0)
+    {
+      $template->set_filenames(array('check_integrity' => 'check_integrity.tpl'));
+
+      foreach ($this->retrieve_list as $i => $c13y)
+      {
+        $can_select = false;
+        $c13y_display = array(
+           'id' => $c13y['id'],
+           'anomaly' => $c13y['anomaly'],
+           'show_ignore_msg' => false,
+           'show_correction_success_fct' => false,
+           'correction_error_fct' => '',
+           'show_correction_fct' => false,
+           'correction_error_fct' => '',
+           'show_correction_bad_fct' => false,
+           'correction_msg' => ''
+          );
+
+        if (isset($c13y['ignored']))
+        {
+          if ($c13y['ignored'])
+          {
+            $c13y_display['show_ignore_msg'] = true;
+          }
+          else
+          {
+            die('$c13y[\'ignored\'] cannot be false');
+          }
+        }
+        else
+        {
+          if (!empty($c13y['correction_fct']))
+          {
+            if (isset($c13y['corrected']))
+            {
+              if ($c13y['corrected'])
+              {
+                $c13y_display['show_correction_success_fct'] = true;
+              }
+              else
+              {
+                $c13y_display['correction_error_fct'] = $this->get_htlm_links_more_info();
+              }
+            }
+            else if ($c13y['is_callable'])
+            {
+              $c13y_display['show_correction_fct'] = true;
+              $template->append('c13y_do_check', $c13y['id']);
+              $submit_automatic_correction = true;
+              $can_select = true;
+            }
+            else
+            {
+              $c13y_display['show_correction_bad_fct'] = true;
+              $can_select = true;
+            }
+          }
+          else
+          {
+            $can_select = true;
+          }
+
+          if (!empty($c13y['correction_msg']) and !isset($c13y['corrected']))
+          {
+            $c13y_display['correction_msg'] = $c13y['correction_msg'];
+          }
+        }
+
+        $c13y_display['can_select'] = $can_select;
+        if ($can_select)
+        {
+          $submit_ignore = true;
+        }
+
+        $template->append('c13y_list', $c13y_display);
+      }
+
+      $template->assign('c13y_show_submit_automatic_correction', $submit_automatic_correction);
+      $template->assign('c13y_show_submit_ignore', $submit_ignore);
+
+      $template->concat('ADMIN_CONTENT', $template->parse('check_integrity', true));
+
+    }
+  }
+
+  /**
+   * Add anomaly data
+   *
+   * @param anomaly arguments
+   * @return void
+   */
+  function add_anomaly($anomaly, $correction_fct = null, $correction_fct_args = null, $correction_msg = null)
+  {
+    $id = md5($anomaly.$correction_fct.serialize($correction_fct_args).$correction_msg);
+
+    if (in_array($id, $this->ignore_list))
+    {
+      $this->build_ignore_list[] = $id;
+    }
+    else
+    {
+      $this->retrieve_list[] =
+        array(
+          'id' => $id,
+          'anomaly' => $anomaly,
+          'correction_fct' => $correction_fct,
+          'correction_fct_args' => $correction_fct_args,
+          'correction_msg' => $correction_msg,
+          'is_callable' => is_callable($correction_fct));
+    }
+  }
+
+  /**
+   * Update table config
+   *
+   * @param ignore list array
+   * @return void
+   */
+  function update_conf($conf_ignore_list = array())
+  {
+    $conf_c13y_ignore =  array();
+    $conf_c13y_ignore['version'] = PHPWG_VERSION;
+    $conf_c13y_ignore['list'] = $conf_ignore_list;
+    $query = 'update '.CONFIG_TABLE.' set value =\''.serialize($conf_c13y_ignore).'\'where param = \'c13y_ignore\';';
+    pwg_query($query);
+  }
+
+  /**
+   * Apply maintenance
+   *
+   * @param void
+   * @return void
+   */
+  function maintenance()
+  {
+    $this->update_conf();
+  }
+
+  /**
+   * Returns links more informations
+   *
+   * @param void
+   * @return html links
+   */
+  function get_htlm_links_more_info()
+  {
+    $pwg_links = pwg_URL();
+    $link_fmt = '<a href="%s" onclick="window.open(this.href, \'\'); return false;">%s</a>';
+    return
+      sprintf
+      (
+        l10n('c13y_more_info'),
+        sprintf($link_fmt, $pwg_links['FORUM'], l10n('c13y_more_info_forum')),
+        sprintf($link_fmt, $pwg_links['WIKI'], l10n('c13y_more_info_wiki'))
+      );
+  }
+
+}
+
+?>
Index: /tags/2.0.2/admin/include/functions.php
===================================================================
--- /tags/2.0.2/admin/include/functions.php	(revision 3278)
+++ /tags/2.0.2/admin/include/functions.php	(revision 3278)
@@ -0,0 +1,2117 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+include(PHPWG_ROOT_PATH.'admin/include/functions_metadata.php');
+
+
+// The function delete_site deletes a site and call the function
+// delete_categories for each primary category of the site
+function delete_site( $id )
+{
+  // destruction of the categories of the site
+  $query = '
+SELECT id
+  FROM '.CATEGORIES_TABLE.'
+  WHERE site_id = '.$id.'
+;';
+  $result = pwg_query($query);
+  $category_ids = array();
+  while ($row = mysql_fetch_array($result))
+  {
+    array_push($category_ids, $row['id']);
+  }
+  delete_categories($category_ids);
+
+  // destruction of the site
+  $query = '
+DELETE FROM '.SITES_TABLE.'
+  WHERE id = '.$id.'
+;';
+  pwg_query($query);
+}
+
+
+// The function delete_categories deletes the categories identified by the
+// (numeric) key of the array $ids. It also deletes (in the database) :
+//    - all the elements of the category (delete_elements, see further)
+//    - all the links between elements and this category
+//    - all the restrictions linked to the category
+// The function works recursively.
+function delete_categories($ids)
+{
+  if (count($ids) == 0)
+  {
+    return;
+  }
+
+  // add sub-category ids to the given ids : if a category is deleted, all
+  // sub-categories must be so
+  $ids = get_subcat_ids($ids);
+
+  // destruction of all the related elements
+  $query = '
+SELECT id
+  FROM '.IMAGES_TABLE.'
+  WHERE storage_category_id IN (
+'.wordwrap(implode(', ', $ids), 80, "\n").')
+;';
+  $result = pwg_query($query);
+  $element_ids = array();
+  while ($row = mysql_fetch_array($result))
+  {
+    array_push($element_ids, $row['id']);
+  }
+  delete_elements($element_ids);
+
+  // destruction of the links between images and this category
+  $query = '
+DELETE FROM '.IMAGE_CATEGORY_TABLE.'
+  WHERE category_id IN (
+'.wordwrap(implode(', ', $ids), 80, "\n").')
+;';
+  pwg_query($query);
+
+  // destruction of the access linked to the category
+  $query = '
+DELETE FROM '.USER_ACCESS_TABLE.'
+  WHERE cat_id IN (
+'.wordwrap(implode(', ', $ids), 80, "\n").')
+;';
+  pwg_query($query);
+
+  $query = '
+DELETE FROM '.GROUP_ACCESS_TABLE.'
+  WHERE cat_id IN (
+'.wordwrap(implode(', ', $ids), 80, "\n").')
+;';
+  pwg_query($query);
+
+  // destruction of the category
+  $query = '
+DELETE FROM '.CATEGORIES_TABLE.'
+  WHERE id IN (
+'.wordwrap(implode(', ', $ids), 80, "\n").')
+;';
+  pwg_query($query);
+
+  $query='
+DELETE FROM '.OLD_PERMALINKS_TABLE.'
+  WHERE cat_id IN ('.implode(',',$ids).')';
+  pwg_query($query);
+
+  $query='
+DELETE FROM '.USER_CACHE_CATEGORIES_TABLE.'
+  WHERE cat_id IN ('.implode(',',$ids).')';
+  pwg_query($query);
+
+  trigger_action('delete_categories', $ids);
+}
+
+// The function delete_elements deletes the elements identified by the
+// (numeric) values of the array $ids. It also deletes (in the database) :
+//    - all the comments related to elements
+//    - all the links between categories and elements
+//    - all the favorites associated to elements
+function delete_elements($ids, $physical_deletion=false)
+{
+  if (count($ids) == 0)
+  {
+    return;
+  }
+  trigger_action('begin_delete_elements', $ids);
+
+  if ($physical_deletion)
+  {
+    include_once(PHPWG_ROOT_PATH.'include/functions_picture.inc.php');
+
+    // we can currently delete physically only photo with no
+    // storage_category_id (added via pLoader)
+    //
+    // we assume that the element is a photo, with no representative
+    $query = '
+SELECT
+    id,
+    path,
+    tn_ext,
+    has_high
+  FROM '.IMAGES_TABLE.'
+  WHERE id IN ('.implode(',', $ids).')
+    AND storage_category_id IS NULL
+;';
+    $result = pwg_query($query);
+    while ($row = mysql_fetch_assoc($result))
+    {
+      $file_path = $row['path'];
+      $thumbnail_path = get_thumbnail_path($row);
+      $high_path = null;
+      if (isset($row['has_high']) and get_boolean($row['has_high']))
+      {
+        $high_path = get_high_path($row);
+      }
+
+      foreach (array($file_path, $thumbnail_path, $high_path) as $path)
+      {
+        if (isset($path) and !unlink($path))
+        {
+          die('"'.$path.'" cannot be removed');
+        }
+      }
+    }
+  }
+
+  // destruction of the comments on the image
+  $query = '
+DELETE FROM '.COMMENTS_TABLE.'
+  WHERE image_id IN (
+'.wordwrap(implode(', ', $ids), 80, "\n").')
+;';
+  pwg_query($query);
+
+  // destruction of the links between images and this category
+  $query = '
+DELETE FROM '.IMAGE_CATEGORY_TABLE.'
+  WHERE image_id IN (
+'.wordwrap(implode(', ', $ids), 80, "\n").')
+;';
+  pwg_query($query);
+
+  // destruction of the links between images and tags
+  $query = '
+DELETE FROM '.IMAGE_TAG_TABLE.'
+  WHERE image_id IN (
+'.wordwrap(implode(', ', $ids), 80, "\n").')
+;';
+  pwg_query($query);
+
+  // destruction of the favorites associated with the picture
+  $query = '
+DELETE FROM '.FAVORITES_TABLE.'
+  WHERE image_id IN (
+'.wordwrap(implode(', ', $ids), 80, "\n").')
+;';
+  pwg_query($query);
+
+  // destruction of the rates associated to this element
+  $query = '
+DELETE FROM '.RATE_TABLE.'
+  WHERE element_id IN (
+'.wordwrap(implode(', ', $ids), 80, "\n").')
+;';
+  pwg_query($query);
+
+  // destruction of the rates associated to this element
+  $query = '
+DELETE FROM '.CADDIE_TABLE.'
+  WHERE element_id IN (
+'.wordwrap(implode(', ', $ids), 80, "\n").')
+;';
+  pwg_query($query);
+
+  // destruction of the image
+  $query = '
+DELETE FROM '.IMAGES_TABLE.'
+  WHERE id IN (
+'.wordwrap(implode(', ', $ids), 80, "\n").')
+;';
+  pwg_query($query);
+
+  trigger_action('delete_elements', $ids);
+}
+
+// The delete_user function delete a user identified by the $user_id
+// It also deletes :
+//     - all the access linked to this user
+//     - all the links to any group
+//     - all the favorites linked to this user
+//     - calculated permissions linked to the user
+//     - all datas about notifications for the user
+function delete_user($user_id)
+{
+  global $conf;
+  $tables = array(
+    // destruction of the access linked to the user
+    USER_ACCESS_TABLE,
+    // destruction of data notification by mail for this user
+    USER_MAIL_NOTIFICATION_TABLE,
+    // destruction of data RSS notification for this user
+    USER_FEED_TABLE,
+    // deletion of calculated permissions linked to the user
+    USER_CACHE_TABLE,
+    // deletion of computed cache data linked to the user
+    USER_CACHE_CATEGORIES_TABLE,
+    // destruction of the group links for this user
+    USER_GROUP_TABLE,
+    // destruction of the favorites associated with the user
+    FAVORITES_TABLE,
+    // destruction of the caddie associated with the user
+    CADDIE_TABLE,
+    // deletion of piwigo specific informations
+    USER_INFOS_TABLE,
+    );
+
+  foreach ($tables as $table)
+  {
+    $query = '
+DELETE FROM '.$table.'
+  WHERE user_id = '.$user_id.'
+;';
+    pwg_query($query);
+  }
+
+  // destruction of the user
+  $query = '
+DELETE FROM '.SESSIONS_TABLE.'
+  WHERE data LIKE "pwg_uid|i:'.(int)$user_id.';%"
+;';
+  pwg_query($query);
+
+  // destruction of the user
+  $query = '
+DELETE FROM '.USERS_TABLE.'
+  WHERE '.$conf['user_fields']['id'].' = '.$user_id.'
+;';
+  pwg_query($query);
+
+  trigger_action('delete_user', $user_id);
+}
+
+/**
+ * Verifies that the representative picture really exists in the db and
+ * picks up a random represantive if possible and based on config.
+ *
+ * @param mixed category id
+ * @returns void
+ */
+function update_category($ids = 'all')
+{
+  global $conf;
+
+  if ($ids=='all')
+  {
+    $where_cats = '1=1';
+  }
+  elseif ( !is_array($ids) )
+  {
+    $where_cats = '%s='.$ids;
+  }
+  else
+  {
+    if (count($ids) == 0)
+    {
+      return false;
+    }
+    $where_cats = '%s IN('.wordwrap(implode(', ', $ids), 120, "\n").')';
+  }
+
+  // find all categories where the setted representative is not possible :
+  // the picture does not exist
+  $query = '
+SELECT DISTINCT c.id
+  FROM '.CATEGORIES_TABLE.' AS c LEFT JOIN '.IMAGES_TABLE.' AS i
+    ON c.representative_picture_id = i.id
+  WHERE representative_picture_id IS NOT NULL
+    AND '.sprintf($where_cats, 'c.id').'
+    AND i.id IS NULL
+;';
+  $wrong_representant = array_from_query($query, 'id');
+
+  if (count($wrong_representant) > 0)
+  {
+    $query = '
+UPDATE '.CATEGORIES_TABLE.'
+  SET representative_picture_id = NULL
+  WHERE id IN ('.wordwrap(implode(', ', $wrong_representant), 120, "\n").')
+;';
+    pwg_query($query);
+  }
+
+  if (!$conf['allow_random_representative'])
+  {
+    // If the random representant is not allowed, we need to find
+    // categories with elements and with no representant. Those categories
+    // must be added to the list of categories to set to a random
+    // representant.
+    $query = '
+SELECT DISTINCT id
+  FROM '.CATEGORIES_TABLE.' INNER JOIN '.IMAGE_CATEGORY_TABLE.'
+    ON id = category_id
+  WHERE representative_picture_id IS NULL
+    AND '.sprintf($where_cats, 'category_id').'
+;';
+    $to_rand = array_from_query($query, 'id');
+    if (count($to_rand) > 0)
+    {
+      set_random_representant($to_rand);
+    }
+  }
+}
+
+/**
+ * returns an array containing sub-directories which can be a category,
+ * recursive by default
+ *
+ * directories nammed "thumbnail", "pwg_high" or "pwg_representative" are
+ * omitted
+ *
+ * @param string $basedir
+ * @return array
+ */
+function get_fs_directories($path, $recursive = true)
+{
+  $dirs = array();
+
+  if (is_dir($path))
+  {
+    if ($contents = opendir($path))
+    {
+      while (($node = readdir($contents)) !== false)
+      {
+        if (is_dir($path.'/'.$node)
+            and $node != '.'
+            and $node != '..'
+            and $node != '.svn'
+            and $node != 'thumbnail'
+            and $node != 'pwg_high'
+            and $node != 'pwg_representative')
+        {
+          array_push($dirs, $path.'/'.$node);
+          if ($recursive)
+          {
+            $dirs = array_merge($dirs, get_fs_directories($path.'/'.$node));
+          }
+        }
+      }
+      closedir($contents);
+    }
+  }
+
+  return $dirs;
+}
+
+/**
+ * inserts multiple lines in a table
+ *
+ * @param string table_name
+ * @param array dbfields
+ * @param array inserts
+ * @return void
+ */
+function mass_inserts($table_name, $dbfields, $datas)
+{
+  if (count($datas) != 0)
+  {
+    $first = true;
+
+    $query = 'SHOW VARIABLES LIKE \'max_allowed_packet\'';
+    list(, $packet_size) = mysql_fetch_row(pwg_query($query));
+    $packet_size = $packet_size - 2000; // The last list of values MUST not exceed 2000 character*/
+    $query = '';
+
+    foreach ($datas as $insert)
+    {
+      if (strlen($query) >= $packet_size)
+      {
+        pwg_query($query);
+        $first = true;
+      }
+
+      if ($first)
+      {
+        $query = '
+INSERT INTO '.$table_name.'
+  ('.implode(',', $dbfields).')
+  VALUES';
+        $first = false;
+      }
+      else
+      {
+        $query .= '
+  , ';
+      }
+
+      $query .= '(';
+      foreach ($dbfields as $field_id => $dbfield)
+      {
+        if ($field_id > 0)
+        {
+          $query .= ',';
+        }
+
+        if (!isset($insert[$dbfield]) or $insert[$dbfield] === '')
+        {
+          $query .= 'NULL';
+        }
+        else
+        {
+          $query .= "'".$insert[$dbfield]."'";
+        }
+      }
+      $query .= ')';
+    }
+    pwg_query($query);
+  }
+}
+
+define('MASS_UPDATES_SKIP_EMPTY', 1);
+/**
+ * updates multiple lines in a table
+ *
+ * @param string table_name
+ * @param array dbfields
+ * @param array datas
+ * @param int flags - if MASS_UPDATES_SKIP_EMPTY - empty values do not overwrite existing ones
+ * @return void
+ */
+function mass_updates($tablename, $dbfields, $datas, $flags=0)
+{
+  if (count($datas) == 0)
+    return;
+  // depending on the MySQL version, we use the multi table update or N update queries
+  if (count($datas) < 10 or version_compare(mysql_get_server_info(), '4.0.4') < 0)
+  { // MySQL is prior to version 4.0.4, multi table update feature is not available
+    foreach ($datas as $data)
+    {
+      $query = '
+UPDATE '.$tablename.'
+  SET ';
+      $is_first = true;
+      foreach ($dbfields['update'] as $key)
+      {
+        $separator = $is_first ? '' : ",\n    ";
+
+        if (isset($data[$key]) and $data[$key] != '')
+        {
+          $query.= $separator.$key.' = \''.$data[$key].'\'';
+        }
+        else
+        {
+          if ($flags & MASS_UPDATES_SKIP_EMPTY )
+            continue; // next field
+          $query.= "$separator$key = NULL";
+        }
+        $is_first = false;
+      }
+      if (!$is_first)
+      {// only if one field at least updated
+        $query.= '
+  WHERE ';
+        $is_first = true;
+        foreach ($dbfields['primary'] as $key)
+        {
+          if (!$is_first)
+          {
+            $query.= ' AND ';
+          }
+          if ( isset($data[$key]) )
+          {
+            $query.= $key.' = \''.$data[$key].'\'';
+          }
+          else
+          {
+            $query.= $key.' IS NULL';
+          }
+          $is_first = false;
+        }
+        pwg_query($query);
+      }
+    } // foreach update
+  } // if mysql_ver or count<X
+  else
+  {
+    // creation of the temporary table
+    $query = '
+SHOW FULL COLUMNS FROM '.$tablename;
+    $result = pwg_query($query);
+    $columns = array();
+    $all_fields = array_merge($dbfields['primary'], $dbfields['update']);
+    while ($row = mysql_fetch_array($result))
+    {
+      if (in_array($row['Field'], $all_fields))
+      {
+        $column = $row['Field'];
+        $column.= ' '.$row['Type'];
+
+        $nullable = true;
+        if (!isset($row['Null']) or $row['Null'] == '' or $row['Null']=='NO')
+        {
+          $column.= ' NOT NULL';
+          $nullable = false;
+        }
+        if (isset($row['Default']))
+        {
+          $column.= " default '".$row['Default']."'";
+        }
+        elseif ($nullable)
+        {
+          $column.= " default NULL";
+        }
+        if (isset($row['Collation']) and $row['Collation'] != 'NULL')
+        {
+          $column.= " collate '".$row['Collation']."'";
+        }
+        array_push($columns, $column);
+      }
+    }
+
+    $temporary_tablename = $tablename.'_'.micro_seconds();
+
+    $query = '
+CREATE TABLE '.$temporary_tablename.'
+(
+  '.implode(",\n  ", $columns).',
+  UNIQUE KEY the_key ('.implode(',', $dbfields['primary']).')
+)';
+
+    pwg_query($query);
+    mass_inserts($temporary_tablename, $all_fields, $datas);
+    if ( $flags & MASS_UPDATES_SKIP_EMPTY )
+      $func_set = create_function('$s', 'return "t1.$s = IFNULL(t2.$s, t1.$s)";');
+    else
+      $func_set = create_function('$s', 'return "t1.$s = t2.$s";');
+
+    // update of images table by joining with temporary table
+    $query = '
+UPDATE '.$tablename.' AS t1, '.$temporary_tablename.' AS t2
+  SET '.
+      implode(
+        "\n    , ",
+        array_map($func_set,$dbfields['update'])
+        ).'
+  WHERE '.
+      implode(
+        "\n    AND ",
+        array_map(
+          create_function('$s', 'return "t1.$s = t2.$s";'),
+          $dbfields['primary']
+          )
+        );
+    pwg_query($query);
+    $query = '
+DROP TABLE '.$temporary_tablename;
+    pwg_query($query);
+  }
+}
+
+/**
+ * order categories (update categories.rank and global_rank database fields)
+ * so that rank field are consecutive integers starting at 1 for each child
+ * @return void
+ */
+function update_global_rank()
+{
+  $query = '
+SELECT id, if(id_uppercat is null,\'\',id_uppercat) AS id_uppercat, uppercats, rank, global_rank
+  FROM '.CATEGORIES_TABLE.'
+  ORDER BY id_uppercat,rank,name';
+
+  $cat_map = array();
+
+  $current_rank = 0;
+  $current_uppercat = '';
+
+  $result = pwg_query($query);
+  while ($row = mysql_fetch_array($result))
+  {
+    if ($row['id_uppercat'] != $current_uppercat)
+    {
+      $current_rank = 0;
+      $current_uppercat = $row['id_uppercat'];
+    }
+    ++$current_rank;
+    $cat =
+      array(
+        'rank' =>        $current_rank,
+        'rank_changed' =>$current_rank!=$row['rank'],
+        'global_rank' => $row['global_rank'],
+        'uppercats' =>   $row['uppercats'],
+        );
+    $cat_map[ $row['id'] ] = $cat;
+  }
+
+  $datas = array();
+
+  foreach( $cat_map as $id=>$cat )
+  {
+    $new_global_rank = preg_replace(
+          '/(\d+)/e',
+          "\$cat_map['$1']['rank']",
+          str_replace(',', '.', $cat['uppercats'] )
+          );
+    if ( $cat['rank_changed']
+      or $new_global_rank!=$cat['global_rank']
+      )
+    {
+      $datas[] = array(
+          'id' => $id,
+          'rank' => $cat['rank'],
+          'global_rank' => $new_global_rank,
+        );
+    }
+  }
+
+  mass_updates(
+    CATEGORIES_TABLE,
+    array(
+      'primary' => array('id'),
+      'update'  => array('rank', 'global_rank')
+      ),
+    $datas
+    );
+  return count($datas);
+}
+
+/**
+ * change the visible property on a set of categories
+ *
+ * @param array categories
+ * @param string value
+ * @return void
+ */
+function set_cat_visible($categories, $value)
+{
+  if (!in_array($value, array('true', 'false')))
+  {
+    trigger_error("set_cat_visible invalid param $value", E_USER_WARNING);
+    return false;
+  }
+
+  // unlocking a category => all its parent categories become unlocked
+  if ($value == 'true')
+  {
+    $uppercats = get_uppercat_ids($categories);
+    $query = '
+UPDATE '.CATEGORIES_TABLE.'
+  SET visible = \'true\'
+  WHERE id IN ('.implode(',', $uppercats).')';
+    pwg_query($query);
+  }
+  // locking a category   => all its child categories become locked
+  if ($value == 'false')
+  {
+    $subcats = get_subcat_ids($categories);
+    $query = '
+UPDATE '.CATEGORIES_TABLE.'
+  SET visible = \'false\'
+  WHERE id IN ('.implode(',', $subcats).')';
+    pwg_query($query);
+  }
+}
+
+/**
+ * change the status property on a set of categories : private or public
+ *
+ * @param array categories
+ * @param string value
+ * @return void
+ */
+function set_cat_status($categories, $value)
+{
+  if (!in_array($value, array('public', 'private')))
+  {
+    trigger_error("set_cat_status invalid param $value", E_USER_WARNING);
+    return false;
+  }
+
+  // make public a category => all its parent categories become public
+  if ($value == 'public')
+  {
+    $uppercats = get_uppercat_ids($categories);
+    $query = '
+UPDATE '.CATEGORIES_TABLE.'
+  SET status = \'public\'
+  WHERE id IN ('.implode(',', $uppercats).')
+;';
+    pwg_query($query);
+  }
+  // make a category private => all its child categories become private
+  if ($value == 'private')
+  {
+    $subcats = get_subcat_ids($categories);
+    $query = '
+UPDATE '.CATEGORIES_TABLE.'
+  SET status = \'private\'
+  WHERE id IN ('.implode(',', $subcats).')';
+    pwg_query($query);
+  }
+}
+
+/**
+ * returns all uppercats category ids of the given category ids
+ *
+ * @param array cat_ids
+ * @return array
+ */
+function get_uppercat_ids($cat_ids)
+{
+  if (!is_array($cat_ids) or count($cat_ids) < 1)
+  {
+    return array();
+  }
+
+  $uppercats = array();
+
+  $query = '
+SELECT uppercats
+  FROM '.CATEGORIES_TABLE.'
+  WHERE id IN ('.implode(',', $cat_ids).')
+;';
+  $result = pwg_query($query);
+  while ($row = mysql_fetch_array($result))
+  {
+    $uppercats = array_merge($uppercats,
+                             explode(',', $row['uppercats']));
+  }
+  $uppercats = array_unique($uppercats);
+
+  return $uppercats;
+}
+
+/**
+ * set a new random representant to the categories
+ *
+ * @param array categories
+ */
+function set_random_representant($categories)
+{
+  $datas = array();
+  foreach ($categories as $category_id)
+  {
+    $query = '
+SELECT image_id
+  FROM '.IMAGE_CATEGORY_TABLE.'
+  WHERE category_id = '.$category_id.'
+  ORDER BY RAND()
+  LIMIT 0,1
+;';
+    list($representative) = mysql_fetch_array(pwg_query($query));
+
+    array_push(
+      $datas,
+      array(
+        'id' => $category_id,
+        'representative_picture_id' => $representative,
+        )
+      );
+  }
+
+  mass_updates(
+    CATEGORIES_TABLE,
+    array(
+      'primary' => array('id'),
+      'update' => array('representative_picture_id')
+      ),
+    $datas
+    );
+}
+
+/**
+ * returns the fulldir for each given category id
+ *
+ * @param array cat_ids
+ * @return array
+ */
+function get_fulldirs($cat_ids)
+{
+  if (count($cat_ids) == 0)
+  {
+    return array();
+  }
+
+  // caching directories of existing categories
+  $query = '
+SELECT id, dir
+  FROM '.CATEGORIES_TABLE.'
+  WHERE dir IS NOT NULL
+;';
+  $cat_dirs = simple_hash_from_query($query, 'id', 'dir');
+
+  // caching galleries_url
+  $query = '
+SELECT id, galleries_url
+  FROM '.SITES_TABLE.'
+;';
+  $galleries_url = simple_hash_from_query($query, 'id', 'galleries_url');
+
+  // categories : id, site_id, uppercats
+  $categories = array();
+
+  $query = '
+SELECT id, uppercats, site_id
+  FROM '.CATEGORIES_TABLE.'
+  WHERE dir IS NOT NULL
+    AND id IN (
+'.wordwrap(implode(', ', $cat_ids), 80, "\n").')
+;';
+  $result = pwg_query($query);
+  while ($row = mysql_fetch_array($result))
+  {
+    array_push($categories, $row);
+  }
+
+  // filling $cat_fulldirs
+  $cat_fulldirs = array();
+  foreach ($categories as $category)
+  {
+    $uppercats = str_replace(',', '/', $category['uppercats']);
+    $cat_fulldirs[$category['id']] = $galleries_url[$category['site_id']];
+    $cat_fulldirs[$category['id']].= preg_replace('/(\d+)/e',
+                                                  "\$cat_dirs['$1']",
+                                                  $uppercats);
+  }
+
+  return $cat_fulldirs;
+}
+
+/**
+ * returns an array with all file system files according to
+ * $conf['file_ext']
+ *
+ * @param string $path
+ * @param bool recursive
+ * @return array
+ */
+function get_fs($path, $recursive = true)
+{
+  global $conf;
+
+  // because isset is faster than in_array...
+  if (!isset($conf['flip_picture_ext']))
+  {
+    $conf['flip_picture_ext'] = array_flip($conf['picture_ext']);
+  }
+  if (!isset($conf['flip_file_ext']))
+  {
+    $conf['flip_file_ext'] = array_flip($conf['file_ext']);
+  }
+
+  $fs['elements'] = array();
+  $fs['thumbnails'] = array();
+  $fs['representatives'] = array();
+  $subdirs = array();
+
+  if (is_dir($path))
+  {
+    if ($contents = opendir($path))
+    {
+      while (($node = readdir($contents)) !== false)
+      {
+        if (is_file($path.'/'.$node))
+        {
+          $extension = get_extension($node);
+
+//          if (in_array($extension, $conf['picture_ext']))
+          if (isset($conf['flip_picture_ext'][$extension]))
+          {
+            if (basename($path) == 'thumbnail')
+            {
+              array_push($fs['thumbnails'], $path.'/'.$node);
+            }
+            else if (basename($path) == 'pwg_representative')
+            {
+              array_push($fs['representatives'], $path.'/'.$node);
+            }
+            else
+            {
+              array_push($fs['elements'], $path.'/'.$node);
+            }
+          }
+//          else if (in_array($extension, $conf['file_ext']))
+          else if (isset($conf['flip_file_ext'][$extension]))
+          {
+            array_push($fs['elements'], $path.'/'.$node);
+          }
+        }
+        else if (is_dir($path.'/'.$node)
+                 and $node != '.'
+                 and $node != '..'
+                 and $node != 'pwg_high'
+                 and $recursive)
+        {
+          array_push($subdirs, $node);
+        }
+      }
+    }
+    closedir($contents);
+
+    foreach ($subdirs as $subdir)
+    {
+      $tmp_fs = get_fs($path.'/'.$subdir);
+
+      $fs['elements']        = array_merge($fs['elements'],
+                                           $tmp_fs['elements']);
+
+      $fs['thumbnails']      = array_merge($fs['thumbnails'],
+                                           $tmp_fs['thumbnails']);
+
+      $fs['representatives'] = array_merge($fs['representatives'],
+                                           $tmp_fs['representatives']);
+    }
+  }
+  return $fs;
+}
+
+/**
+ * stupidly returns the current microsecond since Unix epoch
+ */
+function micro_seconds()
+{
+  $t1 = explode(' ', microtime());
+  $t2 = explode('.', $t1[0]);
+  $t2 = $t1[1].substr($t2[1], 0, 6);
+  return $t2;
+}
+
+/**
+ * synchronize base users list and related users list
+ *
+ * compares and synchronizes base users table (USERS_TABLE) with its child
+ * tables (USER_INFOS_TABLE, USER_ACCESS, USER_CACHE, USER_GROUP) : each
+ * base user must be present in child tables, users in child tables not
+ * present in base table must be deleted.
+ *
+ * @return void
+ */
+function sync_users()
+{
+  global $conf;
+
+  $query = '
+SELECT '.$conf['user_fields']['id'].' AS id
+  FROM '.USERS_TABLE.'
+;';
+  $base_users = array_from_query($query, 'id');
+
+  $query = '
+SELECT user_id
+  FROM '.USER_INFOS_TABLE.'
+;';
+  $infos_users = array_from_query($query, 'user_id');
+
+  // users present in $base_users and not in $infos_users must be added
+  $to_create = array_diff($base_users, $infos_users);
+
+  if (count($to_create) > 0)
+  {
+    create_user_infos($to_create);
+  }
+
+  // users present in user related tables must be present in the base user
+  // table
+  $tables = array(
+    USER_MAIL_NOTIFICATION_TABLE,
+    USER_FEED_TABLE,
+    USER_INFOS_TABLE,
+    USER_ACCESS_TABLE,
+    USER_CACHE_TABLE,
+    USER_CACHE_CATEGORIES_TABLE,
+    USER_GROUP_TABLE
+    );
+
+  foreach ($tables as $table)
+  {
+    $query = '
+SELECT DISTINCT user_id
+  FROM '.$table.'
+;';
+    $to_delete = array_diff(
+      array_from_query($query, 'user_id'),
+      $base_users
+      );
+
+    if (count($to_delete) > 0)
+    {
+      $query = '
+DELETE
+  FROM '.$table.'
+  WHERE user_id in ('.implode(',', $to_delete).')
+;';
+      pwg_query($query);
+    }
+  }
+}
+
+/**
+ * updates categories.uppercats field based on categories.id +
+ * categories.id_uppercat
+ *
+ * @return void
+ */
+function update_uppercats()
+{
+  $query = '
+SELECT id, id_uppercat, uppercats
+  FROM '.CATEGORIES_TABLE.'
+;';
+  $cat_map = hash_from_query($query, 'id');
+
+  $datas = array();
+  foreach ($cat_map as $id => $cat)
+  {
+    $upper_list = array();
+
+    $uppercat = $id;
+    while ($uppercat)
+    {
+      array_push($upper_list, $uppercat);
+      $uppercat = $cat_map[$uppercat]['id_uppercat'];
+    }
+
+    $new_uppercats = implode(',', array_reverse($upper_list));
+    if ($new_uppercats != $cat['uppercats'])
+    {
+      array_push(
+        $datas,
+        array(
+          'id' => $id,
+          'uppercats' => $new_uppercats
+          )
+        );
+    }
+  }
+  $fields = array('primary' => array('id'), 'update' => array('uppercats'));
+  mass_updates(CATEGORIES_TABLE, $fields, $datas);
+}
+
+/**
+ * update images.path field
+ *
+ * @return void
+ */
+function update_path()
+{
+  $query = '
+SELECT DISTINCT(storage_category_id)
+  FROM '.IMAGES_TABLE.'
+  WHERE storage_category_id IS NOT NULL
+;';
+  $cat_ids = array_from_query($query, 'storage_category_id');
+  $fulldirs = get_fulldirs($cat_ids);
+
+  foreach ($cat_ids as $cat_id)
+  {
+    $query = '
+UPDATE '.IMAGES_TABLE.'
+  SET path = CONCAT(\''.$fulldirs[$cat_id].'\',\'/\',file)
+  WHERE storage_category_id = '.$cat_id.'
+;';
+    pwg_query($query);
+  }
+}
+
+/**
+ * update images.average_rate field
+ * param int $element_id optional, otherwise applies to all
+ * @return void
+ */
+function update_average_rate( $element_id=-1 )
+{
+  $query = '
+SELECT element_id,
+       ROUND(AVG(rate),2) AS average_rate
+  FROM '.RATE_TABLE;
+  if ( $element_id != -1 )
+  {
+    $query .= ' WHERE element_id=' . $element_id;
+  }
+  $query .= ' GROUP BY element_id;';
+
+  $result = pwg_query($query);
+
+  $datas = array();
+
+  while ($row = mysql_fetch_array($result))
+  {
+    array_push(
+      $datas,
+      array(
+        'id' => $row['element_id'],
+        'average_rate' => $row['average_rate']
+        )
+      );
+  }
+
+  mass_updates(
+    IMAGES_TABLE,
+    array(
+      'primary' => array('id'),
+      'update' => array('average_rate')
+      ),
+    $datas
+    );
+
+  $query='
+SELECT id FROM '.IMAGES_TABLE .'
+  LEFT JOIN '.RATE_TABLE.' ON id=element_id
+  WHERE element_id IS NULL AND average_rate IS NOT NULL';
+  if ( $element_id != -1 )
+  {
+    $query .= ' AND id=' . $element_id;
+  }
+  $to_update = array_from_query( $query, 'id');
+
+  if ( !empty($to_update) )
+  {
+    $query='
+UPDATE '.IMAGES_TABLE .'
+  SET average_rate=NULL
+  WHERE id IN (' . implode(',',$to_update) . ')';
+    pwg_query($query);
+  }
+}
+
+/**
+ * change the parent category of the given categories. The categories are
+ * supposed virtual.
+ *
+ * @param array category identifiers
+ * @param int parent category identifier
+ * @return void
+ */
+function move_categories($category_ids, $new_parent = -1)
+{
+  global $page;
+
+  if (count($category_ids) == 0)
+  {
+    return;
+  }
+
+  $new_parent = $new_parent < 1 ? 'NULL' : $new_parent;
+
+  $categories = array();
+
+  $query = '
+SELECT id, id_uppercat, status, uppercats
+  FROM '.CATEGORIES_TABLE.'
+  WHERE id IN ('.implode(',', $category_ids).')
+;';
+  $result = pwg_query($query);
+  while ($row = mysql_fetch_array($result))
+  {
+    $categories[$row['id']] =
+      array(
+        'parent' => empty($row['id_uppercat']) ? 'NULL' : $row['id_uppercat'],
+        'status' => $row['status'],
+        'uppercats' => $row['uppercats']
+        );
+  }
+
+  // is the movement possible? The movement is impossible if you try to move
+  // a category in a sub-category or itself
+  if ('NULL' != $new_parent)
+  {
+    $query = '
+SELECT uppercats
+  FROM '.CATEGORIES_TABLE.'
+  WHERE id = '.$new_parent.'
+;';
+    list($new_parent_uppercats) = mysql_fetch_row(pwg_query($query));
+
+    foreach ($categories as $category)
+    {
+      // technically, you can't move a category with uppercats 12,125,13,14
+      // into a new parent category with uppercats 12,125,13,14,24
+      if (preg_match('/^'.$category['uppercats'].'/', $new_parent_uppercats))
+      {
+        array_push(
+          $page['errors'],
+          l10n('You cannot move a category in its own sub category')
+          );
+        return;
+      }
+    }
+  }
+
+  $tables =
+    array(
+      USER_ACCESS_TABLE => 'user_id',
+      GROUP_ACCESS_TABLE => 'group_id'
+      );
+
+  $query = '
+UPDATE '.CATEGORIES_TABLE.'
+  SET id_uppercat = '.$new_parent.'
+  WHERE id IN ('.implode(',', $category_ids).')
+;';
+  pwg_query($query);
+
+  update_uppercats();
+  update_global_rank();
+
+  // status and related permissions management
+  if ('NULL' == $new_parent)
+  {
+    $parent_status = 'public';
+  }
+  else
+  {
+    $query = '
+SELECT status
+  FROM '.CATEGORIES_TABLE.'
+  WHERE id = '.$new_parent.'
+;';
+    list($parent_status) = mysql_fetch_row(pwg_query($query));
+  }
+
+  if ('private' == $parent_status)
+  {
+    foreach ($categories as $cat_id => $category)
+    {
+      switch ($category['status'])
+      {
+        case 'public' :
+        {
+          set_cat_status(array($cat_id), 'private');
+          break;
+        }
+        case 'private' :
+        {
+          $subcats = get_subcat_ids(array($cat_id));
+
+          foreach ($tables as $table => $field)
+          {
+            $query = '
+SELECT '.$field.'
+  FROM '.$table.'
+  WHERE cat_id = '.$cat_id.'
+;';
+            $category_access = array_from_query($query, $field);
+
+            $query = '
+SELECT '.$field.'
+  FROM '.$table.'
+  WHERE cat_id = '.$new_parent.'
+;';
+            $parent_access = array_from_query($query, $field);
+
+            $to_delete = array_diff($parent_access, $category_access);
+
+            if (count($to_delete) > 0)
+            {
+              $query = '
+DELETE FROM '.$table.'
+  WHERE '.$field.' IN ('.implode(',', $to_delete).')
+    AND cat_id IN ('.implode(',', $subcats).')
+;';
+              pwg_query($query);
+            }
+          }
+          break;
+        }
+      }
+    }
+  }
+
+  array_push(
+    $page['infos'],
+    l10n_dec(
+      '%d category moved', '%d categories moved',
+      count($categories)
+      )
+    );
+}
+
+/**
+ * create a virtual category
+ *
+ * @param string category name
+ * @param int parent category id
+ * @return array with ('info' and 'id') or ('error') key
+ */
+function create_virtual_category($category_name, $parent_id=null)
+{
+  global $conf;
+
+  // is the given category name only containing blank spaces ?
+  if (preg_match('/^\s*$/', $category_name))
+  {
+    return array('error' => l10n('cat_error_name'));
+  }
+
+  $parent_id = !empty($parent_id) ? $parent_id : 'NULL';
+
+  $query = '
+SELECT MAX(rank)
+  FROM '.CATEGORIES_TABLE.'
+  WHERE id_uppercat '.(is_numeric($parent_id) ? '= '.$parent_id : 'IS NULL').'
+;';
+  list($current_rank) = mysql_fetch_array(pwg_query($query));
+
+  $insert = array(
+    'name' => $category_name,
+    'rank' => ++$current_rank,
+    'commentable' => boolean_to_string($conf['newcat_default_commentable']),
+    'uploadable' => 'false',
+    );
+
+  if ($parent_id != 'NULL')
+  {
+    $query = '
+SELECT id, uppercats, global_rank, visible, status
+  FROM '.CATEGORIES_TABLE.'
+  WHERE id = '.$parent_id.'
+;';
+    $parent = mysql_fetch_array(pwg_query($query));
+
+    $insert{'id_uppercat'} = $parent{'id'};
+    $insert{'global_rank'} = $parent{'global_rank'}.'.'.$insert{'rank'};
+
+    // at creation, must a category be visible or not ? Warning : if the
+    // parent category is invisible, the category is automatically create
+    // invisible. (invisible = locked)
+    if ('false' == $parent['visible'])
+    {
+      $insert{'visible'} = 'false';
+    }
+    else
+    {
+      $insert{'visible'} = boolean_to_string($conf['newcat_default_visible']);
+    }
+
+    // at creation, must a category be public or private ? Warning : if the
+    // parent category is private, the category is automatically create
+    // private.
+    if ('private' == $parent['status'])
+    {
+      $insert{'status'} = 'private';
+    }
+    else
+    {
+      $insert{'status'} = $conf['newcat_default_status'];
+    }
+  }
+  else
+  {
+    $insert{'visible'} = boolean_to_string($conf['newcat_default_visible']);
+    $insert{'status'} = $conf['newcat_default_status'];
+    $insert{'global_rank'} = $insert{'rank'};
+  }
+
+  // we have then to add the virtual category
+  mass_inserts(
+    CATEGORIES_TABLE,
+    array(
+      'site_id', 'name', 'id_uppercat', 'rank', 'commentable',
+      'uploadable', 'visible', 'status', 'global_rank',
+      ),
+    array($insert)
+    );
+
+  $inserted_id = mysql_insert_id();
+
+  $query = '
+UPDATE
+  '.CATEGORIES_TABLE.'
+  SET uppercats = \''.
+    (isset($parent) ? $parent{'uppercats'}.',' : '').
+    $inserted_id.
+    '\'
+  WHERE id = '.$inserted_id.'
+;';
+  pwg_query($query);
+
+  return array(
+    'info' => l10n('cat_virtual_added'),
+    'id'   => $inserted_id,
+    );
+}
+
+/**
+ * Set tags to an image. Warning: given tags are all tags associated to the
+ * image, not additionnal tags.
+ *
+ * @param array tag ids
+ * @param int image id
+ * @return void
+ */
+function set_tags($tags, $image_id)
+{
+  $query = '
+DELETE
+  FROM '.IMAGE_TAG_TABLE.'
+  WHERE image_id = '.$image_id.'
+;';
+  pwg_query($query);
+
+  if (count($tags) > 0)
+  {
+    $inserts = array();
+    foreach ($tags as $tag_id)
+    {
+      array_push(
+        $inserts,
+        array(
+          'tag_id' => $tag_id,
+          'image_id' => $image_id
+          )
+        );
+    }
+    mass_inserts(
+      IMAGE_TAG_TABLE,
+      array_keys($inserts[0]),
+      $inserts
+      );
+  }
+}
+
+/**
+ * Add new tags to a set of images.
+ *
+ * @param array tag ids
+ * @param array image ids
+ * @return void
+ */
+function add_tags($tags, $images)
+{
+  if (count($tags) == 0 or count($tags) == 0)
+  {
+    return;
+  }
+
+  // we can't insert twice the same {image_id,tag_id} so we must first
+  // delete lines we'll insert later
+  $query = '
+DELETE
+  FROM '.IMAGE_TAG_TABLE.'
+  WHERE image_id IN ('.implode(',', $images).')
+    AND tag_id IN ('.implode(',', $tags).')
+;';
+  pwg_query($query);
+
+  $inserts = array();
+  foreach ($images as $image_id)
+  {
+    foreach ($tags as $tag_id)
+    {
+      array_push(
+        $inserts,
+        array(
+          'image_id' => $image_id,
+          'tag_id' => $tag_id,
+          )
+        );
+    }
+  }
+  mass_inserts(
+    IMAGE_TAG_TABLE,
+    array_keys($inserts[0]),
+    $inserts
+    );
+}
+
+function tag_id_from_tag_name($tag_name)
+{
+  global $page;
+
+  $tag_name = trim($tag_name);
+  if (isset($page['tag_id_from_tag_name_cache'][$tag_name]))
+  {
+    return $page['tag_id_from_tag_name_cache'][$tag_name];
+  }
+
+  // does the tag already exists?
+  $query = '
+SELECT id
+  FROM '.TAGS_TABLE.'
+  WHERE name = \''.$tag_name.'\'
+;';
+  $existing_tags = array_from_query($query, 'id');
+
+  if (count($existing_tags) == 0)
+  {
+    mass_inserts(
+      TAGS_TABLE,
+      array('name', 'url_name'),
+      array(
+        array(
+          'name' => $tag_name,
+          'url_name' => str2url($tag_name),
+          )
+        )
+      );
+
+    $page['tag_id_from_tag_name_cache'][$tag_name] = mysql_insert_id();
+  }
+  else
+  {
+    $page['tag_id_from_tag_name_cache'][$tag_name] = $existing_tags[0];
+  }
+
+  return $page['tag_id_from_tag_name_cache'][$tag_name];
+}
+
+function set_tags_of($tags_of)
+{
+  if (count($tags_of) > 0)
+  {
+    $query = '
+DELETE
+  FROM '.IMAGE_TAG_TABLE.'
+  WHERE image_id IN ('.implode(',', array_keys($tags_of)).')
+;';
+    pwg_query($query);
+
+    $inserts = array();
+
+    foreach ($tags_of as $image_id => $tag_ids)
+    {
+      foreach ($tag_ids as $tag_id)
+      {
+        array_push(
+          $inserts,
+          array(
+            'image_id' => $image_id,
+            'tag_id' => $tag_id,
+            )
+          );
+      }
+    }
+
+    mass_inserts(
+      IMAGE_TAG_TABLE,
+      array_keys($inserts[0]),
+      $inserts
+      );
+  }
+}
+
+/**
+ * Do maintenance on all PWG tables
+ *
+ * @return none
+ */
+function do_maintenance_all_tables()
+{
+  global $prefixeTable, $page;
+
+  $all_tables = array();
+
+  // List all tables
+  $query = 'SHOW TABLES LIKE \''.$prefixeTable.'%\'';
+  $result = pwg_query($query);
+  while ($row = mysql_fetch_array($result))
+  {
+    array_push($all_tables, $row[0]);
+  }
+
+  // Repair all tables
+  $query = 'REPAIR TABLE '.implode(', ', $all_tables);
+  $mysql_rc = pwg_query($query);
+
+  // Re-Order all tables
+  foreach ($all_tables as $table_name)
+  {
+    $all_primary_key = array();
+
+    $query = 'DESC '.$table_name.';';
+    $result = pwg_query($query);
+    while ($row = mysql_fetch_array($result))
+    {
+      if ($row['Key'] == 'PRI')
+      {
+        array_push($all_primary_key, $row['Field']);
+      }
+    }
+
+    if (count($all_primary_key) != 0)
+    {
+      $query = 'ALTER TABLE '.$table_name.' ORDER BY '.implode(', ', $all_primary_key).';';
+      $mysql_rc = $mysql_rc && pwg_query($query);
+    }
+  }
+
+  // Optimize all tables
+  $query = 'OPTIMIZE TABLE '.implode(', ', $all_tables);
+  $mysql_rc = $mysql_rc && pwg_query($query);
+  if ($mysql_rc)
+  {
+    array_push(
+          $page['infos'],
+          l10n('Optimizations completed')
+          );
+  }
+  else
+  {
+    array_push(
+          $page['errors'],
+          l10n('Optimizations errors')
+          );
+  }
+}
+
+/**
+ * Associate a list of images to a list of categories.
+ *
+ * The function will not duplicate links
+ *
+ * @param array images
+ * @param array categories
+ * @return void
+ */
+function associate_images_to_categories($images, $categories)
+{
+  if (count($images) == 0
+      or count($categories) == 0)
+  {
+    return false;
+  }
+
+  $query = '
+DELETE
+  FROM '.IMAGE_CATEGORY_TABLE.'
+  WHERE image_id IN ('.implode(',', $images).')
+    AND category_id IN ('.implode(',', $categories).')
+;';
+  pwg_query($query);
+
+  $inserts = array();
+  foreach ($categories as $category_id)
+  {
+    foreach ($images as $image_id)
+    {
+      array_push(
+        $inserts,
+        array(
+          'image_id' => $image_id,
+          'category_id' => $category_id,
+          )
+        );
+    }
+  }
+
+  mass_inserts(
+    IMAGE_CATEGORY_TABLE,
+    array_keys($inserts[0]),
+    $inserts
+    );
+
+  update_category($categories);
+}
+
+/**
+ * Associate images associated to a list of source categories to a list of
+ * destination categories.
+ *
+ * @param array sources
+ * @param array destinations
+ * @return void
+ */
+function associate_categories_to_categories($sources, $destinations)
+{
+  if (count($sources) == 0)
+  {
+    return false;
+  }
+
+  $query = '
+SELECT image_id
+  FROM '.IMAGE_CATEGORY_TABLE.'
+  WHERE category_id IN ('.implode(',', $sources).')
+;';
+  $images = array_from_query($query, 'image_id');
+
+  associate_images_to_categories($images, $destinations);
+}
+
+/**
+ * Refer main Piwigo URLs (currently PHPWG_DOMAIN domain)
+ *
+ * @param void
+ * @return array like $conf['links']
+ */
+function pwg_URL()
+{
+  $urls = array(
+    'HOME'       => 'http://'.PHPWG_DOMAIN,
+    'WIKI'       => 'http://'.PHPWG_DOMAIN.'/doc',
+    'DEMO'       => 'http://'.PHPWG_DOMAIN.'/demo',
+    'FORUM'      => 'http://'.PHPWG_DOMAIN.'/forum',
+    'BUGS'       => 'http://'.PHPWG_DOMAIN.'/bugs',
+    'EXTENSIONS' => 'http://'.PHPWG_DOMAIN.'/ext',
+    );
+  return $urls;
+}
+
+/**
+ * Invalidates cahed data (permissions and category counts) for all users.
+ */
+function invalidate_user_cache($full = true)
+{
+  if ($full)
+  {
+    $query = '
+TRUNCATE TABLE '.USER_CACHE_CATEGORIES_TABLE.';';
+    pwg_query($query);
+    $query = '
+TRUNCATE TABLE '.USER_CACHE_TABLE.';';
+    pwg_query($query);
+  }
+  else
+  {
+    $query = '
+UPDATE '.USER_CACHE_TABLE.'
+  SET need_update = \'true\';';
+    pwg_query($query);
+  }
+  trigger_action('invalidate_user_cache', $full);
+}
+
+/**
+ * adds the caracter set to a create table sql query.
+ * all CREATE TABLE queries must call this function
+ * @param string query - the sql query
+ */
+function create_table_add_character_set($query)
+{
+  defined('DB_CHARSET') or fatal_error('create_table_add_character_set DB_CHARSET undefined');
+  if ('DB_CHARSET'!='')
+  {
+    if ( version_compare(mysql_get_server_info(), '4.1.0', '<') )
+    {
+      return $query;
+    }
+    $charset_collate = " DEFAULT CHARACTER SET ".DB_CHARSET;
+    if (DB_COLLATE!='')
+    {
+      $charset_collate .= " COLLATE ".DB_COLLATE;
+    }
+    if ( is_array($query) )
+    {
+      foreach( $query as $id=>$q)
+      {
+        $q=trim($q);
+        $q=trim($q, ';');
+        if (preg_match('/^CREATE\s+TABLE/i',$q))
+        {
+          $q.=$charset_collate;
+        }
+        $q .= ';';
+        $query[$id] = $q;
+      }
+    }
+    else
+    {
+      $query=trim($query);
+      $query=trim($query, ';');
+      if (preg_match('/^CREATE\s+TABLE/i',$query))
+      {
+        $query.=$charset_collate;
+      }
+      $query .= ';';
+    }
+  }
+  return $query;
+}
+
+/**
+ * Returns array use on template with html_options method
+ * @param Min and Max access to use
+ * @return array of user access level
+ */
+function get_user_access_level_html_options($MinLevelAccess = ACCESS_FREE, $MaxLevelAccess = ACCESS_CLOSED)
+{
+  $tpl_options = array();
+  for ($level = $MinLevelAccess; $level <= $MaxLevelAccess; $level++)
+  {
+    $tpl_options[$level] = l10n(sprintf('ACCESS_%d', $level));
+  }
+  return $tpl_options;
+}
+
+/**
+ * returns a list of templates currently available in template-extension
+ * Each .tpl file is extracted from template-extension.
+ * @return array
+ */
+function get_extents($start='')
+{
+  if ($start == '') { $start = './template-extension'; }
+  $dir = opendir($start);
+  $extents = array();
+
+  while (($file = readdir($dir)) !== false)
+  {
+    if ( $file == '.' or $file == '..' or $file == '.svn') continue;
+    $path = $start . '/' . $file;
+    if (is_dir($path))
+    {
+      $extents = array_merge($extents, get_extents($path));
+    }
+    elseif ( !is_link($path) and file_exists($path)
+            and get_extension($path) == 'tpl' )
+    {
+      $extents[] = substr($path, 21);
+    }
+  }
+  return $extents;
+}
+
+function create_tag($tag_name)
+{
+  // does the tag already exists?
+  $query = '
+SELECT id
+  FROM '.TAGS_TABLE.'
+  WHERE name = \''.$tag_name.'\'
+;';
+  $existing_tags = array_from_query($query, 'id');
+
+  if (count($existing_tags) == 0)
+  {
+    mass_inserts(
+      TAGS_TABLE,
+      array('name', 'url_name'),
+      array(
+        array(
+          'name' => $tag_name,
+          'url_name' => str2url($tag_name),
+          )
+        )
+      );
+
+    $inserted_id = mysql_insert_id();
+
+    return array(
+      'info' => sprintf(
+        l10n('Tag "%s" was added'),
+        stripslashes($tag_name)
+        ),
+      'id' => $inserted_id,
+      );
+  }
+  else
+  {
+    return array(
+      'error' => sprintf(
+        l10n('Tag "%s" already exists'),
+        stripslashes($tag_name)
+        )
+      );
+  }
+}
+
+/**
+ * Is the category accessible to the (Admin) user ?
+ *
+ * Note : if the user is not authorized to see this category, category jump
+ * will be replaced by admin cat_modify page
+ *
+ * @param int category id to verify
+ * @return bool
+ */
+function cat_admin_access($category_id)
+{
+  global $user;
+
+  // $filter['visible_categories'] and $filter['visible_images']
+  // are not used because it's not necessary (filter <> restriction)
+  if (in_array($category_id, explode(',', $user['forbidden_categories'])))
+  {
+    return false;
+  }
+  return true;
+}
+
+/**
+ * Retrieve data from external URL
+ *
+ * @param string $src: URL
+ * @param global $dest: can be a file ressource or string
+ * @return bool
+ */
+function fetchRemote($src, &$dest, $user_agent='Piwigo', $step=0)
+{
+  // Try to retrieve data from local file?
+  if (!url_is_remote($src))
+  {
+    $content = @file_get_contents($src);
+    if ($content !== false)
+    {
+      is_resource($dest) ? @fwrite($dest, $content) : $dest = $content;
+      return true;
+    }
+    else
+    {
+      return false;
+    }
+  }
+
+  // After 3 redirections, return false
+  if ($step > 3) return false;
+
+  // Initialize $dest
+  is_resource($dest) or $dest = '';
+
+  // Try curl to read remote file
+  if (function_exists('curl_init'))
+  {
+    $ch = @curl_init();
+    @curl_setopt($ch, CURLOPT_URL, $src);
+    @curl_setopt($ch, CURLOPT_HEADER, 1);
+    @curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
+    @curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+    $content = @curl_exec($ch);
+    $header_length = @curl_getinfo($ch, CURLINFO_HEADER_SIZE);
+    $status = @curl_getinfo($ch, CURLINFO_HTTP_CODE);
+    @curl_close($ch);
+    if ($content !== false and $status >= 200 and $status < 400)
+    {
+      if (preg_match('/Location:\s+?(.+)/', substr($content, 0, $header_length), $m))
+      {
+        return fetchRemote($m[1], $dest, $user_agent, $step+1);
+      }
+      $content = substr($content, $header_length);
+      is_resource($dest) ? @fwrite($dest, $content) : $dest = $content;
+      return true;
+    }
+  }
+
+  // Try file_get_contents to read remote file
+  if (ini_get('allow_url_fopen'))
+  {
+    $content = @file_get_contents($src);
+    if ($content !== false)
+    {
+      is_resource($dest) ? @fwrite($dest, $content) : $dest = $content;
+      return true;
+    }
+  }
+
+  // Try fsockopen to read remote file
+  $src = parse_url($src);
+  $host = $src['host'];
+  $path = isset($src['path']) ? $src['path'] : '/';
+  $path .= isset($src['query']) ? '?'.$src['query'] : '';
+
+  if (($s = @fsockopen($host,80,$errno,$errstr,5)) === false)
+  {
+    return false;
+  }
+
+  fwrite($s,
+    "GET ".$path." HTTP/1.0\r\n"
+    ."Host: ".$host."\r\n"
+    ."User-Agent: ".$user_agent."\r\n"
+    ."Accept: */*\r\n"
+    ."\r\n"
+  );
+
+  $i = 0;
+  $in_content = false;
+  while (!feof($s))
+  {
+    $line = fgets($s);
+
+    if (rtrim($line,"\r\n") == '' && !$in_content)
+    {
+      $in_content = true;
+      $i++;
+      continue;
+    }
+    if ($i == 0)
+    {
+      if (!preg_match('/HTTP\/(\\d\\.\\d)\\s*(\\d+)\\s*(.*)/',rtrim($line,"\r\n"), $m))
+      {
+        fclose($s);
+        return false;
+      }
+      $status = (integer) $m[2];
+      if ($status < 200 || $status >= 400)
+      {
+        fclose($s);
+        return false;
+      }
+    }
+    if (!$in_content)
+    {
+      if (preg_match('/Location:\s+?(.+)$/',rtrim($line,"\r\n"),$m))
+      {
+        fclose($s);
+        return fetchRemote(trim($m[1]),$dest,$user_agent,$step+1);
+      }
+      $i++;
+      continue;
+    }
+    is_resource($dest) ? @fwrite($dest, $line) : $dest .= $line;
+    $i++;
+  }
+  fclose($s);
+  return true;
+}
+
+
+/**
+ * returns the groupname corresponding to the given group identifier if
+ * exists
+ *
+ * @param int group_id
+ * @return mixed
+ */
+function get_groupname($group_id)
+{
+  $query = '
+SELECT name
+  FROM '.GROUPS_TABLE.'
+  WHERE id = '.intval($group_id).'
+;';
+  $result = pwg_query($query);
+  if (mysql_num_rows($result) > 0)
+  {
+    list($groupname) = mysql_fetch_row($result);
+  }
+  else
+  {
+    return false;
+  }
+
+  return $groupname;
+}
+
+/**
+ * returns the username corresponding to the given user identifier if exists
+ *
+ * @param int user_id
+ * @return mixed
+ */
+function get_username($user_id)
+{
+  global $conf;
+
+  $query = '
+SELECT '.$conf['user_fields']['username'].'
+  FROM '.USERS_TABLE.'
+  WHERE '.$conf['user_fields']['id'].' = '.intval($user_id).'
+;';
+  $result = pwg_query($query);
+  if (mysql_num_rows($result) > 0)
+  {
+    list($username) = mysql_fetch_row($result);
+  }
+  else
+  {
+    return false;
+  }
+
+  return $username;
+}
+?>
Index: /tags/2.0.2/admin/include/functions_history.inc.php
===================================================================
--- /tags/2.0.2/admin/include/functions_history.inc.php	(revision 3278)
+++ /tags/2.0.2/admin/include/functions_history.inc.php	(revision 3278)
@@ -0,0 +1,179 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+include_once(PHPWG_ROOT_PATH.'admin/include/tabsheet.class.php');
+
+function history_tabsheet()
+{
+  global $page, $link_start;
+
+  // TabSheet
+  $tabsheet = new tabsheet();
+  // TabSheet initialization
+  $tabsheet->add('stats', l10n('Statistics'), $link_start.'stats');
+  $tabsheet->add('history', l10n('Search'), $link_start.'history');
+  // TabSheet selection
+  $tabsheet->select($page['page']);
+  // Assign tabsheet to template
+  $tabsheet->assign();
+}
+
+function history_compare($a, $b)
+{
+  return strcmp($a['date'].$a['time'], $b['date'].$b['time']);
+}
+
+function get_history($data, $search, $types)
+{
+  if (isset($search['fields']['filename']))
+  {
+    $query = '
+SELECT
+    id
+  FROM '.IMAGES_TABLE.'
+  WHERE file LIKE \''.$search['fields']['filename'].'\'
+;';
+    $search['image_ids'] = array_from_query($query, 'id');
+  }
+  
+  // echo '<pre>'; print_r($search); echo '</pre>';
+  
+  $clauses = array();
+
+  if (isset($search['fields']['date-after']))
+  {
+    array_push(
+      $clauses,
+      "date >= '".$search['fields']['date-after']."'"
+      );
+  }
+
+  if (isset($search['fields']['date-before']))
+  {
+    array_push(
+      $clauses,
+      "date <= '".$search['fields']['date-before']."'"
+      );
+  }
+
+  if (isset($search['fields']['types']))
+  {
+    $local_clauses = array();
+    
+    foreach ($types as $type) {
+      if (in_array($type, $search['fields']['types'])) {
+        $clause = 'image_type ';
+        if ($type == 'none')
+        {
+          $clause.= 'IS NULL';
+        }
+        else
+        {
+          $clause.= "= '".$type."'";
+        }
+        
+        array_push($local_clauses, $clause);
+      }
+    }
+    
+    if (count($local_clauses) > 0)
+    {
+      array_push(
+        $clauses,
+        implode(' OR ', $local_clauses)
+        );
+    }
+  }
+
+  if (isset($search['fields']['user'])
+      and $search['fields']['user'] != -1)
+  {
+    array_push(
+      $clauses,
+      'user_id = '.$search['fields']['user']
+      );
+  }
+
+  if (isset($search['fields']['image_id']))
+  {
+    array_push(
+      $clauses,
+      'image_id = '.$search['fields']['image_id']
+      );
+  }
+  
+  if (isset($search['fields']['filename']))
+  {
+    if (count($search['image_ids']) == 0)
+    {
+      // a clause that is always false
+      array_push($clauses, '1 = 2 ');
+    }
+    else
+    {
+      array_push(
+        $clauses,
+        'image_id IN ('.implode(', ', $search['image_ids']).')'
+        );
+    }
+  }
+  
+  $clauses = prepend_append_array_items($clauses, '(', ')');
+
+  $where_separator =
+    implode(
+      "\n    AND ",
+      $clauses
+      );
+  
+  $query = '
+SELECT
+    date,
+    time,
+    user_id,
+    IP,
+    section,
+    category_id,
+    tag_ids,
+    image_id,
+    image_type
+  FROM '.HISTORY_TABLE.'
+  WHERE '.$where_separator.'
+;';
+
+  // LIMIT '.$page['start'].', '.$conf['nb_logs_page'].'
+
+  $result = pwg_query($query);
+
+  while ($row = mysql_fetch_assoc($result))
+  {
+    array_push($data, $row);
+  }
+
+  return $data;
+}
+
+add_event_handler('get_history', 'get_history', EVENT_HANDLER_PRIORITY_NEUTRAL, 3);
+trigger_action('functions_history_included');
+
+?>
Index: /tags/2.0.2/admin/include/functions_metadata.php
===================================================================
--- /tags/2.0.2/admin/include/functions_metadata.php	(revision 3278)
+++ /tags/2.0.2/admin/include/functions_metadata.php	(revision 3278)
@@ -0,0 +1,294 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+include_once(PHPWG_ROOT_PATH.'/include/functions_metadata.inc.php');
+
+
+function get_sync_iptc_data($file)
+{
+  global $conf;
+
+  $map = $conf['use_iptc_mapping'];
+
+  $iptc = get_iptc_data($file, $map);
+
+  foreach ($iptc as $pwg_key => $value)
+  {
+    if (in_array($pwg_key, array('date_creation', 'date_available')))
+    {
+      if (preg_match('/(\d{4})(\d{2})(\d{2})/', $value, $matches))
+      {
+        $iptc[$pwg_key] = $matches[1].'-'.$matches[2].'-'.$matches[3];
+      }
+    }
+  }
+
+  if (isset($iptc['keywords']))
+  {
+    // official keywords separator is the comma
+    $iptc['keywords'] = preg_replace('/[.;]/', ',', $iptc['keywords']);
+    $iptc['keywords'] = preg_replace('/^,+|,+$/', '', $iptc['keywords']);
+
+    $iptc['keywords'] = implode(
+      ',',
+      array_unique(
+        explode(
+          ',',
+          $iptc['keywords']
+          )
+        )
+      );
+  }
+
+  foreach ($iptc as $pwg_key => $value)
+  {
+    $iptc[$pwg_key] = addslashes($iptc[$pwg_key]);
+  }
+
+  return $iptc;
+}
+
+function get_sync_exif_data($file)
+{
+  global $conf;
+
+  $exif = get_exif_data($file, $conf['use_exif_mapping']);
+
+  foreach ($exif as $pwg_key => $value)
+  {
+    if (in_array($pwg_key, array('date_creation', 'date_available')))
+    {
+      if (preg_match('/^(\d{4}).(\d{2}).(\d{2})/', $value, $matches))
+      {
+        $exif[$pwg_key] = $matches[1].'-'.$matches[2].'-'.$matches[3];
+      }
+    }
+    $exif[$pwg_key] = addslashes($exif[$pwg_key]);
+  }
+
+  return $exif;
+}
+
+function update_metadata($files)
+{
+  global $conf;
+
+  if (!defined('CURRENT_DATE'))
+  {
+    define('CURRENT_DATE', date('Y-m-d'));
+  }
+
+  $datas = array();
+  $tags_of = array();
+  $has_high_images = array();
+
+  $image_ids = array();
+  foreach ($files as $id => $file)
+  {
+    array_push($image_ids, $id);
+  }
+
+  $query = '
+SELECT id
+  FROM '.IMAGES_TABLE.'
+  WHERE has_high = \'true\'
+    AND id IN (
+'.wordwrap(implode(', ', $image_ids), 80, "\n").'
+)
+;';
+
+  $has_high_images = array_from_query($query, 'id');
+
+  foreach ($files as $id => $file)
+  {
+    $data = array();
+    $data['id'] = $id;
+    $data['filesize'] = floor(filesize($file)/1024);
+
+    if ($image_size = @getimagesize($file))
+    {
+      $data['width'] = $image_size[0];
+      $data['height'] = $image_size[1];
+    }
+
+    if (in_array($id, $has_high_images))
+    {
+      $high_file = dirname($file).'/pwg_high/'.basename($file);
+
+      $data['high_filesize'] = floor(filesize($high_file)/1024);
+    }
+
+    if ($conf['use_exif'])
+    {
+      $exif = get_sync_exif_data($file);
+    }
+
+    if ($conf['use_iptc'])
+    {
+      $iptc = get_sync_iptc_data($file);
+      if (count($iptc) > 0)
+      {
+        foreach (array_keys($iptc) as $key)
+        {
+          if ($key == 'keywords' or $key == 'tags')
+          {
+            if (!isset($tags_of[$id]))
+            {
+              $tags_of[$id] = array();
+            }
+
+            foreach (explode(',', $iptc[$key]) as $tag_name)
+            {
+              array_push(
+                $tags_of[$id],
+                tag_id_from_tag_name($tag_name)
+                );
+            }
+          }
+        }
+      }
+    }
+
+    $data['date_metadata_update'] = CURRENT_DATE;
+
+    array_push($datas, $data);
+  }
+
+  if (count($datas) > 0)
+  {
+    $update_fields =
+      array(
+        'filesize',
+        'width',
+        'height',
+        'high_filesize',
+        'date_metadata_update'
+        );
+
+    if ($conf['use_exif'])
+    {
+      $update_fields =
+        array_merge(
+          $update_fields,
+          array_keys($conf['use_exif_mapping'])
+          );
+    }
+
+    if ($conf['use_iptc'])
+    {
+      $update_fields =
+        array_merge(
+          $update_fields,
+          array_diff(
+            array_keys($conf['use_iptc_mapping']),
+            array('tags', 'keywords')
+            )
+          );
+    }
+
+    mass_updates(
+      IMAGES_TABLE,
+      array(
+        'primary' => array('id'),
+        'update'  => array_unique($update_fields)
+        ),
+      $datas,
+      MASS_UPDATES_SKIP_EMPTY
+      );
+  }
+
+  set_tags_of($tags_of);
+}
+
+/**
+ * returns an array associating element id (images.id) with its complete
+ * path in the filesystem
+ *
+ * @param int id_uppercat
+ * @param int site_id
+ * @param boolean recursive ?
+ * @param boolean only newly added files ?
+ * @return array
+ */
+function get_filelist($category_id = '', $site_id=1, $recursive = false,
+                      $only_new = false)
+{
+  // filling $cat_ids : all categories required
+  $cat_ids = array();
+
+  $query = '
+SELECT id
+  FROM '.CATEGORIES_TABLE.'
+  WHERE site_id = '.$site_id.'
+    AND dir IS NOT NULL';
+  if (is_numeric($category_id))
+  {
+    if ($recursive)
+    {
+      $query.= '
+    AND uppercats REGEXP \'(^|,)'.$category_id.'(,|$)\'
+';
+    }
+    else
+    {
+      $query.= '
+    AND id = '.$category_id.'
+';
+    }
+  }
+  $query.= '
+;';
+  $result = pwg_query($query);
+  while ($row = mysql_fetch_array($result))
+  {
+    array_push($cat_ids, $row['id']);
+  }
+
+  if (count($cat_ids) == 0)
+  {
+    return array();
+  }
+
+  $files = array();
+
+  $query = '
+SELECT id, path
+  FROM '.IMAGES_TABLE.'
+  WHERE storage_category_id IN ('.implode(',', $cat_ids).')';
+  if ($only_new)
+  {
+    $query.= '
+    AND date_metadata_update IS NULL
+';
+  }
+  $query.= '
+;';
+  $result = pwg_query($query);
+  while ($row = mysql_fetch_array($result))
+  {
+    $files[$row['id']] = $row['path'];
+  }
+
+  return $files;
+}
+?>
Index: /tags/2.0.2/admin/include/functions_notification_by_mail.inc.php
===================================================================
--- /tags/2.0.2/admin/include/functions_notification_by_mail.inc.php	(revision 3278)
+++ /tags/2.0.2/admin/include/functions_notification_by_mail.inc.php	(revision 3278)
@@ -0,0 +1,530 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+/* nbm_global_var */
+$env_nbm = array
+          (
+            'start_time' => get_moment(),
+            'sendmail_timeout' => (intval(ini_get('max_execution_time')) * $conf['nbm_max_treatment_timeout_percent']),
+            'is_sendmail_timeout' => false
+          );
+
+if
+  (
+    (!isset($env_nbm['sendmail_timeout'])) or
+    (!is_numeric($env_nbm['sendmail_timeout'])) or
+    ($env_nbm['sendmail_timeout'] <= 0)
+  )
+{
+  $env_nbm['sendmail_timeout'] = $conf['nbm_treatment_timeout_default'];
+}
+
+/*
+ * Search an available check_key
+ *
+ * It's a copy of function find_available_feed_id
+ *
+ * @return string nbm identifier
+ */
+function find_available_check_key()
+{
+  while (true)
+  {
+    $key = generate_key(16);
+    $query = '
+select
+  count(*)
+from
+  '.USER_MAIL_NOTIFICATION_TABLE.'
+where
+  check_key = \''.$key.'\';';
+
+    list($count) = mysql_fetch_row(pwg_query($query));
+    if ($count == 0)
+    {
+      return $key;
+    }
+  }
+}
+
+/*
+ * Check sendmail timeout state
+ *
+ * @return true, if it's timeout
+ */
+function check_sendmail_timeout()
+{
+  global $env_nbm;
+
+  $env_nbm['is_sendmail_timeout'] = ((get_moment() - $env_nbm['start_time']) > $env_nbm['sendmail_timeout']);
+
+  return $env_nbm['is_sendmail_timeout'];
+}
+
+
+/*
+ * Add quote to all elements of check_key_list
+ *
+ * @return quoted check key list
+ */
+function quote_check_key_list($check_key_list = array())
+{
+  return array_map(create_function('$s', 'return \'\\\'\'.$s.\'\\\'\';'), $check_key_list);
+}
+
+/*
+ * Execute all main queries to get list of user 
+ *
+ * Type are the type of list 'subscribe', 'send'
+ *
+ * return array of users
+ */
+function get_user_notifications($action, $check_key_list = array(), $enabled_filter_value = '')
+{
+  global $conf;
+
+  $data_users = array();
+
+  if (in_array($action, array('subscribe', 'send')))
+  {
+    $quoted_check_key_list = quote_check_key_list($check_key_list);
+    if (count($quoted_check_key_list) != 0 )
+    {
+      $query_and_check_key = ' and 
+    check_key in ('.implode(",", $quoted_check_key_list).') ';
+    }
+    else
+    {
+      $query_and_check_key = '';
+    }
+
+    $query = '
+select
+  N.user_id,
+  N.check_key,
+  U.'.$conf['user_fields']['username'].' as username,
+  U.'.$conf['user_fields']['email'].' as mail_address,
+  N.enabled,
+  N.last_send
+from
+  '.USER_MAIL_NOTIFICATION_TABLE.' as N,
+  '.USERS_TABLE.' as U
+where
+  N.user_id =  U.'.$conf['user_fields']['id'];
+  
+    if ($action == 'send')
+    {
+      // No mail empty and all users enabled
+      $query .= ' and
+  N.enabled = \'true\' and
+  U.'.$conf['user_fields']['email'].' is not null';
+    }
+
+    $query .= $query_and_check_key;
+
+    if (isset($enabled_filter_value) and ($enabled_filter_value != ''))
+    {
+      $query .= ' and
+        N.enabled = \''.boolean_to_string($enabled_filter_value).'\'';
+    }
+
+    $query .= '
+order by';
+
+    if ($action == 'send')
+    {
+      $query .= '
+  last_send, username;';
+    }
+    else
+    {
+      $query .= '
+  username;';
+    }
+
+    $query .= ';';
+
+    $result = pwg_query($query);
+    if (!empty($result))
+    {
+      while ($nbm_user = mysql_fetch_array($result))
+      {
+        array_push($data_users, $nbm_user);
+      }
+    }
+  }
+  return $data_users;
+}
+
+/*
+ * Begin of use nbm environment
+ * Prepare and save current environment and initialize data in order to send mail
+ *
+ * Return none
+ */
+function begin_users_env_nbm($is_to_send_mail = false)
+{
+  global $user, $lang, $lang_info, $conf, $env_nbm;
+
+  // Save $user, $lang_info and $lang arrays (include/user.inc.php has been executed)
+  $env_nbm['save_user'] = $user;
+  // Save current language to stack, necessary because $user change during NBM
+  switch_lang_to($user['language']);
+
+  $env_nbm['is_to_send_mail'] = $is_to_send_mail;
+
+  if ($is_to_send_mail)
+  {
+    // Init mail configuration
+    $env_nbm['email_format'] = get_str_email_format($conf['nbm_send_html_mail']);
+    $env_nbm['send_as_name'] = ((isset($conf['nbm_send_mail_as']) and !empty($conf['nbm_send_mail_as'])) ? $conf['nbm_send_mail_as'] : get_mail_sender_name());
+    $env_nbm['send_as_mail_address'] = get_webmaster_mail_address();
+    $env_nbm['send_as_mail_formated'] = format_email($env_nbm['send_as_name'], $env_nbm['send_as_mail_address']);
+    // Init mail counter
+    $env_nbm['error_on_mail_count'] = 0;
+    $env_nbm['sent_mail_count'] = 0;
+    // Save sendmail message info and error in the original language
+    $env_nbm['msg_info'] = l10n('nbm_msg_mail_sent_to');
+    $env_nbm['msg_error'] = l10n('nbm_msg_error_sending_email_to');
+  }
+}
+
+/*
+ * End of use nbm environment
+ * Restore environment
+ *
+ * Return none
+ */
+function end_users_env_nbm()
+{
+  global $user, $lang, $lang_info, $env_nbm;
+
+  // Restore $user, $lang_info and $lang arrays (include/user.inc.php has been executed)
+  $user = $env_nbm['save_user'];
+  // Restore current language to stack, necessary because $user change during NBM
+  switch_lang_back();
+
+  if ($env_nbm['is_to_send_mail'])
+  {
+    unset($env_nbm['email_format']);
+    unset($env_nbm['send_as_name']);
+    unset($env_nbm['send_as_mail_address']);
+    unset($env_nbm['send_as_mail_formated']);
+    // Don t unset counter
+    //unset($env_nbm['error_on_mail_count']);
+    //unset($env_nbm['sent_mail_count']);
+    unset($env_nbm['msg_info']);
+    unset($env_nbm['msg_error']);
+  }
+
+  unset($env_nbm['save_user']);
+  unset($env_nbm['is_to_send_mail']);
+}
+
+/*
+ * Set user on nbm enviromnent
+ *
+ * Return none
+ */
+function set_user_on_env_nbm(&$nbm_user, $is_action_send)
+{
+  global $user, $lang, $lang_info, $env_nbm;
+
+  $user = build_user( $nbm_user['user_id'], true );
+
+  switch_lang_to($user['language']);
+
+  if ($is_action_send)
+  {
+    $nbm_user['template'] = $user['template'];
+    $nbm_user['theme'] = $user['theme'];
+    $env_nbm['mail_template'] =
+      get_mail_template($env_nbm['email_format'], 
+        array('template' => $nbm_user['template'], 'theme' => $nbm_user['theme']));
+    $env_nbm['mail_template']->set_filename('notification_by_mail', 'notification_by_mail.tpl');
+  }
+}
+
+/*
+ * Unset user on nbm enviromnent
+ *
+ * Return none
+ */
+function unset_user_on_env_nbm()
+{
+  global $env_nbm;
+
+  switch_lang_back();
+  unset($env_nbm['mail_template']);
+}
+
+/*
+ * Inc Counter success
+ *
+ * Return none
+ */
+function inc_mail_sent_success($nbm_user)
+{
+  global $page, $env_nbm;
+
+  $env_nbm['sent_mail_count'] += 1;
+  array_push($page['infos'], sprintf($env_nbm['msg_info'], $nbm_user['username'], $nbm_user['mail_address']));
+}
+
+/*
+ * Inc Counter failed
+ *
+ * Return none
+ */
+function inc_mail_sent_failed($nbm_user)
+{
+  global $page, $env_nbm;
+
+  $env_nbm['error_on_mail_count'] += 1;
+  array_push($page['errors'], sprintf($env_nbm['msg_error'], $nbm_user['username'], $nbm_user['mail_address']));
+}
+
+/*
+ * Display Counter Info
+ *
+ * Return none
+ */
+function display_counter_info()
+{
+  global $page, $env_nbm;
+
+  if ($env_nbm['error_on_mail_count'] != 0)
+  {
+    array_push($page['errors'], l10n_dec('nbm_msg_n_mail_not_send', 'nbm_msg_n_mails_not_send', $env_nbm['error_on_mail_count']));
+    if ($env_nbm['sent_mail_count'] != 0)
+      array_push($page['infos'], l10n_dec('nbm_msg_n_mail_sent', 'nbm_msg_n_mails_sent', $env_nbm['sent_mail_count']));
+  }
+  else
+  {
+    if ($env_nbm['sent_mail_count'] == 0)
+      array_push($page['infos'], l10n('nbm_no_mail_to_send'));
+    else
+      array_push($page['infos'], l10n_dec('nbm_msg_n_mail_sent', 'nbm_msg_n_mails_sent', $env_nbm['sent_mail_count']));
+  }
+}
+
+function assign_vars_nbm_mail_content($nbm_user)
+{
+  global $env_nbm;
+
+  set_make_full_url();
+
+  $env_nbm['mail_template']->assign
+  (
+    array
+    (
+      'USERNAME' => $nbm_user['username'],
+
+      'SEND_AS_NAME' => $env_nbm['send_as_name'],
+
+      'UNSUBSCRIBE_LINK' => add_url_params(get_root_url().'nbm.php', array('unsubscribe' => $nbm_user['check_key'])),
+      'SUBSCRIBE_LINK' => add_url_params(get_root_url().'nbm.php', array('subscribe' => $nbm_user['check_key'])),
+      'CONTACT_EMAIL' => $env_nbm['send_as_mail_address']
+    )
+  );
+
+  unset_make_full_url();
+}
+
+/*
+ * Subscribe or unsubscribe notification by mail
+ *
+ * is_subscribe define if action=subscribe or unsubscribe
+ * check_key list where action will be done
+ *
+ * @return check_key list treated
+ */
+function do_subscribe_unsubscribe_notification_by_mail($is_admin_request, $is_subscribe = false, $check_key_list = array())
+{
+  global $conf, $page, $env_nbm, $conf;
+
+  $check_key_treated = array();
+  $updated_data_count = 0;
+  $error_on_updated_data_count = 0;
+
+  if ($is_subscribe)
+  {
+    $msg_info = l10n('nbm_user_change_enabled_true');
+    $msg_error = l10n('nbm_user_not_change_enabled_true');
+  }
+  else
+  {
+    $msg_info = l10n('nbm_user_change_enabled_false');
+    $msg_error = l10n('nbm_user_not_change_enabled_false');
+  }
+
+  if (count($check_key_list) != 0)
+  {
+    $updates = array();
+    $enabled_value = boolean_to_string($is_subscribe);
+    $data_users = get_user_notifications('subscribe', $check_key_list, !$is_subscribe);
+
+    // Prepare message after change language
+    $msg_break_timeout = l10n('nbm_break_timeout_send_mail');
+
+    // Begin nbm users environment
+    begin_users_env_nbm(true);
+
+    foreach ($data_users as $nbm_user)
+    {
+      if (check_sendmail_timeout())
+      {
+        // Stop fill list on 'send', if the quota is override
+        array_push($page['errors'], $msg_break_timeout);
+        break;
+      }
+
+      // Fill return list
+      array_push($check_key_treated, $nbm_user['check_key']);
+
+      $do_update = true;
+      if ($nbm_user['mail_address'] != '')
+      {
+        // set env nbm user
+        set_user_on_env_nbm($nbm_user, true);
+
+        $subject = '['.$conf['gallery_title'].']: '.($is_subscribe ? l10n('nbm_object_subscribe'): l10n('nbm_object_unsubscribe'));
+
+        // Assign current var for nbm mail
+        assign_vars_nbm_mail_content($nbm_user);
+
+        $section_action_by = ($is_subscribe ? 'subscribe_by_' : 'unsubscribe_by_');
+        $section_action_by .= ($is_admin_request ? 'admin' : 'himself');
+        $env_nbm['mail_template']->assign
+        (
+          array
+          (
+            $section_action_by => true,
+            'GOTO_GALLERY_TITLE' => $conf['gallery_title'],
+            'GOTO_GALLERY_URL' => $conf['gallery_url'],
+          )
+        );
+
+        if (pwg_mail
+            (
+              format_email($nbm_user['username'], $nbm_user['mail_address']),
+              array
+              (
+                'from' => $env_nbm['send_as_mail_formated'],
+                'subject' => $subject,
+                'email_format' => $env_nbm['email_format'],
+                'content' => $env_nbm['mail_template']->parse('notification_by_mail', true),
+                'content_format' => $env_nbm['email_format'],
+                'template' => $nbm_user['template'],
+                'theme' => $nbm_user['theme']
+              )
+            ))
+        {
+          inc_mail_sent_success($nbm_user);
+        }
+        else
+        {
+          inc_mail_sent_failed($nbm_user);
+          $do_update = false;
+        }
+
+        // unset env nbm user
+        unset_user_on_env_nbm();
+
+      }
+
+      if ($do_update)
+      {
+        array_push
+        (
+          $updates,
+          array
+          (
+            'check_key' => $nbm_user['check_key'],
+            'enabled' => $enabled_value
+          )
+        );
+        $updated_data_count += 1;
+        array_push($page['infos'], sprintf($msg_info, $nbm_user['username'], $nbm_user['mail_address']));
+      }
+      else
+      {
+        $error_on_updated_data_count += 1;
+        array_push($page['errors'], sprintf($msg_error, $nbm_user['username'], $nbm_user['mail_address']));
+      }
+
+    }
+
+    // Restore nbm environment
+    end_users_env_nbm();
+
+    display_counter_info();
+
+    mass_updates(
+      USER_MAIL_NOTIFICATION_TABLE,
+      array(
+        'primary' => array('check_key'),
+        'update' => array('enabled')
+      ),
+      $updates
+    );
+
+  }
+
+  array_push($page['infos'], l10n_dec('nbm_user_change_enabled_updated_data_count', 'nbm_users_change_enabled_updated_data_count', $updated_data_count));
+  if ($error_on_updated_data_count != 0)
+  {
+    array_push($page['errors'],
+      l10n_dec('nbm_user_change_enabled_error_on_updated_data_count',
+               'nbm_users_change_enabled_error_on_updated_data_count',
+               $error_on_updated_data_count));
+  }
+
+  return $check_key_treated;
+}
+
+/*
+ * Unsubscribe notification by mail
+ *
+ * check_key list where action will be done
+ *
+ * @return check_key list treated
+ */
+function unsubscribe_notification_by_mail($is_admin_request, $check_key_list = array())
+{
+  return do_subscribe_unsubscribe_notification_by_mail($is_admin_request, false, $check_key_list);
+}
+
+/*
+ * Subscribe notification by mail
+ *
+ * check_key list where action will be done
+ *
+ * @return check_key list treated
+ */
+function subscribe_notification_by_mail($is_admin_request, $check_key_list = array())
+{
+  return do_subscribe_unsubscribe_notification_by_mail($is_admin_request, true, $check_key_list);
+}
+
+?>
Index: /tags/2.0.2/admin/include/functions_permalinks.php
===================================================================
--- /tags/2.0.2/admin/include/functions_permalinks.php	(revision 3278)
+++ /tags/2.0.2/admin/include/functions_permalinks.php	(revision 3278)
@@ -0,0 +1,204 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+/** returns a category id that corresponds to the given permalink (or null)
+ * @param string permalink
+ */
+function get_cat_id_from_permalink( $permalink )
+{
+  $query ='
+SELECT id FROM '.CATEGORIES_TABLE.'
+  WHERE permalink="'.$permalink.'"';
+  $ids = array_from_query($query, 'id');
+  if (!empty($ids))
+  {
+    return $ids[0];
+  }
+  return null;
+}
+
+/** returns a category id that has used before this permalink (or null)
+ * @param string permalink
+ * @param boolean is_hit if true update the usage counters on the old permalinks
+ */
+function get_cat_id_from_old_permalink($permalink)
+{
+  $query='
+SELECT c.id
+  FROM '.OLD_PERMALINKS_TABLE.' op INNER JOIN '.CATEGORIES_TABLE.' c
+    ON op.cat_id=c.id
+  WHERE op.permalink="'.$permalink.'"
+  LIMIT 1';
+  $result = pwg_query($query);
+  $cat_id = null;
+  if ( mysql_num_rows($result) )
+    list( $cat_id ) = mysql_fetch_array($result);
+  return $cat_id;
+}
+
+
+/** deletes the permalink associated with a category
+ * returns true on success
+ * @param int cat_id the target category id
+ * @param boolean save if true, the current category-permalink association
+ * is saved in the old permalinks table in case external links hit it
+ */
+function delete_cat_permalink( $cat_id, $save )
+{
+  global $page, $cache;
+  $query = '
+SELECT permalink
+  FROM '.CATEGORIES_TABLE.'
+  WHERE id="'.$cat_id.'"
+;';
+  $result = pwg_query($query);
+  if ( mysql_num_rows($result) )
+  {
+    list($permalink) = mysql_fetch_array($result);
+  }
+  if ( !isset($permalink) )
+  {// no permalink; nothing to do
+    return true;
+  }
+  if ($save)
+  {
+    $old_cat_id = get_cat_id_from_old_permalink($permalink);
+    if ( isset($old_cat_id) and $old_cat_id!=$cat_id )
+    {
+      $page['errors'][] = 
+        sprintf( 
+          l10n('Permalink_%s_histo_used_by_%s'),
+          $permalink, $old_cat_id
+        );
+      return false;
+    }
+  }
+  $query = '
+UPDATE '.CATEGORIES_TABLE.'
+  SET permalink=NULL
+  WHERE id='.$cat_id.'
+  LIMIT 1';
+  pwg_query($query);
+  
+  unset( $cache['cat_names'] ); //force regeneration
+  if ($save)
+  {
+    if ( isset($old_cat_id) )
+    {
+      $query = '
+UPDATE '.OLD_PERMALINKS_TABLE.'
+  SET date_deleted=NOW()
+  WHERE cat_id='.$cat_id.' AND permalink="'.$permalink.'"';
+    }
+    else
+    {
+      $query = '
+INSERT INTO '.OLD_PERMALINKS_TABLE.'
+  (permalink, cat_id, date_deleted)
+VALUES
+  ( "'.$permalink.'",'.$cat_id.',NOW() )';
+    }
+    pwg_query( $query );
+  }
+  return true;
+}
+
+/** sets a new permalink for a category
+ * returns true on success
+ * @param int cat_id the target category id
+ * @param string permalink the new permalink
+ * @param boolean save if true, the current category-permalink association
+ * is saved in the old permalinks table in case external links hit it
+ */
+function set_cat_permalink( $cat_id, $permalink, $save )
+{
+  global $page, $cache;
+  
+  $sanitized_permalink = preg_replace( '#[^a-zA-Z0-9_/-]#', '' ,$permalink);
+  $sanitized_permalink = trim($sanitized_permalink, '/');
+  $sanitized_permalink = str_replace('//', '/', $sanitized_permalink);
+  if ( $sanitized_permalink != $permalink 
+      or preg_match( '#^(\d)+(-.*)?$#', $permalink) )
+  {
+    $page['errors'][] = l10n('Permalink_name_rule');
+    return false;
+  }
+  
+  // check if the new permalink is actively used
+  $existing_cat_id = get_cat_id_from_permalink( $permalink );
+  if ( isset($existing_cat_id) )
+  {
+    if ( $existing_cat_id==$cat_id )
+    {// no change required
+      return true;
+    }
+    else
+    {
+      $page['errors'][] = 
+        sprintf( 
+          l10n('Permalink %s is already used by category %s'),
+          $permalink, $existing_cat_id 
+        );
+      return false;
+    }
+  }
+
+  // check if the new permalink was historically used
+  $old_cat_id = get_cat_id_from_old_permalink($permalink);
+  if ( isset($old_cat_id) and $old_cat_id!=$cat_id )
+  {
+    $page['errors'][] = 
+      sprintf( 
+        l10n('Permalink_%s_histo_used_by_%s'),
+        $permalink, $old_cat_id
+      );
+    return false;
+  }
+
+  if ( !delete_cat_permalink($cat_id, $save ) )
+  {
+    return false;
+  }
+
+  if ( isset($old_cat_id) )
+  {// the new permalink must not be active and old at the same time
+    assert( $old_cat_id==$cat_id );
+    $query = '
+DELETE FROM '.OLD_PERMALINKS_TABLE.'
+  WHERE cat_id='.$old_cat_id.' AND permalink="'.$permalink.'"';
+    pwg_query($query);
+  }
+  
+  $query = '
+UPDATE '.CATEGORIES_TABLE.'
+  SET permalink="'.$permalink.'"
+  WHERE id='.$cat_id.'
+  LIMIT 1';
+  pwg_query($query);
+
+  unset( $cache['cat_names'] ); //force regeneration
+  
+  return true;
+}
+
+?>
Index: /tags/2.0.2/admin/include/functions_plugins.inc.php
===================================================================
--- /tags/2.0.2/admin/include/functions_plugins.inc.php	(revision 3278)
+++ /tags/2.0.2/admin/include/functions_plugins.inc.php	(revision 3278)
@@ -0,0 +1,64 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+/**
+ * Retrieves an url for a plugin page.
+ * @param string file - php script full name
+ */
+function get_admin_plugin_menu_link($file)
+{
+  global $page;
+  $real_file = realpath($file);
+  $url = get_root_url().'admin.php?page=plugin';
+  if (false!==$real_file)
+  {
+    $real_plugin_path = rtrim(realpath(PHPWG_PLUGINS_PATH), '\\/');
+    $file = substr($real_file, strlen($real_plugin_path)+1);
+    $file = str_replace('\\', '/', $file);//Windows
+    $url .= '&amp;section='.urlencode($file);
+  }
+  else if (isset($page['errors']))
+  {
+    array_push($page['errors'], 'PLUGIN ERROR: "'.$file.'" is not a valid file');
+  }
+  return $url;
+}
+
+/**
+ * Set tabsheet for plugins pages.
+ * @param string selected page.
+ */
+function set_plugins_tabsheet($selected)
+{
+  include_once(PHPWG_ROOT_PATH.'admin/include/tabsheet.class.php');
+
+  $link = get_root_url().'admin.php?page=';
+
+  $tabsheet = new tabsheet();
+  $tabsheet->add('plugins_list', l10n('plugins_tab_list'), $link.'plugins_list');
+  $tabsheet->add('plugins_update', l10n('plugins_tab_update'), $link.'plugins_update');
+  $tabsheet->add('plugins_new', l10n('plugins_tab_new'), $link.'plugins_new');
+  $tabsheet->select($selected);
+  $tabsheet->assign();
+}
+?>
Index: /tags/2.0.2/admin/include/functions_themes.inc.php
===================================================================
--- /tags/2.0.2/admin/include/functions_themes.inc.php	(revision 3278)
+++ /tags/2.0.2/admin/include/functions_themes.inc.php	(revision 3278)
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Accordion menus need to be stable (called by themeconf.inc which need it)
+ */
+function selected_admin_menu()
+{
+  if (isset($_GET['page']))
+  {
+    switch ($_GET['page']) {
+      case 'configuration':
+      case 'extend_for_templates':
+      case 'menubar':
+        return 1;
+      case 'site_manager':
+      case 'site_update':
+      case 'cat_list':
+      case 'cat_modify':
+      case 'cat_move':
+      case 'cat_options':
+      case 'cat_perm':
+      case 'permalinks':
+        return 2;
+      case 'element_set':
+        if (isset($_GET['cat']) and is_numeric($_GET['cat']) ) {
+          return 2;
+        }
+      case 'picture_modify':
+        return 3;
+      case 'comments':
+      case 'upload':
+      case 'thumbnail':
+      case 'rating':
+      case 'tags':
+        return 3;
+      case 'user_list':
+      case 'user_perm':
+      case 'group_list':
+      case 'group_perm':
+      case 'notification_by_mail':
+        return 4;
+      case 'stats':
+      case 'history':
+      case 'maintenance':
+      case 'advanced_feature':
+      case 'plugins_list':
+      case 'plugins_update':
+      case 'plugins_new':
+      case 'plugin':
+        return 5;
+    }
+  }
+  if (isset($_GET['plgmenu'])) /* Later added plugins will add plgmenu in url */
+  {
+    return 5;
+  }
+  return 0;
+}
+?>
Index: /tags/2.0.2/admin/include/functions_upgrade.php
===================================================================
--- /tags/2.0.2/admin/include/functions_upgrade.php	(revision 3278)
+++ /tags/2.0.2/admin/include/functions_upgrade.php	(revision 3278)
@@ -0,0 +1,236 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+function check_upgrade()
+{
+  if (defined('PHPWG_IN_UPGRADE'))
+  {
+    return PHPWG_IN_UPGRADE;
+  }
+  return false;
+}
+
+// concerning upgrade, we use the default tables
+function prepare_conf_upgrade()
+{
+  global $prefixeTable;
+
+  // $conf is not used for users tables
+  // define cannot be re-defined
+  define('CATEGORIES_TABLE', $prefixeTable.'categories');
+  define('COMMENTS_TABLE', $prefixeTable.'comments');
+  define('CONFIG_TABLE', $prefixeTable.'config');
+  define('FAVORITES_TABLE', $prefixeTable.'favorites');
+  define('GROUP_ACCESS_TABLE', $prefixeTable.'group_access');
+  define('GROUPS_TABLE', $prefixeTable.'groups');
+  define('HISTORY_TABLE', $prefixeTable.'history');
+  define('HISTORY_SUMMARY_TABLE', $prefixeTable.'history_summary');
+  define('IMAGE_CATEGORY_TABLE', $prefixeTable.'image_category');
+  define('IMAGES_TABLE', $prefixeTable.'images');
+  define('SESSIONS_TABLE', $prefixeTable.'sessions');
+  define('SITES_TABLE', $prefixeTable.'sites');
+  define('USER_ACCESS_TABLE', $prefixeTable.'user_access');
+  define('USER_GROUP_TABLE', $prefixeTable.'user_group');
+  define('USERS_TABLE', $prefixeTable.'users');
+  define('USER_INFOS_TABLE', $prefixeTable.'user_infos');
+  define('USER_FEED_TABLE', $prefixeTable.'user_feed');
+  define('WAITING_TABLE', $prefixeTable.'waiting');
+  define('RATE_TABLE', $prefixeTable.'rate');
+  define('USER_CACHE_TABLE', $prefixeTable.'user_cache');
+  define('USER_CACHE_CATEGORIES_TABLE', $prefixeTable.'user_cache_categories');
+  define('CADDIE_TABLE', $prefixeTable.'caddie');
+  define('UPGRADE_TABLE', $prefixeTable.'upgrade');
+  define('SEARCH_TABLE', $prefixeTable.'search');
+  define('USER_MAIL_NOTIFICATION_TABLE', $prefixeTable.'user_mail_notification');
+  define('TAGS_TABLE', $prefixeTable.'tags');
+  define('IMAGE_TAG_TABLE', $prefixeTable.'image_tag');
+  define('PLUGINS_TABLE', $prefixeTable.'plugins');
+  define('OLD_PERMALINKS_TABLE', $prefixeTable.'old_permalinks');
+}
+
+// Create empty local files to avoid log errors
+function create_empty_local_files()
+{
+   $files =
+      array (
+         PHPWG_ROOT_PATH . 'template-common/local-layout.css',
+         PHPWG_ROOT_PATH . 'template/yoga/local-layout.css'
+         );
+
+   foreach ($files as $path)
+   {
+      if (!file_exists ($path))
+      {
+         $file = @fopen($path, "w");
+         @fwrite($file , '/* You can modify this file */');
+         @fclose($file);
+      }
+   }
+}
+
+// Deactivate all non-standard plugins
+function deactivate_non_standard_plugins()
+{
+  global $page;
+
+  $standard_plugins = array(
+    'add_index',
+    'admin_advices',
+    'admin_multi_view',
+    'c13y_upgrade',
+    'event_tracer',
+    'language_switch',
+    'LocalFilesEditor'
+    );
+
+  $query = '
+SELECT id
+FROM '.PREFIX_TABLE.'plugins
+WHERE state = "active"
+AND id NOT IN ("' . implode('","', $standard_plugins) . '")
+;';
+
+  $result = pwg_query($query);
+  $plugins = array();
+  while ($row = mysql_fetch_assoc($result))
+  {
+    array_push($plugins, $row['id']);
+  }
+
+  if (!empty($plugins))
+  {
+    $query = '
+UPDATE '.PREFIX_TABLE.'plugins
+SET state="inactive"
+WHERE id IN ("' . implode('","', $plugins) . '")
+;';
+    pwg_query($query);
+
+    array_push($page['infos'],
+      l10n('deactivated plugins').'<p><i>'.implode(', ', $plugins).'</i></p>');
+  }
+}
+
+// Check access rights
+function check_upgrade_access_rights($current_release, $username, $password)
+{
+  global $conf, $page;
+
+  if(!get_magic_quotes_gpc())
+  {
+    $username = mysql_real_escape_string($username);
+  }
+
+  if (version_compare($current_release, '2.0', '<'))
+  {
+    $username = utf8_decode($username);
+    $password = utf8_decode($password);
+  }
+
+  if (version_compare($current_release, '1.5', '<'))
+  {
+    $query = '
+SELECT password, status
+FROM '.USERS_TABLE.'
+WHERE username = "'.$username.'"
+;';
+  }
+  else
+  {
+    $query = '
+SELECT u.password, ui.status
+FROM '.$conf['users_table'].' AS u
+INNER JOIN '.USER_INFOS_TABLE.' AS ui
+ON u.'.$conf['user_fields']['id'].'=ui.user_id
+WHERE '.$conf['user_fields']['username'].'="'.$username.'"
+;';
+  }
+  $row = mysql_fetch_assoc(pwg_query($query));
+
+  if (!isset($conf['pass_convert']))
+  {
+    $conf['pass_convert'] = create_function('$s', 'return md5($s);');
+  }
+
+  if ($row['password'] != $conf['pass_convert']($password))
+  {
+    array_push($page['errors'], l10n('invalid_pwd'));
+  }
+  elseif ($row['status'] != 'admin' and $row['status'] != 'webmaster')
+  {
+    array_push($page['errors'], l10n('You do not have access rights to run upgrade'));
+  }
+  else
+  {
+    define('PHPWG_IN_UPGRADE', true);
+  }
+}
+
+/**
+ * which upgrades are available ?
+ *
+ * @return array
+ */
+function get_available_upgrade_ids()
+{
+  $upgrades_path = PHPWG_ROOT_PATH.'install/db';
+
+  $available_upgrade_ids = array();
+
+  if ($contents = opendir($upgrades_path))
+  {
+    while (($node = readdir($contents)) !== false)
+    {
+      if (is_file($upgrades_path.'/'.$node)
+          and preg_match('/^(.*?)-database\.php$/', $node, $match))
+      {
+        array_push($available_upgrade_ids, $match[1]);
+      }
+    }
+  }
+  natcasesort($available_upgrade_ids);
+
+  return $available_upgrade_ids;
+}
+
+
+/**
+ * returns true if there are available upgrade files
+ */
+function check_upgrade_feed()
+{
+  // retrieve already applied upgrades
+  $query = '
+SELECT id
+  FROM '.UPGRADE_TABLE.'
+;';
+  $applied = array_from_query($query, 'id');
+
+  // retrieve existing upgrades
+  $existing = get_available_upgrade_ids();
+
+  // which upgrades need to be applied?
+  return (count(array_diff($existing, $applied)) > 0);
+}
+
+?>
Index: /tags/2.0.2/admin/include/functions_waiting.inc.php
===================================================================
--- /tags/2.0.2/admin/include/functions_waiting.inc.php	(revision 3278)
+++ /tags/2.0.2/admin/include/functions_waiting.inc.php	(revision 3278)
@@ -0,0 +1,41 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+include_once(PHPWG_ROOT_PATH.'admin/include/tabsheet.class.php');
+
+function waiting_tabsheet()
+{
+  global $page, $link_start;
+
+  // TabSheet
+  $tabsheet = new tabsheet();
+  // TabSheet initialization
+  $tabsheet->add('comments', l10n('comments'), $link_start.'comments');
+  $tabsheet->add('upload', l10n('Pictures'), $link_start.'upload');
+  // TabSheet selection
+  $tabsheet->select($page['page']);
+  // Assign tabsheet to template
+  $tabsheet->assign();
+}
+
+?>
Index: /tags/2.0.2/admin/include/index.php
===================================================================
--- /tags/2.0.2/admin/include/index.php	(revision 3278)
+++ /tags/2.0.2/admin/include/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/admin/include/pclzip.lib.php
===================================================================
--- /tags/2.0.2/admin/include/pclzip.lib.php	(revision 3278)
+++ /tags/2.0.2/admin/include/pclzip.lib.php	(revision 3278)
@@ -0,0 +1,3568 @@
+<?php
+// --------------------------------------------------------------------------------
+// PhpConcept Library - Zip Module 2.6
+// --------------------------------------------------------------------------------
+// License GNU/LGPL - Vincent Blavet - March 2006
+// http://www.phpconcept.net
+// --------------------------------------------------------------------------------
+//
+// Presentation :
+//   PclZip is a PHP library that manage ZIP archives.
+//   So far tests show that archives generated by PclZip are readable by
+//   WinZip application and other tools.
+//
+// Description :
+//   See readme.txt and http://www.phpconcept.net
+//
+// Warning :
+//   This library and the associated files are non commercial, non professional
+//   work.
+//   It should not have unexpected results. However if any damage is caused by
+//   this software the author can not be responsible.
+//   The use of this software is at the risk of the user.
+//
+// --------------------------------------------------------------------------------
+
+if (!defined('PCLZIP_READ_BLOCK_SIZE')) {
+  define( 'PCLZIP_READ_BLOCK_SIZE', 2048 );
+}
+
+if (!defined('PCLZIP_SEPARATOR')) {
+  define( 'PCLZIP_SEPARATOR', ',' );
+}
+
+if (!defined('PCLZIP_ERROR_EXTERNAL')) {
+  define( 'PCLZIP_ERROR_EXTERNAL', 0 );
+}
+
+if (!defined('PCLZIP_TEMPORARY_DIR')) {
+  define( 'PCLZIP_TEMPORARY_DIR', '' );
+}
+
+
+$g_pclzip_version = "2.6";
+
+define( 'PCLZIP_ERR_USER_ABORTED', 2 );
+define( 'PCLZIP_ERR_NO_ERROR', 0 );
+define( 'PCLZIP_ERR_WRITE_OPEN_FAIL', -1 );
+define( 'PCLZIP_ERR_READ_OPEN_FAIL', -2 );
+define( 'PCLZIP_ERR_INVALID_PARAMETER', -3 );
+define( 'PCLZIP_ERR_MISSING_FILE', -4 );
+define( 'PCLZIP_ERR_FILENAME_TOO_LONG', -5 );
+define( 'PCLZIP_ERR_INVALID_ZIP', -6 );
+define( 'PCLZIP_ERR_BAD_EXTRACTED_FILE', -7 );
+define( 'PCLZIP_ERR_DIR_CREATE_FAIL', -8 );
+define( 'PCLZIP_ERR_BAD_EXTENSION', -9 );
+define( 'PCLZIP_ERR_BAD_FORMAT', -10 );
+define( 'PCLZIP_ERR_DELETE_FILE_FAIL', -11 );
+define( 'PCLZIP_ERR_RENAME_FILE_FAIL', -12 );
+define( 'PCLZIP_ERR_BAD_CHECKSUM', -13 );
+define( 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', -14 );
+define( 'PCLZIP_ERR_MISSING_OPTION_VALUE', -15 );
+define( 'PCLZIP_ERR_INVALID_OPTION_VALUE', -16 );
+define( 'PCLZIP_ERR_ALREADY_A_DIRECTORY', -17 );
+define( 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION', -18 );
+define( 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION', -19 );
+define( 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE', -20 );
+define( 'PCLZIP_ERR_DIRECTORY_RESTRICTION', -21 );
+
+define( 'PCLZIP_OPT_PATH', 77001 );
+define( 'PCLZIP_OPT_ADD_PATH', 77002 );
+define( 'PCLZIP_OPT_REMOVE_PATH', 77003 );
+define( 'PCLZIP_OPT_REMOVE_ALL_PATH', 77004 );
+define( 'PCLZIP_OPT_SET_CHMOD', 77005 );
+define( 'PCLZIP_OPT_EXTRACT_AS_STRING', 77006 );
+define( 'PCLZIP_OPT_NO_COMPRESSION', 77007 );
+define( 'PCLZIP_OPT_BY_NAME', 77008 );
+define( 'PCLZIP_OPT_BY_INDEX', 77009 );
+define( 'PCLZIP_OPT_BY_EREG', 77010 );
+define( 'PCLZIP_OPT_BY_PREG', 77011 );
+define( 'PCLZIP_OPT_COMMENT', 77012 );
+define( 'PCLZIP_OPT_ADD_COMMENT', 77013 );
+define( 'PCLZIP_OPT_PREPEND_COMMENT', 77014 );
+define( 'PCLZIP_OPT_EXTRACT_IN_OUTPUT', 77015 );
+define( 'PCLZIP_OPT_REPLACE_NEWER', 77016 );
+define( 'PCLZIP_OPT_STOP_ON_ERROR', 77017 );
+define( 'PCLZIP_OPT_EXTRACT_DIR_RESTRICTION', 77019 );
+
+define( 'PCLZIP_ATT_FILE_NAME', 79001 );
+define( 'PCLZIP_ATT_FILE_NEW_SHORT_NAME', 79002 );
+define( 'PCLZIP_ATT_FILE_NEW_FULL_NAME', 79003 );
+define( 'PCLZIP_ATT_FILE_MTIME', 79004 );
+define( 'PCLZIP_ATT_FILE_CONTENT', 79005 );
+define( 'PCLZIP_ATT_FILE_COMMENT', 79006 );
+
+define( 'PCLZIP_CB_PRE_EXTRACT', 78001 );
+define( 'PCLZIP_CB_POST_EXTRACT', 78002 );
+define( 'PCLZIP_CB_PRE_ADD', 78003 );
+define( 'PCLZIP_CB_POST_ADD', 78004 );
+
+
+class PclZip
+{
+  var $zipname = '';
+
+  var $zip_fd = 0;
+
+  var $error_code = 1;
+  var $error_string = '';
+  
+  var $magic_quotes_status;
+
+function PclZip($p_zipname)
+{
+
+  if (!function_exists('gzopen'))
+  {
+    die('Abort '.basename(__FILE__).' : Missing zlib extensions');
+  }
+
+  $this->zipname = $p_zipname;
+  $this->zip_fd = 0;
+  $this->magic_quotes_status = -1;
+
+  return;
+}
+
+function create($p_filelist)
+{
+  $v_result=1;
+
+  $this->privErrorReset();
+
+  $v_options = array();
+  $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;
+
+  $v_size = func_num_args();
+
+  if ($v_size > 1) {
+    $v_arg_list = func_get_args();
+
+    array_shift($v_arg_list);
+    $v_size--;
+
+    if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
+
+      $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
+                                          array (PCLZIP_OPT_REMOVE_PATH => 'optional',
+                                                 PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
+                                                 PCLZIP_OPT_ADD_PATH => 'optional',
+                                                 PCLZIP_CB_PRE_ADD => 'optional',
+                                                 PCLZIP_CB_POST_ADD => 'optional',
+                                                 PCLZIP_OPT_NO_COMPRESSION => 'optional',
+                                                 PCLZIP_OPT_COMMENT => 'optional'
+                                           ));
+      if ($v_result != 1) {
+        return 0;
+      }
+    }
+
+    else {
+
+      $v_options[PCLZIP_OPT_ADD_PATH] = $v_arg_list[0];
+
+      if ($v_size == 2) {
+        $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1];
+      }
+      else if ($v_size > 2) {
+        PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
+                         "Invalid number / type of arguments");
+        return 0;
+      }
+    }
+  }
+
+  $v_string_list = array();
+  $v_att_list = array();
+  $v_filedescr_list = array();
+  $p_result_list = array();
+  
+  if (is_array($p_filelist)) {
+  
+    if (isset($p_filelist[0]) && is_array($p_filelist[0])) {
+      $v_att_list = $p_filelist;
+    }
+    
+    else {
+      $v_string_list = $p_filelist;
+    }
+  }
+
+  else if (is_string($p_filelist)) {
+    $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);
+  }
+
+  else {
+    PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_filelist");
+    return 0;
+  }
+  
+  if (sizeof($v_string_list) != 0) {
+    foreach ($v_string_list as $v_string) {
+      if ($v_string != '') {
+        $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string;
+      }
+      else {
+      }
+    }
+  }
+  
+  $v_supported_attributes
+  = array ( PCLZIP_ATT_FILE_NAME => 'mandatory'
+           ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional'
+           ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional'
+           ,PCLZIP_ATT_FILE_MTIME => 'optional'
+           ,PCLZIP_ATT_FILE_CONTENT => 'optional'
+           ,PCLZIP_ATT_FILE_COMMENT => 'optional'
+          );
+  foreach ($v_att_list as $v_entry) {
+    $v_result = $this->privFileDescrParseAtt($v_entry,
+                                             $v_filedescr_list[],
+                                             $v_options,
+                                             $v_supported_attributes);
+    if ($v_result != 1) {
+      return 0;
+    }
+  }
+
+  $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options);
+  if ($v_result != 1) {
+    return 0;
+  }
+
+  $v_result = $this->privCreate($v_filedescr_list, $p_result_list, $v_options);
+  if ($v_result != 1) {
+    return 0;
+  }
+
+  return $p_result_list;
+}
+
+function add($p_filelist)
+{
+  $v_result=1;
+
+  $this->privErrorReset();
+
+  $v_options = array();
+  $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;
+
+  $v_size = func_num_args();
+
+  if ($v_size > 1) {
+    $v_arg_list = func_get_args();
+
+    array_shift($v_arg_list);
+    $v_size--;
+
+    if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
+
+      $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
+                                          array (PCLZIP_OPT_REMOVE_PATH => 'optional',
+                                                 PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
+                                                 PCLZIP_OPT_ADD_PATH => 'optional',
+                                                 PCLZIP_CB_PRE_ADD => 'optional',
+                                                 PCLZIP_CB_POST_ADD => 'optional',
+                                                 PCLZIP_OPT_NO_COMPRESSION => 'optional',
+                                                 PCLZIP_OPT_COMMENT => 'optional',
+                                                 PCLZIP_OPT_ADD_COMMENT => 'optional',
+                                                 PCLZIP_OPT_PREPEND_COMMENT => 'optional'
+                         ));
+      if ($v_result != 1) {
+        return 0;
+      }
+    }
+
+    else {
+
+      $v_options[PCLZIP_OPT_ADD_PATH] = $v_add_path = $v_arg_list[0];
+
+      if ($v_size == 2) {
+        $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1];
+      }
+      else if ($v_size > 2) {
+        PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
+
+        return 0;
+      }
+    }
+  }
+
+  $v_string_list = array();
+  $v_att_list = array();
+  $v_filedescr_list = array();
+  $p_result_list = array();
+  
+  if (is_array($p_filelist)) {
+  
+    if (isset($p_filelist[0]) && is_array($p_filelist[0])) {
+      $v_att_list = $p_filelist;
+    }
+    
+    else {
+      $v_string_list = $p_filelist;
+    }
+  }
+
+  else if (is_string($p_filelist)) {
+    $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);
+  }
+
+  else {
+    PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type '".gettype($p_filelist)."' for p_filelist");
+    return 0;
+  }
+  
+  if (sizeof($v_string_list) != 0) {
+    foreach ($v_string_list as $v_string) {
+      $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string;
+    }
+  }
+  
+  $v_supported_attributes
+  = array ( PCLZIP_ATT_FILE_NAME => 'mandatory'
+           ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional'
+           ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional'
+           ,PCLZIP_ATT_FILE_MTIME => 'optional'
+           ,PCLZIP_ATT_FILE_CONTENT => 'optional'
+           ,PCLZIP_ATT_FILE_COMMENT => 'optional'
+          );
+  foreach ($v_att_list as $v_entry) {
+    $v_result = $this->privFileDescrParseAtt($v_entry,
+                                             $v_filedescr_list[],
+                                             $v_options,
+                                             $v_supported_attributes);
+    if ($v_result != 1) {
+      return 0;
+    }
+  }
+
+  $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options);
+  if ($v_result != 1) {
+    return 0;
+  }
+
+  $v_result = $this->privAdd($v_filedescr_list, $p_result_list, $v_options);
+  if ($v_result != 1) {
+    return 0;
+  }
+
+  return $p_result_list;
+}
+
+function listContent()
+{
+  $v_result=1;
+
+  $this->privErrorReset();
+
+  if (!$this->privCheckFormat()) {
+    return(0);
+  }
+
+  $p_list = array();
+  if (($v_result = $this->privList($p_list)) != 1)
+  {
+    unset($p_list);
+    return(0);
+  }
+
+  return $p_list;
+}
+
+function extract()
+{
+  $v_result=1;
+
+  $this->privErrorReset();
+
+  if (!$this->privCheckFormat()) {
+    return(0);
+  }
+
+  $v_options = array();
+  $v_path = '';
+  $v_remove_path = "";
+  $v_remove_all_path = false;
+
+  $v_size = func_num_args();
+
+  $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
+
+  if ($v_size > 0) {
+    $v_arg_list = func_get_args();
+
+    if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
+
+      $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
+                                          array (PCLZIP_OPT_PATH => 'optional',
+                                                 PCLZIP_OPT_REMOVE_PATH => 'optional',
+                                                 PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
+                                                 PCLZIP_OPT_ADD_PATH => 'optional',
+                                                 PCLZIP_CB_PRE_EXTRACT => 'optional',
+                                                 PCLZIP_CB_POST_EXTRACT => 'optional',
+                                                 PCLZIP_OPT_SET_CHMOD => 'optional',
+                                                 PCLZIP_OPT_BY_NAME => 'optional',
+                                                 PCLZIP_OPT_BY_EREG => 'optional',
+                                                 PCLZIP_OPT_BY_PREG => 'optional',
+                                                 PCLZIP_OPT_BY_INDEX => 'optional',
+                                                 PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',
+                                                 PCLZIP_OPT_EXTRACT_IN_OUTPUT => 'optional',
+                                                 PCLZIP_OPT_REPLACE_NEWER => 'optional'
+                                                 ,PCLZIP_OPT_STOP_ON_ERROR => 'optional'
+                                                 ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional'
+                          ));
+      if ($v_result != 1) {
+        return 0;
+      }
+
+      if (isset($v_options[PCLZIP_OPT_PATH])) {
+        $v_path = $v_options[PCLZIP_OPT_PATH];
+      }
+      if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
+        $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
+      }
+      if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
+        $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
+      }
+      if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
+        if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {
+          $v_path .= '/';
+        }
+        $v_path .= $v_options[PCLZIP_OPT_ADD_PATH];
+      }
+    }
+
+    else {
+
+      $v_path = $v_arg_list[0];
+
+      if ($v_size == 2) {
+        $v_remove_path = $v_arg_list[1];
+      }
+      else if ($v_size > 2) {
+        PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
+
+        return 0;
+      }
+    }
+  }
+
+
+  $p_list = array();
+  $v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path,
+                                     $v_remove_all_path, $v_options);
+  if ($v_result < 1) {
+    unset($p_list);
+    return(0);
+  }
+
+  return $p_list;
+}
+
+
+function extractByIndex($p_index)
+{
+  $v_result=1;
+
+  $this->privErrorReset();
+
+  if (!$this->privCheckFormat()) {
+    return(0);
+  }
+
+  $v_options = array();
+  $v_path = '';
+  $v_remove_path = "";
+  $v_remove_all_path = false;
+
+  $v_size = func_num_args();
+
+  $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
+
+  if ($v_size > 1) {
+    $v_arg_list = func_get_args();
+
+    array_shift($v_arg_list);
+    $v_size--;
+
+    if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
+
+      $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
+                                          array (PCLZIP_OPT_PATH => 'optional',
+                                                 PCLZIP_OPT_REMOVE_PATH => 'optional',
+                                                 PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
+                                                 PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',
+                                                 PCLZIP_OPT_ADD_PATH => 'optional',
+                                                 PCLZIP_CB_PRE_EXTRACT => 'optional',
+                                                 PCLZIP_CB_POST_EXTRACT => 'optional',
+                                                 PCLZIP_OPT_SET_CHMOD => 'optional',
+                                                 PCLZIP_OPT_REPLACE_NEWER => 'optional'
+                                                 ,PCLZIP_OPT_STOP_ON_ERROR => 'optional'
+                                                 ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional'
+                         ));
+      if ($v_result != 1) {
+        return 0;
+      }
+
+      if (isset($v_options[PCLZIP_OPT_PATH])) {
+        $v_path = $v_options[PCLZIP_OPT_PATH];
+      }
+      if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
+        $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
+      }
+      if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
+        $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
+      }
+      if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
+        if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {
+          $v_path .= '/';
+        }
+        $v_path .= $v_options[PCLZIP_OPT_ADD_PATH];
+      }
+      if (!isset($v_options[PCLZIP_OPT_EXTRACT_AS_STRING])) {
+        $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
+      }
+      else {
+      }
+    }
+
+    else {
+
+      $v_path = $v_arg_list[0];
+
+      if ($v_size == 2) {
+        $v_remove_path = $v_arg_list[1];
+      }
+      else if ($v_size > 2) {
+        PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
+
+        return 0;
+      }
+    }
+  }
+
+
+  $v_arg_trick = array (PCLZIP_OPT_BY_INDEX, $p_index);
+  $v_options_trick = array();
+  $v_result = $this->privParseOptions($v_arg_trick, sizeof($v_arg_trick), $v_options_trick,
+                                      array (PCLZIP_OPT_BY_INDEX => 'optional' ));
+  if ($v_result != 1) {
+      return 0;
+  }
+  $v_options[PCLZIP_OPT_BY_INDEX] = $v_options_trick[PCLZIP_OPT_BY_INDEX];
+
+  if (($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) < 1) {
+      return(0);
+  }
+
+  return $p_list;
+}
+
+function delete()
+{
+  $v_result=1;
+
+  $this->privErrorReset();
+
+  if (!$this->privCheckFormat()) {
+    return(0);
+  }
+
+  $v_options = array();
+
+  $v_size = func_num_args();
+
+  if ($v_size > 0) {
+    $v_arg_list = func_get_args();
+
+    $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
+                                      array (PCLZIP_OPT_BY_NAME => 'optional',
+                                             PCLZIP_OPT_BY_EREG => 'optional',
+                                             PCLZIP_OPT_BY_PREG => 'optional',
+                                             PCLZIP_OPT_BY_INDEX => 'optional' ));
+    if ($v_result != 1) {
+        return 0;
+    }
+  }
+
+  $this->privDisableMagicQuotes();
+
+  $v_list = array();
+  if (($v_result = $this->privDeleteByRule($v_list, $v_options)) != 1) {
+    $this->privSwapBackMagicQuotes();
+    unset($v_list);
+    return(0);
+  }
+
+  $this->privSwapBackMagicQuotes();
+
+  return $v_list;
+}
+
+function deleteByIndex($p_index)
+{
+  
+  $p_list = $this->delete(PCLZIP_OPT_BY_INDEX, $p_index);
+
+  return $p_list;
+}
+
+function properties()
+{
+
+  $this->privErrorReset();
+
+  $this->privDisableMagicQuotes();
+
+  if (!$this->privCheckFormat()) {
+    $this->privSwapBackMagicQuotes();
+    return(0);
+  }
+
+  $v_prop = array();
+  $v_prop['comment'] = '';
+  $v_prop['nb'] = 0;
+  $v_prop['status'] = 'not_exist';
+
+  if (@is_file($this->zipname))
+  {
+    if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0)
+    {
+      $this->privSwapBackMagicQuotes();
+      
+      PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode');
+
+      return 0;
+    }
+
+    $v_central_dir = array();
+    if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
+    {
+      $this->privSwapBackMagicQuotes();
+      return 0;
+    }
+
+    $this->privCloseFd();
+
+    $v_prop['comment'] = $v_central_dir['comment'];
+    $v_prop['nb'] = $v_central_dir['entries'];
+    $v_prop['status'] = 'ok';
+  }
+
+  $this->privSwapBackMagicQuotes();
+
+  return $v_prop;
+}
+
+function duplicate($p_archive)
+{
+  $v_result = 1;
+
+  $this->privErrorReset();
+
+  if ((is_object($p_archive)) && (get_class($p_archive) == 'pclzip'))
+  {
+
+    $v_result = $this->privDuplicate($p_archive->zipname);
+  }
+
+  else if (is_string($p_archive))
+  {
+
+    if (!is_file($p_archive)) {
+      PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "No file with filename '".$p_archive."'");
+      $v_result = PCLZIP_ERR_MISSING_FILE;
+    }
+    else {
+      $v_result = $this->privDuplicate($p_archive);
+    }
+  }
+
+  else
+  {
+    PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");
+    $v_result = PCLZIP_ERR_INVALID_PARAMETER;
+  }
+
+  return $v_result;
+}
+
+function merge($p_archive_to_add)
+{
+  $v_result = 1;
+
+  $this->privErrorReset();
+
+  if (!$this->privCheckFormat()) {
+    return(0);
+  }
+
+  if ((is_object($p_archive_to_add)) && (get_class($p_archive_to_add) == 'pclzip'))
+  {
+
+    $v_result = $this->privMerge($p_archive_to_add);
+  }
+
+  else if (is_string($p_archive_to_add))
+  {
+
+    $v_object_archive = new PclZip($p_archive_to_add);
+
+    $v_result = $this->privMerge($v_object_archive);
+  }
+
+  else
+  {
+    PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");
+    $v_result = PCLZIP_ERR_INVALID_PARAMETER;
+  }
+
+  return $v_result;
+}
+
+
+
+function errorCode()
+{
+  if (PCLZIP_ERROR_EXTERNAL == 1) {
+    return(PclErrorCode());
+  }
+  else {
+    return($this->error_code);
+  }
+}
+
+function errorName($p_with_code=false)
+{
+  $v_name = array ( PCLZIP_ERR_NO_ERROR => 'PCLZIP_ERR_NO_ERROR',
+                    PCLZIP_ERR_WRITE_OPEN_FAIL => 'PCLZIP_ERR_WRITE_OPEN_FAIL',
+                    PCLZIP_ERR_READ_OPEN_FAIL => 'PCLZIP_ERR_READ_OPEN_FAIL',
+                    PCLZIP_ERR_INVALID_PARAMETER => 'PCLZIP_ERR_INVALID_PARAMETER',
+                    PCLZIP_ERR_MISSING_FILE => 'PCLZIP_ERR_MISSING_FILE',
+                    PCLZIP_ERR_FILENAME_TOO_LONG => 'PCLZIP_ERR_FILENAME_TOO_LONG',
+                    PCLZIP_ERR_INVALID_ZIP => 'PCLZIP_ERR_INVALID_ZIP',
+                    PCLZIP_ERR_BAD_EXTRACTED_FILE => 'PCLZIP_ERR_BAD_EXTRACTED_FILE',
+                    PCLZIP_ERR_DIR_CREATE_FAIL => 'PCLZIP_ERR_DIR_CREATE_FAIL',
+                    PCLZIP_ERR_BAD_EXTENSION => 'PCLZIP_ERR_BAD_EXTENSION',
+                    PCLZIP_ERR_BAD_FORMAT => 'PCLZIP_ERR_BAD_FORMAT',
+                    PCLZIP_ERR_DELETE_FILE_FAIL => 'PCLZIP_ERR_DELETE_FILE_FAIL',
+                    PCLZIP_ERR_RENAME_FILE_FAIL => 'PCLZIP_ERR_RENAME_FILE_FAIL',
+                    PCLZIP_ERR_BAD_CHECKSUM => 'PCLZIP_ERR_BAD_CHECKSUM',
+                    PCLZIP_ERR_INVALID_ARCHIVE_ZIP => 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP',
+                    PCLZIP_ERR_MISSING_OPTION_VALUE => 'PCLZIP_ERR_MISSING_OPTION_VALUE',
+                    PCLZIP_ERR_INVALID_OPTION_VALUE => 'PCLZIP_ERR_INVALID_OPTION_VALUE',
+                    PCLZIP_ERR_UNSUPPORTED_COMPRESSION => 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION',
+                    PCLZIP_ERR_UNSUPPORTED_ENCRYPTION => 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION'
+                    ,PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE => 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE'
+                    ,PCLZIP_ERR_DIRECTORY_RESTRICTION => 'PCLZIP_ERR_DIRECTORY_RESTRICTION'
+                  );
+
+  if (isset($v_name[$this->error_code])) {
+    $v_value = $v_name[$this->error_code];
+  }
+  else {
+    $v_value = 'NoName';
+  }
+
+  if ($p_with_code) {
+    return($v_value.' ('.$this->error_code.')');
+  }
+  else {
+    return($v_value);
+  }
+}
+
+function errorInfo($p_full=false)
+{
+  if (PCLZIP_ERROR_EXTERNAL == 1) {
+    return(PclErrorString());
+  }
+  else {
+    if ($p_full) {
+      return($this->errorName(true)." : ".$this->error_string);
+    }
+    else {
+      return($this->error_string." [code ".$this->error_code."]");
+    }
+  }
+}
+
+
+
+
+
+function privCheckFormat($p_level=0)
+{
+  $v_result = true;
+
+    clearstatcache();
+
+  $this->privErrorReset();
+
+  if (!is_file($this->zipname)) {
+    PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "Missing archive file '".$this->zipname."'");
+    return(false);
+  }
+
+  if (!is_readable($this->zipname)) {
+    PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to read archive '".$this->zipname."'");
+    return(false);
+  }
+
+
+
+
+  return $v_result;
+}
+
+function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_requested_options=false)
+{
+  $v_result=1;
+  
+  $i=0;
+  while ($i<$p_size) {
+
+    if (!isset($v_requested_options[$p_options_list[$i]])) {
+      PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid optional parameter '".$p_options_list[$i]."' for this method");
+
+      return PclZip::errorCode();
+    }
+
+    switch ($p_options_list[$i]) {
+      case PCLZIP_OPT_PATH :
+      case PCLZIP_OPT_REMOVE_PATH :
+      case PCLZIP_OPT_ADD_PATH :
+        if (($i+1) >= $p_size) {
+          PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
+
+          return PclZip::errorCode();
+        }
+
+        $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE);
+        $i++;
+      break;
+
+      case PCLZIP_OPT_EXTRACT_DIR_RESTRICTION :
+        if (($i+1) >= $p_size) {
+          PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
+
+          return PclZip::errorCode();
+        }
+
+        if (   is_string($p_options_list[$i+1])
+            && ($p_options_list[$i+1] != '')) {
+          $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE);
+          $i++;
+        }
+        else {
+        }
+      break;
+
+      case PCLZIP_OPT_BY_NAME :
+        if (($i+1) >= $p_size) {
+          PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
+
+          return PclZip::errorCode();
+        }
+
+        if (is_string($p_options_list[$i+1])) {
+            $v_result_list[$p_options_list[$i]][0] = $p_options_list[$i+1];
+        }
+        else if (is_array($p_options_list[$i+1])) {
+            $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
+        }
+        else {
+          PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
+
+          return PclZip::errorCode();
+        }
+        $i++;
+      break;
+
+      case PCLZIP_OPT_BY_EREG :
+      case PCLZIP_OPT_BY_PREG :
+        if (($i+1) >= $p_size) {
+          PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
+
+          return PclZip::errorCode();
+        }
+
+        if (is_string($p_options_list[$i+1])) {
+            $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
+        }
+        else {
+          PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
+
+          return PclZip::errorCode();
+        }
+        $i++;
+      break;
+
+      case PCLZIP_OPT_COMMENT :
+      case PCLZIP_OPT_ADD_COMMENT :
+      case PCLZIP_OPT_PREPEND_COMMENT :
+        if (($i+1) >= $p_size) {
+          PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE,
+                         "Missing parameter value for option '"
+               .PclZipUtilOptionText($p_options_list[$i])
+               ."'");
+
+          return PclZip::errorCode();
+        }
+
+        if (is_string($p_options_list[$i+1])) {
+            $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
+        }
+        else {
+          PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE,
+                         "Wrong parameter value for option '"
+               .PclZipUtilOptionText($p_options_list[$i])
+               ."'");
+
+          return PclZip::errorCode();
+        }
+        $i++;
+      break;
+
+      case PCLZIP_OPT_BY_INDEX :
+        if (($i+1) >= $p_size) {
+          PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
+
+          return PclZip::errorCode();
+        }
+
+        $v_work_list = array();
+        if (is_string($p_options_list[$i+1])) {
+
+            $p_options_list[$i+1] = strtr($p_options_list[$i+1], ' ', '');
+
+            $v_work_list = explode(",", $p_options_list[$i+1]);
+        }
+        else if (is_integer($p_options_list[$i+1])) {
+            $v_work_list[0] = $p_options_list[$i+1].'-'.$p_options_list[$i+1];
+        }
+        else if (is_array($p_options_list[$i+1])) {
+            $v_work_list = $p_options_list[$i+1];
+        }
+        else {
+          PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Value must be integer, string or array for option '".PclZipUtilOptionText($p_options_list[$i])."'");
+
+          return PclZip::errorCode();
+        }
+        
+        $v_sort_flag=false;
+        $v_sort_value=0;
+        for ($j=0; $j<sizeof($v_work_list); $j++) {
+            $v_item_list = explode("-", $v_work_list[$j]);
+            $v_size_item_list = sizeof($v_item_list);
+            
+            
+            if ($v_size_item_list == 1) {
+                $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];
+                $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[0];
+            }
+            elseif ($v_size_item_list == 2) {
+                $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];
+                $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[1];
+            }
+            else {
+                PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Too many values in index range for option '".PclZipUtilOptionText($p_options_list[$i])."'");
+
+                return PclZip::errorCode();
+            }
+
+
+            if ($v_result_list[$p_options_list[$i]][$j]['start'] < $v_sort_value) {
+                $v_sort_flag=true;
+
+                PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Invalid order of index range for option '".PclZipUtilOptionText($p_options_list[$i])."'");
+
+                return PclZip::errorCode();
+            }
+            $v_sort_value = $v_result_list[$p_options_list[$i]][$j]['start'];
+        }
+        
+        if ($v_sort_flag) {
+        }
+
+        $i++;
+      break;
+
+      case PCLZIP_OPT_REMOVE_ALL_PATH :
+      case PCLZIP_OPT_EXTRACT_AS_STRING :
+      case PCLZIP_OPT_NO_COMPRESSION :
+      case PCLZIP_OPT_EXTRACT_IN_OUTPUT :
+      case PCLZIP_OPT_REPLACE_NEWER :
+      case PCLZIP_OPT_STOP_ON_ERROR :
+        $v_result_list[$p_options_list[$i]] = true;
+      break;
+
+      case PCLZIP_OPT_SET_CHMOD :
+        if (($i+1) >= $p_size) {
+          PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
+
+          return PclZip::errorCode();
+        }
+
+        $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
+        $i++;
+      break;
+
+      case PCLZIP_CB_PRE_EXTRACT :
+      case PCLZIP_CB_POST_EXTRACT :
+      case PCLZIP_CB_PRE_ADD :
+      case PCLZIP_CB_POST_ADD :
+
+        if (($i+1) >= $p_size) {
+          PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
+
+          return PclZip::errorCode();
+        }
+
+        $v_function_name = $p_options_list[$i+1];
+
+        if (!function_exists($v_function_name)) {
+          PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Function '".$v_function_name."()' is not an existing function for option '".PclZipUtilOptionText($p_options_list[$i])."'");
+
+          return PclZip::errorCode();
+        }
+
+        $v_result_list[$p_options_list[$i]] = $v_function_name;
+        $i++;
+      break;
+
+      default :
+        PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
+                         "Unknown parameter '"
+               .$p_options_list[$i]."'");
+
+        return PclZip::errorCode();
+    }
+
+    $i++;
+  }
+
+  if ($v_requested_options !== false) {
+    for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) {
+      if ($v_requested_options[$key] == 'mandatory') {
+        if (!isset($v_result_list[$key])) {
+          PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")");
+
+          return PclZip::errorCode();
+        }
+      }
+    }
+  }
+
+  return $v_result;
+}
+
+function privFileDescrParseAtt(&$p_file_list, &$p_filedescr, $v_options, $v_requested_options=false)
+{
+  $v_result=1;
+  
+  foreach ($p_file_list as $v_key => $v_value) {
+  
+    if (!isset($v_requested_options[$v_key])) {
+      PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file attribute '".$v_key."' for this file");
+
+      return PclZip::errorCode();
+    }
+
+    switch ($v_key) {
+      case PCLZIP_ATT_FILE_NAME :
+        if (!is_string($v_value)) {
+          PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
+          return PclZip::errorCode();
+        }
+
+        $p_filedescr['filename'] = PclZipUtilPathReduction($v_value);
+        
+        if ($p_filedescr['filename'] == '') {
+          PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty filename for attribute '".PclZipUtilOptionText($v_key)."'");
+          return PclZip::errorCode();
+        }
+
+      break;
+
+      case PCLZIP_ATT_FILE_NEW_SHORT_NAME :
+        if (!is_string($v_value)) {
+          PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
+          return PclZip::errorCode();
+        }
+
+        $p_filedescr['new_short_name'] = PclZipUtilPathReduction($v_value);
+
+        if ($p_filedescr['new_short_name'] == '') {
+          PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty short filename for attribute '".PclZipUtilOptionText($v_key)."'");
+          return PclZip::errorCode();
+        }
+      break;
+
+      case PCLZIP_ATT_FILE_NEW_FULL_NAME :
+        if (!is_string($v_value)) {
+          PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
+          return PclZip::errorCode();
+        }
+
+        $p_filedescr['new_full_name'] = PclZipUtilPathReduction($v_value);
+
+        if ($p_filedescr['new_full_name'] == '') {
+          PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty full filename for attribute '".PclZipUtilOptionText($v_key)."'");
+          return PclZip::errorCode();
+        }
+      break;
+
+      case PCLZIP_ATT_FILE_COMMENT :
+        if (!is_string($v_value)) {
+          PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
+          return PclZip::errorCode();
+        }
+
+        $p_filedescr['comment'] = $v_value;
+      break;
+
+      case PCLZIP_ATT_FILE_MTIME :
+        if (!is_integer($v_value)) {
+          PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". Integer expected for attribute '".PclZipUtilOptionText($v_key)."'");
+          return PclZip::errorCode();
+        }
+
+        $p_filedescr['mtime'] = $v_value;
+      break;
+
+      case PCLZIP_ATT_FILE_CONTENT :
+        $p_filedescr['content'] = $v_value;
+      break;
+
+      default :
+        PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
+                             "Unknown parameter '".$v_key."'");
+
+        return PclZip::errorCode();
+    }
+
+    if ($v_requested_options !== false) {
+      for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) {
+        if ($v_requested_options[$key] == 'mandatory') {
+          if (!isset($p_file_list[$key])) {
+            PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")");
+            return PclZip::errorCode();
+          }
+        }
+      }
+    }
+  
+  }
+  
+  return $v_result;
+}
+
+function privFileDescrExpand(&$p_filedescr_list, &$p_options)
+{
+  $v_result=1;
+  
+  $v_result_list = array();
+  
+  for ($i=0; $i<sizeof($p_filedescr_list); $i++) {
+    
+    $v_descr = $p_filedescr_list[$i];
+    
+    $v_descr['filename'] = PclZipUtilTranslateWinPath($v_descr['filename']);
+    $v_descr['filename'] = PclZipUtilPathReduction($v_descr['filename']);
+    
+    if (file_exists($v_descr['filename'])) {
+      if (@is_file($v_descr['filename'])) {
+        $v_descr['type'] = 'file';
+      }
+      else if (@is_dir($v_descr['filename'])) {
+        $v_descr['type'] = 'folder';
+      }
+      else if (@is_link($v_descr['filename'])) {
+        continue;
+      }
+      else {
+        continue;
+      }
+    }
+    
+    else if (isset($v_descr['content'])) {
+      $v_descr['type'] = 'virtual_file';
+    }
+    
+    else {
+      PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$v_descr['filename']."' does not exists");
+
+      return PclZip::errorCode();
+    }
+    
+    $this->privCalculateStoredFilename($v_descr, $p_options);
+    
+    $v_result_list[sizeof($v_result_list)] = $v_descr;
+    
+    if ($v_descr['type'] == 'folder') {
+      $v_dirlist_descr = array();
+      $v_dirlist_nb = 0;
+      if ($v_folder_handler = @opendir($v_descr['filename'])) {
+        while (($v_item_handler = @readdir($v_folder_handler)) !== false) {
+
+          if (($v_item_handler == '.') || ($v_item_handler == '..')) {
+              continue;
+          }
+          
+          $v_dirlist_descr[$v_dirlist_nb]['filename'] = $v_descr['filename'].'/'.$v_item_handler;
+          
+          if ($v_descr['stored_filename'] != $v_descr['filename']) {
+            if ($v_descr['stored_filename'] != '') {
+              $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_descr['stored_filename'].'/'.$v_item_handler;
+            }
+            else {
+              $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_item_handler;
+            }
+          }
+    
+          $v_dirlist_nb++;
+        }
+        
+        @closedir($v_folder_handler);
+      }
+      else {
+      }
+      
+      if ($v_dirlist_nb != 0) {
+        if (($v_result = $this->privFileDescrExpand($v_dirlist_descr, $p_options)) != 1) {
+          return $v_result;
+        }
+        
+        $v_result_list = array_merge($v_result_list, $v_dirlist_descr);
+      }
+      else {
+      }
+        
+      unset($v_dirlist_descr);
+    }
+  }
+  
+  $p_filedescr_list = $v_result_list;
+
+  return $v_result;
+}
+
+function privCreate($p_filedescr_list, &$p_result_list, &$p_options)
+{
+  $v_result=1;
+  $v_list_detail = array();
+  
+  $this->privDisableMagicQuotes();
+
+  if (($v_result = $this->privOpenFd('wb')) != 1)
+  {
+    return $v_result;
+  }
+
+  $v_result = $this->privAddList($p_filedescr_list, $p_result_list, $p_options);
+
+  $this->privCloseFd();
+
+  $this->privSwapBackMagicQuotes();
+
+  return $v_result;
+}
+
+function privAdd($p_filedescr_list, &$p_result_list, &$p_options)
+{
+  $v_result=1;
+  $v_list_detail = array();
+
+  if ((!is_file($this->zipname)) || (filesize($this->zipname) == 0))
+  {
+
+    $v_result = $this->privCreate($p_filedescr_list, $p_result_list, $p_options);
+
+    return $v_result;
+  }
+  $this->privDisableMagicQuotes();
+
+  if (($v_result=$this->privOpenFd('rb')) != 1)
+  {
+    $this->privSwapBackMagicQuotes();
+
+    return $v_result;
+  }
+
+  $v_central_dir = array();
+  if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
+  {
+    $this->privCloseFd();
+    $this->privSwapBackMagicQuotes();
+    return $v_result;
+  }
+
+  @rewind($this->zip_fd);
+
+  $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
+
+  if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0)
+  {
+    $this->privCloseFd();
+    $this->privSwapBackMagicQuotes();
+
+    PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode');
+
+    return PclZip::errorCode();
+  }
+
+  $v_size = $v_central_dir['offset'];
+  while ($v_size != 0)
+  {
+    $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
+    $v_buffer = fread($this->zip_fd, $v_read_size);
+    @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
+    $v_size -= $v_read_size;
+  }
+
+  $v_swap = $this->zip_fd;
+  $this->zip_fd = $v_zip_temp_fd;
+  $v_zip_temp_fd = $v_swap;
+
+  $v_header_list = array();
+  if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1)
+  {
+    fclose($v_zip_temp_fd);
+    $this->privCloseFd();
+    @unlink($v_zip_temp_name);
+    $this->privSwapBackMagicQuotes();
+
+    return $v_result;
+  }
+
+  $v_offset = @ftell($this->zip_fd);
+
+  $v_size = $v_central_dir['size'];
+  while ($v_size != 0)
+  {
+    $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
+    $v_buffer = @fread($v_zip_temp_fd, $v_read_size);
+    @fwrite($this->zip_fd, $v_buffer, $v_read_size);
+    $v_size -= $v_read_size;
+  }
+
+  for ($i=0, $v_count=0; $i<sizeof($v_header_list); $i++)
+  {
+    if ($v_header_list[$i]['status'] == 'ok') {
+      if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
+        fclose($v_zip_temp_fd);
+        $this->privCloseFd();
+        @unlink($v_zip_temp_name);
+        $this->privSwapBackMagicQuotes();
+
+        return $v_result;
+      }
+      $v_count++;
+    }
+
+    $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
+  }
+
+  $v_comment = $v_central_dir['comment'];
+  if (isset($p_options[PCLZIP_OPT_COMMENT])) {
+    $v_comment = $p_options[PCLZIP_OPT_COMMENT];
+  }
+  if (isset($p_options[PCLZIP_OPT_ADD_COMMENT])) {
+    $v_comment = $v_comment.$p_options[PCLZIP_OPT_ADD_COMMENT];
+  }
+  if (isset($p_options[PCLZIP_OPT_PREPEND_COMMENT])) {
+    $v_comment = $p_options[PCLZIP_OPT_PREPEND_COMMENT].$v_comment;
+  }
+
+  $v_size = @ftell($this->zip_fd)-$v_offset;
+
+  if (($v_result = $this->privWriteCentralHeader($v_count+$v_central_dir['entries'], $v_size, $v_offset, $v_comment)) != 1)
+  {
+    unset($v_header_list);
+    $this->privSwapBackMagicQuotes();
+
+    return $v_result;
+  }
+
+  $v_swap = $this->zip_fd;
+  $this->zip_fd = $v_zip_temp_fd;
+  $v_zip_temp_fd = $v_swap;
+
+  $this->privCloseFd();
+
+  @fclose($v_zip_temp_fd);
+
+  $this->privSwapBackMagicQuotes();
+
+  @unlink($this->zipname);
+
+  PclZipUtilRename($v_zip_temp_name, $this->zipname);
+
+  return $v_result;
+}
+
+function privOpenFd($p_mode)
+{
+  $v_result=1;
+
+  if ($this->zip_fd != 0)
+  {
+    PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Zip file \''.$this->zipname.'\' already open');
+
+    return PclZip::errorCode();
+  }
+
+  if (($this->zip_fd = @fopen($this->zipname, $p_mode)) == 0)
+  {
+    PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in '.$p_mode.' mode');
+
+    return PclZip::errorCode();
+  }
+
+  return $v_result;
+}
+
+function privCloseFd()
+{
+  $v_result=1;
+
+  if ($this->zip_fd != 0)
+    @fclose($this->zip_fd);
+  $this->zip_fd = 0;
+
+  return $v_result;
+}
+
+function privAddList($p_filedescr_list, &$p_result_list, &$p_options)
+{
+  $v_result=1;
+
+  $v_header_list = array();
+  if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1)
+  {
+    return $v_result;
+  }
+
+  $v_offset = @ftell($this->zip_fd);
+
+  for ($i=0,$v_count=0; $i<sizeof($v_header_list); $i++)
+  {
+    if ($v_header_list[$i]['status'] == 'ok') {
+      if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
+        return $v_result;
+      }
+      $v_count++;
+    }
+
+    $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
+  }
+
+  $v_comment = '';
+  if (isset($p_options[PCLZIP_OPT_COMMENT])) {
+    $v_comment = $p_options[PCLZIP_OPT_COMMENT];
+  }
+
+  $v_size = @ftell($this->zip_fd)-$v_offset;
+
+  if (($v_result = $this->privWriteCentralHeader($v_count, $v_size, $v_offset, $v_comment)) != 1)
+  {
+    unset($v_header_list);
+
+    return $v_result;
+  }
+
+  return $v_result;
+}
+
+function privAddFileList($p_filedescr_list, &$p_result_list, &$p_options)
+{
+  $v_result=1;
+  $v_header = array();
+
+  $v_nb = sizeof($p_result_list);
+
+  for ($j=0; ($j<sizeof($p_filedescr_list)) && ($v_result==1); $j++) {
+    $p_filedescr_list[$j]['filename']
+    = PclZipUtilTranslateWinPath($p_filedescr_list[$j]['filename'], false);
+    
+
+    if ($p_filedescr_list[$j]['filename'] == "") {
+      continue;
+    }
+
+    if (   ($p_filedescr_list[$j]['type'] != 'virtual_file')
+        && (!file_exists($p_filedescr_list[$j]['filename']))) {
+      PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$p_filedescr_list[$j]['filename']."' does not exists");
+      return PclZip::errorCode();
+    }
+
+    if (   ($p_filedescr_list[$j]['type'] == 'file')
+        || ($p_filedescr_list[$j]['type'] == 'virtual_file')
+        || (   ($p_filedescr_list[$j]['type'] == 'folder')
+            && (   !isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])
+                || !$p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))
+        ) {
+
+      $v_result = $this->privAddFile($p_filedescr_list[$j], $v_header,
+                                     $p_options);
+      if ($v_result != 1) {
+        return $v_result;
+      }
+
+      $p_result_list[$v_nb++] = $v_header;
+    }
+  }
+
+  return $v_result;
+}
+
+function privAddFile($p_filedescr, &$p_header, &$p_options)
+{
+  $v_result=1;
+  
+  $p_filename = $p_filedescr['filename'];
+
+  if ($p_filename == "") {
+    PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file list parameter (invalid or empty list)");
+
+    return PclZip::errorCode();
+  }
+
+
+
+  clearstatcache();
+  $p_header['version'] = 20;
+  $p_header['version_extracted'] = 10;
+  $p_header['flag'] = 0;
+  $p_header['compression'] = 0;
+  $p_header['crc'] = 0;
+  $p_header['compressed_size'] = 0;
+  $p_header['filename_len'] = strlen($p_filename);
+  $p_header['extra_len'] = 0;
+  $p_header['disk'] = 0;
+  $p_header['internal'] = 0;
+  $p_header['offset'] = 0;
+  $p_header['filename'] = $p_filename;
+  $p_header['stored_filename'] = $p_filedescr['stored_filename'];
+  $p_header['extra'] = '';
+  $p_header['status'] = 'ok';
+  $p_header['index'] = -1;
+
+  if ($p_filedescr['type']=='file') {
+    $p_header['external'] = 0x00000000;
+    $p_header['size'] = filesize($p_filename);
+  }
+  
+  else if ($p_filedescr['type']=='folder') {
+    $p_header['external'] = 0x00000010;
+    $p_header['mtime'] = filemtime($p_filename);
+    $p_header['size'] = filesize($p_filename);
+  }
+  
+  else if ($p_filedescr['type'] == 'virtual_file') {
+    $p_header['external'] = 0x00000000;
+    $p_header['size'] = strlen($p_filedescr['content']);
+  }
+  
+
+  if (isset($p_filedescr['mtime'])) {
+    $p_header['mtime'] = $p_filedescr['mtime'];
+  }
+  else if ($p_filedescr['type'] == 'virtual_file') {
+    $p_header['mtime'] = mktime();
+  }
+  else {
+    $p_header['mtime'] = filemtime($p_filename);
+  }
+
+  if (isset($p_filedescr['comment'])) {
+    $p_header['comment_len'] = strlen($p_filedescr['comment']);
+    $p_header['comment'] = $p_filedescr['comment'];
+  }
+  else {
+    $p_header['comment_len'] = 0;
+    $p_header['comment'] = '';
+  }
+
+  if (isset($p_options[PCLZIP_CB_PRE_ADD])) {
+
+    $v_local_header = array();
+    $this->privConvertHeader2FileInfo($p_header, $v_local_header);
+
+    eval('$v_result = '.$p_options[PCLZIP_CB_PRE_ADD].'(PCLZIP_CB_PRE_ADD, $v_local_header);');
+    if ($v_result == 0) {
+      $p_header['status'] = "skipped";
+      $v_result = 1;
+    }
+
+    if ($p_header['stored_filename'] != $v_local_header['stored_filename']) {
+      $p_header['stored_filename'] = PclZipUtilPathReduction($v_local_header['stored_filename']);
+    }
+  }
+
+  if ($p_header['stored_filename'] == "") {
+    $p_header['status'] = "filtered";
+  }
+  
+  if (strlen($p_header['stored_filename']) > 0xFF) {
+    $p_header['status'] = 'filename_too_long';
+  }
+
+  if ($p_header['status'] == 'ok') {
+
+    if (   ($p_filedescr['type'] == 'file')
+        || ($p_filedescr['type'] == 'virtual_file')) {
+        
+      if ($p_filedescr['type'] == 'file') {        
+
+        if (($v_file = @fopen($p_filename, "rb")) == 0) {
+          PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode");
+          return PclZip::errorCode();
+        }
+
+        $v_content = @fread($v_file, $p_header['size']);
+
+        @fclose($v_file);
+      }
+      else if ($p_filedescr['type'] == 'virtual_file') {        
+        $v_content = $p_filedescr['content'];
+      }
+
+      $p_header['crc'] = @crc32($v_content);
+      
+      if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) {
+        $p_header['compressed_size'] = $p_header['size'];
+        $p_header['compression'] = 0;
+      }
+      
+      else {
+        $v_content = @gzdeflate($v_content);
+
+        $p_header['compressed_size'] = strlen($v_content);
+        $p_header['compression'] = 8;
+      }
+      
+
+
+      if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
+        @fclose($v_file);
+        return $v_result;
+      }
+
+      @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']);
+    }
+
+    else if ($p_filedescr['type'] == 'folder') {
+      if (@substr($p_header['stored_filename'], -1) != '/') {
+        $p_header['stored_filename'] .= '/';
+      }
+
+      $p_header['size'] = 0;
+      $p_header['external'] = 0x00000010;
+      if (($v_result = $this->privWriteFileHeader($p_header)) != 1)
+      {
+        return $v_result;
+      }
+    }
+  }
+
+  if (isset($p_options[PCLZIP_CB_POST_ADD])) {
+
+    $v_local_header = array();
+    $this->privConvertHeader2FileInfo($p_header, $v_local_header);
+
+    eval('$v_result = '.$p_options[PCLZIP_CB_POST_ADD].'(PCLZIP_CB_POST_ADD, $v_local_header);');
+    if ($v_result == 0) {
+      $v_result = 1;
+    }
+
+  }
+
+  return $v_result;
+}
+
+function privCalculateStoredFilename(&$p_filedescr, &$p_options)
+{
+  $v_result=1;
+  
+  $p_filename = $p_filedescr['filename'];
+  if (isset($p_options[PCLZIP_OPT_ADD_PATH])) {
+    $p_add_dir = $p_options[PCLZIP_OPT_ADD_PATH];
+  }
+  else {
+    $p_add_dir = '';
+  }
+  if (isset($p_options[PCLZIP_OPT_REMOVE_PATH])) {
+    $p_remove_dir = $p_options[PCLZIP_OPT_REMOVE_PATH];
+  }
+  else {
+    $p_remove_dir = '';
+  }
+  if (isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
+    $p_remove_all_dir = $p_options[PCLZIP_OPT_REMOVE_ALL_PATH];
+  }
+  else {
+    $p_remove_all_dir = 0;
+  }
+
+  if (isset($p_filedescr['new_full_name'])) {
+    $v_stored_filename = $p_filedescr['new_full_name'];
+  }
+  
+  else {
+
+    if (isset($p_filedescr['new_short_name'])) {
+      $v_path_info = pathinfo($p_filename);
+      $v_dir = '';
+      if ($v_path_info['dirname'] != '') {
+        $v_dir = $v_path_info['dirname'].'/';
+      }
+      $v_stored_filename = $v_dir.$p_filedescr['new_short_name'];
+    }
+    else {
+      $v_stored_filename = $p_filename;
+    }
+
+    if ($p_remove_all_dir) {
+      $v_stored_filename = basename($p_filename);
+    }
+    else if ($p_remove_dir != "") {
+      if (substr($p_remove_dir, -1) != '/')
+        $p_remove_dir .= "/";
+
+      if (   (substr($p_filename, 0, 2) == "./")
+          || (substr($p_remove_dir, 0, 2) == "./")) {
+          
+        if (   (substr($p_filename, 0, 2) == "./")
+            && (substr($p_remove_dir, 0, 2) != "./")) {
+          $p_remove_dir = "./".$p_remove_dir;
+        }
+        if (   (substr($p_filename, 0, 2) != "./")
+            && (substr($p_remove_dir, 0, 2) == "./")) {
+          $p_remove_dir = substr($p_remove_dir, 2);
+        }
+      }
+
+      $v_compare = PclZipUtilPathInclusion($p_remove_dir,
+                                           $v_stored_filename);
+      if ($v_compare > 0) {
+        if ($v_compare == 2) {
+          $v_stored_filename = "";
+        }
+        else {
+          $v_stored_filename = substr($v_stored_filename,
+                                      strlen($p_remove_dir));
+        }
+      }
+    }
+    if ($p_add_dir != "") {
+      if (substr($p_add_dir, -1) == "/")
+        $v_stored_filename = $p_add_dir.$v_stored_filename;
+      else
+        $v_stored_filename = $p_add_dir."/".$v_stored_filename;
+    }
+  }
+
+  $v_stored_filename = PclZipUtilPathReduction($v_stored_filename);
+  $p_filedescr['stored_filename'] = $v_stored_filename;
+  
+  return $v_result;
+}
+
+function privWriteFileHeader(&$p_header)
+{
+  $v_result=1;
+
+  $p_header['offset'] = ftell($this->zip_fd);
+
+  $v_date = getdate($p_header['mtime']);
+  $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;
+  $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];
+
+  $v_binary_data = pack("VvvvvvVVVvv", 0x04034b50,
+                      $p_header['version_extracted'], $p_header['flag'],
+                        $p_header['compression'], $v_mtime, $v_mdate,
+                        $p_header['crc'], $p_header['compressed_size'],
+            $p_header['size'],
+                        strlen($p_header['stored_filename']),
+            $p_header['extra_len']);
+
+  fputs($this->zip_fd, $v_binary_data, 30);
+
+  if (strlen($p_header['stored_filename']) != 0)
+  {
+    fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
+  }
+  if ($p_header['extra_len'] != 0)
+  {
+    fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);
+  }
+
+  return $v_result;
+}
+
+function privWriteCentralFileHeader(&$p_header)
+{
+  $v_result=1;
+
+
+  $v_date = getdate($p_header['mtime']);
+  $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;
+  $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];
+
+
+  $v_binary_data = pack("VvvvvvvVVVvvvvvVV", 0x02014b50,
+                      $p_header['version'], $p_header['version_extracted'],
+                        $p_header['flag'], $p_header['compression'],
+            $v_mtime, $v_mdate, $p_header['crc'],
+                        $p_header['compressed_size'], $p_header['size'],
+                        strlen($p_header['stored_filename']),
+            $p_header['extra_len'], $p_header['comment_len'],
+                        $p_header['disk'], $p_header['internal'],
+            $p_header['external'], $p_header['offset']);
+
+  fputs($this->zip_fd, $v_binary_data, 46);
+
+  if (strlen($p_header['stored_filename']) != 0)
+  {
+    fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
+  }
+  if ($p_header['extra_len'] != 0)
+  {
+    fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);
+  }
+  if ($p_header['comment_len'] != 0)
+  {
+    fputs($this->zip_fd, $p_header['comment'], $p_header['comment_len']);
+  }
+
+  return $v_result;
+}
+
+function privWriteCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment)
+{
+  $v_result=1;
+
+  $v_binary_data = pack("VvvvvVVv", 0x06054b50, 0, 0, $p_nb_entries,
+                      $p_nb_entries, $p_size,
+            $p_offset, strlen($p_comment));
+
+  fputs($this->zip_fd, $v_binary_data, 22);
+
+  if (strlen($p_comment) != 0)
+  {
+    fputs($this->zip_fd, $p_comment, strlen($p_comment));
+  }
+
+  return $v_result;
+}
+
+function privList(&$p_list)
+{
+  $v_result=1;
+
+  $this->privDisableMagicQuotes();
+
+  if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0)
+  {
+    $this->privSwapBackMagicQuotes();
+    
+    PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode');
+
+    return PclZip::errorCode();
+  }
+
+  $v_central_dir = array();
+  if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
+  {
+    $this->privSwapBackMagicQuotes();
+    return $v_result;
+  }
+
+  @rewind($this->zip_fd);
+  if (@fseek($this->zip_fd, $v_central_dir['offset']))
+  {
+    $this->privSwapBackMagicQuotes();
+
+    PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
+
+    return PclZip::errorCode();
+  }
+
+  for ($i=0; $i<$v_central_dir['entries']; $i++)
+  {
+    if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1)
+    {
+      $this->privSwapBackMagicQuotes();
+      return $v_result;
+    }
+    $v_header['index'] = $i;
+
+    $this->privConvertHeader2FileInfo($v_header, $p_list[$i]);
+    unset($v_header);
+  }
+
+  $this->privCloseFd();
+
+  $this->privSwapBackMagicQuotes();
+
+  return $v_result;
+}
+
+function privConvertHeader2FileInfo($p_header, &$p_info)
+{
+  $v_result=1;
+
+  $p_info['filename'] = $p_header['filename'];
+  $p_info['stored_filename'] = $p_header['stored_filename'];
+  $p_info['size'] = $p_header['size'];
+  $p_info['compressed_size'] = $p_header['compressed_size'];
+  $p_info['mtime'] = $p_header['mtime'];
+  $p_info['comment'] = $p_header['comment'];
+  $p_info['folder'] = (($p_header['external']&0x00000010)==0x00000010);
+  $p_info['index'] = $p_header['index'];
+  $p_info['status'] = $p_header['status'];
+  $p_info['crc'] = $p_header['crc'];
+
+  return $v_result;
+}
+
+function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
+{
+  $v_result=1;
+
+  $this->privDisableMagicQuotes();
+
+  if (   ($p_path == "")
+    || (   (substr($p_path, 0, 1) != "/")
+      && (substr($p_path, 0, 3) != "../")
+    && (substr($p_path,1,2)!=":/")))
+    $p_path = "./".$p_path;
+
+  if (($p_path != "./") && ($p_path != "/"))
+  {
+    while (substr($p_path, -1) == "/")
+    {
+      $p_path = substr($p_path, 0, strlen($p_path)-1);
+    }
+  }
+
+  if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/'))
+  {
+    $p_remove_path .= '/';
+  }
+  $p_remove_path_size = strlen($p_remove_path);
+
+  if (($v_result = $this->privOpenFd('rb')) != 1)
+  {
+    $this->privSwapBackMagicQuotes();
+    return $v_result;
+  }
+
+  $v_central_dir = array();
+  if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
+  {
+    $this->privCloseFd();
+    $this->privSwapBackMagicQuotes();
+
+    return $v_result;
+  }
+
+  $v_pos_entry = $v_central_dir['offset'];
+
+  $j_start = 0;
+  for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++)
+  {
+
+    @rewind($this->zip_fd);
+    if (@fseek($this->zip_fd, $v_pos_entry))
+    {
+      $this->privCloseFd();
+      $this->privSwapBackMagicQuotes();
+
+      PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
+
+      return PclZip::errorCode();
+    }
+
+    $v_header = array();
+    if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1)
+    {
+      $this->privCloseFd();
+      $this->privSwapBackMagicQuotes();
+
+      return $v_result;
+    }
+
+    $v_header['index'] = $i;
+
+    $v_pos_entry = ftell($this->zip_fd);
+
+    $v_extract = false;
+
+    if (   (isset($p_options[PCLZIP_OPT_BY_NAME]))
+        && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {
+
+        for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_extract); $j++) {
+
+            if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") {
+
+                if (   (strlen($v_header['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j]))
+                    && (substr($v_header['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
+                    $v_extract = true;
+                }
+            }
+            elseif ($v_header['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {
+                $v_extract = true;
+            }
+        }
+    }
+
+    else if (   (isset($p_options[PCLZIP_OPT_BY_EREG]))
+             && ($p_options[PCLZIP_OPT_BY_EREG] != "")) {
+
+        if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header['stored_filename'])) {
+            $v_extract = true;
+        }
+    }
+
+    else if (   (isset($p_options[PCLZIP_OPT_BY_PREG]))
+             && ($p_options[PCLZIP_OPT_BY_PREG] != "")) {
+
+        if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header['stored_filename'])) {
+            $v_extract = true;
+        }
+    }
+
+    else if (   (isset($p_options[PCLZIP_OPT_BY_INDEX]))
+             && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {
+        
+        for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_extract); $j++) {
+
+            if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) {
+                $v_extract = true;
+            }
+            if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {
+                $j_start = $j+1;
+            }
+
+            if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) {
+                break;
+            }
+        }
+    }
+
+    else {
+        $v_extract = true;
+    }
+
+    if (   ($v_extract)
+      && (   ($v_header['compression'] != 8)
+        && ($v_header['compression'] != 0))) {
+        $v_header['status'] = 'unsupported_compression';
+
+        if (   (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
+        && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
+
+            $this->privSwapBackMagicQuotes();
+            
+            PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_COMPRESSION,
+                           "Filename '".$v_header['stored_filename']."' is "
+                       ."compressed by an unsupported compression "
+                       ."method (".$v_header['compression'].") ");
+
+            return PclZip::errorCode();
+    }
+  }
+  
+    if (($v_extract) && (($v_header['flag'] & 1) == 1)) {
+        $v_header['status'] = 'unsupported_encryption';
+
+        if (   (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
+        && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
+
+            $this->privSwapBackMagicQuotes();
+
+            PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION,
+                           "Unsupported encryption for "
+                       ." filename '".$v_header['stored_filename']
+                 ."'");
+
+            return PclZip::errorCode();
+    }
+  }
+
+    if (($v_extract) && ($v_header['status'] != 'ok')) {
+        $v_result = $this->privConvertHeader2FileInfo($v_header,
+                                          $p_file_list[$v_nb_extracted++]);
+        if ($v_result != 1) {
+            $this->privCloseFd();
+            $this->privSwapBackMagicQuotes();
+            return $v_result;
+        }
+
+        $v_extract = false;
+    }
+    
+    if ($v_extract)
+    {
+
+      @rewind($this->zip_fd);
+      if (@fseek($this->zip_fd, $v_header['offset']))
+      {
+        $this->privCloseFd();
+
+        $this->privSwapBackMagicQuotes();
+
+        PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
+
+        return PclZip::errorCode();
+      }
+
+      if ($p_options[PCLZIP_OPT_EXTRACT_AS_STRING]) {
+
+        $v_result1 = $this->privExtractFileAsString($v_header, $v_string);
+        if ($v_result1 < 1) {
+          $this->privCloseFd();
+          $this->privSwapBackMagicQuotes();
+          return $v_result1;
+        }
+
+        if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted])) != 1)
+        {
+          $this->privCloseFd();
+          $this->privSwapBackMagicQuotes();
+
+          return $v_result;
+        }
+
+        $p_file_list[$v_nb_extracted]['content'] = $v_string;
+
+        $v_nb_extracted++;
+        
+        if ($v_result1 == 2) {
+          break;
+        }
+      }
+      elseif (   (isset($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT]))
+          && ($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) {
+        $v_result1 = $this->privExtractFileInOutput($v_header, $p_options);
+        if ($v_result1 < 1) {
+          $this->privCloseFd();
+          $this->privSwapBackMagicQuotes();
+          return $v_result1;
+        }
+
+        if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) {
+          $this->privCloseFd();
+          $this->privSwapBackMagicQuotes();
+          return $v_result;
+        }
+
+        if ($v_result1 == 2) {
+          break;
+        }
+      }
+      else {
+        $v_result1 = $this->privExtractFile($v_header,
+                                        $p_path, $p_remove_path,
+                      $p_remove_all_path,
+                      $p_options);
+        if ($v_result1 < 1) {
+          $this->privCloseFd();
+          $this->privSwapBackMagicQuotes();
+          return $v_result1;
+        }
+
+        if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1)
+        {
+          $this->privCloseFd();
+          $this->privSwapBackMagicQuotes();
+
+          return $v_result;
+        }
+
+        if ($v_result1 == 2) {
+          break;
+        }
+      }
+    }
+  }
+
+  $this->privCloseFd();
+  $this->privSwapBackMagicQuotes();
+
+  return $v_result;
+}
+
+function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
+{
+  $v_result=1;
+
+  if (($v_result = $this->privReadFileHeader($v_header)) != 1)
+  {
+    return $v_result;
+  }
+
+
+  if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
+  }
+
+  if ($p_remove_all_path == true) {
+      if (($p_entry['external']&0x00000010)==0x00000010) {
+
+          $p_entry['status'] = "filtered";
+
+          return $v_result;
+      }
+
+      $p_entry['filename'] = basename($p_entry['filename']);
+  }
+
+  else if ($p_remove_path != "")
+  {
+    if (PclZipUtilPathInclusion($p_remove_path, $p_entry['filename']) == 2)
+    {
+
+      $p_entry['status'] = "filtered";
+
+      return $v_result;
+    }
+
+    $p_remove_path_size = strlen($p_remove_path);
+    if (substr($p_entry['filename'], 0, $p_remove_path_size) == $p_remove_path)
+    {
+
+      $p_entry['filename'] = substr($p_entry['filename'], $p_remove_path_size);
+
+    }
+  }
+
+  if ($p_path != '') {
+    $p_entry['filename'] = $p_path."/".$p_entry['filename'];
+  }
+  
+  if (isset($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION])) {
+    $v_inclusion
+    = PclZipUtilPathInclusion($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION],
+                              $p_entry['filename']); 
+    if ($v_inclusion == 0) {
+
+      PclZip::privErrorLog(PCLZIP_ERR_DIRECTORY_RESTRICTION,
+                         "Filename '".$p_entry['filename']."' is "
+               ."outside PCLZIP_OPT_EXTRACT_DIR_RESTRICTION");
+
+      return PclZip::errorCode();
+    }
+  }
+
+  if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
+
+    $v_local_header = array();
+    $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
+
+    eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');
+    if ($v_result == 0) {
+      $p_entry['status'] = "skipped";
+      $v_result = 1;
+    }
+    
+    if ($v_result == 2) {
+      $p_entry['status'] = "aborted";
+      $v_result = PCLZIP_ERR_USER_ABORTED;
+    }
+
+    $p_entry['filename'] = $v_local_header['filename'];
+  }
+
+
+  if ($p_entry['status'] == 'ok') {
+
+  if (file_exists($p_entry['filename']))
+  {
+
+    if (is_dir($p_entry['filename']))
+    {
+
+      $p_entry['status'] = "already_a_directory";
+      
+      if (   (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
+      && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
+
+          PclZip::privErrorLog(PCLZIP_ERR_ALREADY_A_DIRECTORY,
+                         "Filename '".$p_entry['filename']."' is "
+               ."already used by an existing directory");
+
+          return PclZip::errorCode();
+  }
+    }
+    else if (!is_writeable($p_entry['filename']))
+    {
+
+      $p_entry['status'] = "write_protected";
+
+      if (   (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
+      && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
+
+          PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL,
+                         "Filename '".$p_entry['filename']."' exists "
+               ."and is write protected");
+
+          return PclZip::errorCode();
+  }
+    }
+
+    else if (filemtime($p_entry['filename']) > $p_entry['mtime'])
+    {
+      if (   (isset($p_options[PCLZIP_OPT_REPLACE_NEWER]))
+      && ($p_options[PCLZIP_OPT_REPLACE_NEWER]===true)) {
+  }
+  else {
+          $p_entry['status'] = "newer_exist";
+
+          if (   (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
+          && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
+
+              PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL,
+                 "Newer version of '".$p_entry['filename']."' exists "
+            ."and option PCLZIP_OPT_REPLACE_NEWER is not selected");
+
+              return PclZip::errorCode();
+      }
+  }
+    }
+    else {
+    }
+  }
+
+  else {
+    if ((($p_entry['external']&0x00000010)==0x00000010) || (substr($p_entry['filename'], -1) == '/'))
+      $v_dir_to_check = $p_entry['filename'];
+    else if (!strstr($p_entry['filename'], "/"))
+      $v_dir_to_check = "";
+    else
+      $v_dir_to_check = dirname($p_entry['filename']);
+
+    if (($v_result = $this->privDirCheck($v_dir_to_check, (($p_entry['external']&0x00000010)==0x00000010))) != 1) {
+
+      $p_entry['status'] = "path_creation_fail";
+
+      $v_result = 1;
+    }
+  }
+  }
+
+  if ($p_entry['status'] == 'ok') {
+
+    if (!(($p_entry['external']&0x00000010)==0x00000010))
+    {
+      if ($p_entry['compression'] == 0) {
+
+            if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0)
+        {
+
+          $p_entry['status'] = "write_error";
+
+          return $v_result;
+        }
+
+
+        $v_size = $p_entry['compressed_size'];
+        while ($v_size != 0)
+        {
+          $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
+          $v_buffer = @fread($this->zip_fd, $v_read_size);
+
+          @fwrite($v_dest_file, $v_buffer, $v_read_size);            
+          $v_size -= $v_read_size;
+        }
+
+        fclose($v_dest_file);
+
+        touch($p_entry['filename'], $p_entry['mtime']);
+        
+
+      }
+      else {
+        if (($p_entry['flag'] & 1) == 1) {
+
+        }
+        else {
+            $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
+        }
+        
+        $v_file_content = @gzinflate($v_buffer);
+        unset($v_buffer);
+        if ($v_file_content === FALSE) {
+
+          $p_entry['status'] = "error";
+          
+          return $v_result;
+        }
+        
+        if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) {
+
+          $p_entry['status'] = "write_error";
+
+          return $v_result;
+        }
+
+        @fwrite($v_dest_file, $v_file_content, $p_entry['size']);
+        unset($v_file_content);
+
+        @fclose($v_dest_file);
+
+        @touch($p_entry['filename'], $p_entry['mtime']);
+      }
+
+      if (isset($p_options[PCLZIP_OPT_SET_CHMOD])) {
+
+        @chmod($p_entry['filename'], $p_options[PCLZIP_OPT_SET_CHMOD]);
+      }
+
+    }
+  }
+
+  if ($p_entry['status'] == "aborted") {
+    $p_entry['status'] = "skipped";
+}
+
+  elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
+
+    $v_local_header = array();
+    $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
+
+    eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);');
+
+    if ($v_result == 2) {
+      $v_result = PCLZIP_ERR_USER_ABORTED;
+    }
+  }
+
+  return $v_result;
+}
+
+function privExtractFileInOutput(&$p_entry, &$p_options)
+{
+  $v_result=1;
+
+  if (($v_result = $this->privReadFileHeader($v_header)) != 1) {
+    return $v_result;
+  }
+
+
+  if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
+  }
+
+  if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
+
+    $v_local_header = array();
+    $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
+
+    eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');
+    if ($v_result == 0) {
+      $p_entry['status'] = "skipped";
+      $v_result = 1;
+    }
+
+    if ($v_result == 2) {
+      $p_entry['status'] = "aborted";
+      $v_result = PCLZIP_ERR_USER_ABORTED;
+    }
+
+    $p_entry['filename'] = $v_local_header['filename'];
+  }
+
+
+  if ($p_entry['status'] == 'ok') {
+
+    if (!(($p_entry['external']&0x00000010)==0x00000010)) {
+      if ($p_entry['compressed_size'] == $p_entry['size']) {
+
+        $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
+
+        echo $v_buffer;
+        unset($v_buffer);
+      }
+      else {
+
+        $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
+        
+        $v_file_content = gzinflate($v_buffer);
+        unset($v_buffer);
+
+        echo $v_file_content;
+        unset($v_file_content);
+      }
+    }
+  }
+
+  if ($p_entry['status'] == "aborted") {
+    $p_entry['status'] = "skipped";
+}
+
+  elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
+
+    $v_local_header = array();
+    $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
+
+    eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);');
+
+    if ($v_result == 2) {
+      $v_result = PCLZIP_ERR_USER_ABORTED;
+    }
+  }
+
+  return $v_result;
+}
+
+function privExtractFileAsString(&$p_entry, &$p_string)
+{
+  $v_result=1;
+
+  $v_header = array();
+  if (($v_result = $this->privReadFileHeader($v_header)) != 1)
+  {
+    return $v_result;
+  }
+
+
+  if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
+  }
+
+
+  if (!(($p_entry['external']&0x00000010)==0x00000010))
+  {
+    if ($p_entry['compression'] == 0) {
+
+      $p_string = @fread($this->zip_fd, $p_entry['compressed_size']);
+    }
+    else {
+
+      $v_data = @fread($this->zip_fd, $p_entry['compressed_size']);
+      
+      if (($p_string = @gzinflate($v_data)) === FALSE) {
+      }
+    }
+
+  }
+  else {
+  }
+
+  return $v_result;
+}
+
+function privReadFileHeader(&$p_header)
+{
+  $v_result=1;
+
+  $v_binary_data = @fread($this->zip_fd, 4);
+  $v_data = unpack('Vid', $v_binary_data);
+
+  if ($v_data['id'] != 0x04034b50)
+  {
+
+    PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure');
+
+    return PclZip::errorCode();
+  }
+
+  $v_binary_data = fread($this->zip_fd, 26);
+
+  if (strlen($v_binary_data) != 26)
+  {
+    $p_header['filename'] = "";
+    $p_header['status'] = "invalid_header";
+
+    PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data));
+
+    return PclZip::errorCode();
+  }
+
+  $v_data = unpack('vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $v_binary_data);
+
+  $p_header['filename'] = fread($this->zip_fd, $v_data['filename_len']);
+
+  if ($v_data['extra_len'] != 0) {
+    $p_header['extra'] = fread($this->zip_fd, $v_data['extra_len']);
+  }
+  else {
+    $p_header['extra'] = '';
+  }
+
+  $p_header['version_extracted'] = $v_data['version'];
+  $p_header['compression'] = $v_data['compression'];
+  $p_header['size'] = $v_data['size'];
+  $p_header['compressed_size'] = $v_data['compressed_size'];
+  $p_header['crc'] = $v_data['crc'];
+  $p_header['flag'] = $v_data['flag'];
+  $p_header['filename_len'] = $v_data['filename_len'];
+
+  $p_header['mdate'] = $v_data['mdate'];
+  $p_header['mtime'] = $v_data['mtime'];
+  if ($p_header['mdate'] && $p_header['mtime'])
+  {
+    $v_hour = ($p_header['mtime'] & 0xF800) >> 11;
+    $v_minute = ($p_header['mtime'] & 0x07E0) >> 5;
+    $v_seconde = ($p_header['mtime'] & 0x001F)*2;
+
+    $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;
+    $v_month = ($p_header['mdate'] & 0x01E0) >> 5;
+    $v_day = $p_header['mdate'] & 0x001F;
+
+    $p_header['mtime'] = mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);
+
+  }
+  else
+  {
+    $p_header['mtime'] = time();
+  }
+
+
+  $p_header['stored_filename'] = $p_header['filename'];
+
+  $p_header['status'] = "ok";
+
+  return $v_result;
+}
+
+function privReadCentralFileHeader(&$p_header)
+{
+  $v_result=1;
+
+  $v_binary_data = @fread($this->zip_fd, 4);
+  $v_data = unpack('Vid', $v_binary_data);
+
+  if ($v_data['id'] != 0x02014b50)
+  {
+
+    PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure');
+
+    return PclZip::errorCode();
+  }
+
+  $v_binary_data = fread($this->zip_fd, 42);
+
+  if (strlen($v_binary_data) != 42)
+  {
+    $p_header['filename'] = "";
+    $p_header['status'] = "invalid_header";
+
+    PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data));
+
+    return PclZip::errorCode();
+  }
+
+  $p_header = unpack('vversion/vversion_extracted/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len/vcomment_len/vdisk/vinternal/Vexternal/Voffset', $v_binary_data);
+
+  if ($p_header['filename_len'] != 0)
+    $p_header['filename'] = fread($this->zip_fd, $p_header['filename_len']);
+  else
+    $p_header['filename'] = '';
+
+  if ($p_header['extra_len'] != 0)
+    $p_header['extra'] = fread($this->zip_fd, $p_header['extra_len']);
+  else
+    $p_header['extra'] = '';
+
+  if ($p_header['comment_len'] != 0)
+    $p_header['comment'] = fread($this->zip_fd, $p_header['comment_len']);
+  else
+    $p_header['comment'] = '';
+
+
+  if (1)
+  {
+    $v_hour = ($p_header['mtime'] & 0xF800) >> 11;
+    $v_minute = ($p_header['mtime'] & 0x07E0) >> 5;
+    $v_seconde = ($p_header['mtime'] & 0x001F)*2;
+
+    $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;
+    $v_month = ($p_header['mdate'] & 0x01E0) >> 5;
+    $v_day = $p_header['mdate'] & 0x001F;
+
+    $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);
+
+  }
+  else
+  {
+    $p_header['mtime'] = time();
+  }
+
+  $p_header['stored_filename'] = $p_header['filename'];
+
+  $p_header['status'] = 'ok';
+
+  if (substr($p_header['filename'], -1) == '/') {
+    $p_header['external'] = 0x00000010;
+  }
+
+
+  return $v_result;
+}
+
+function privCheckFileHeaders(&$p_local_header, &$p_central_header)
+{
+  $v_result=1;
+
+    if ($p_local_header['filename'] != $p_central_header['filename']) {
+}
+if ($p_local_header['version_extracted'] != $p_central_header['version_extracted']) {
+}
+if ($p_local_header['flag'] != $p_central_header['flag']) {
+}
+if ($p_local_header['compression'] != $p_central_header['compression']) {
+}
+if ($p_local_header['mtime'] != $p_central_header['mtime']) {
+}
+if ($p_local_header['filename_len'] != $p_central_header['filename_len']) {
+}
+
+  if (($p_local_header['flag'] & 8) == 8) {
+      $p_local_header['size'] = $p_central_header['size'];
+      $p_local_header['compressed_size'] = $p_central_header['compressed_size'];
+      $p_local_header['crc'] = $p_central_header['crc'];
+}
+
+  return $v_result;
+}
+
+function privReadEndCentralDir(&$p_central_dir)
+{
+  $v_result=1;
+
+  $v_size = filesize($this->zipname);
+  @fseek($this->zip_fd, $v_size);
+  if (@ftell($this->zip_fd) != $v_size)
+  {
+    PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to go to the end of the archive \''.$this->zipname.'\'');
+
+    return PclZip::errorCode();
+  }
+
+  $v_found = 0;
+  if ($v_size > 26) {
+    @fseek($this->zip_fd, $v_size-22);
+    if (($v_pos = @ftell($this->zip_fd)) != ($v_size-22))
+    {
+      PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\'');
+
+      return PclZip::errorCode();
+    }
+
+    $v_binary_data = @fread($this->zip_fd, 4);
+    $v_data = @unpack('Vid', $v_binary_data);
+
+    if ($v_data['id'] == 0x06054b50) {
+      $v_found = 1;
+    }
+
+    $v_pos = ftell($this->zip_fd);
+  }
+
+  if (!$v_found) {
+    $v_maximum_size = 65557;      if ($v_maximum_size > $v_size)
+      $v_maximum_size = $v_size;
+    @fseek($this->zip_fd, $v_size-$v_maximum_size);
+    if (@ftell($this->zip_fd) != ($v_size-$v_maximum_size))
+    {
+      PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\'');
+
+      return PclZip::errorCode();
+    }
+
+    $v_pos = ftell($this->zip_fd);
+    $v_bytes = 0x00000000;
+    while ($v_pos < $v_size)
+    {
+      $v_byte = @fread($this->zip_fd, 1);
+
+      $v_bytes = ($v_bytes << 8) | Ord($v_byte);
+
+      if ($v_bytes == 0x504b0506)
+      {
+        $v_pos++;
+        break;
+      }
+
+      $v_pos++;
+    }
+
+    if ($v_pos == $v_size)
+    {
+
+      PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Unable to find End of Central Dir Record signature");
+
+      return PclZip::errorCode();
+    }
+  }
+
+  $v_binary_data = fread($this->zip_fd, 18);
+
+  if (strlen($v_binary_data) != 18)
+  {
+
+    PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid End of Central Dir Record size : ".strlen($v_binary_data));
+
+    return PclZip::errorCode();
+  }
+
+  $v_data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $v_binary_data);
+
+  if (($v_pos + $v_data['comment_size'] + 18) != $v_size) {
+
+          if (0) {
+    PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT,
+                       'The central dir is not at the end of the archive.'
+             .' Some trailing bytes exists after the archive.');
+
+    return PclZip::errorCode();
+  }
+  }
+
+  if ($v_data['comment_size'] != 0) {
+    $p_central_dir['comment'] = fread($this->zip_fd, $v_data['comment_size']);
+  }
+  else
+    $p_central_dir['comment'] = '';
+
+  $p_central_dir['entries'] = $v_data['entries'];
+  $p_central_dir['disk_entries'] = $v_data['disk_entries'];
+  $p_central_dir['offset'] = $v_data['offset'];
+  $p_central_dir['size'] = $v_data['size'];
+  $p_central_dir['disk'] = $v_data['disk'];
+  $p_central_dir['disk_start'] = $v_data['disk_start'];
+
+
+  return $v_result;
+}
+
+function privDeleteByRule(&$p_result_list, &$p_options)
+{
+  $v_result=1;
+  $v_list_detail = array();
+
+  if (($v_result=$this->privOpenFd('rb')) != 1)
+  {
+    return $v_result;
+  }
+
+  $v_central_dir = array();
+  if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
+  {
+    $this->privCloseFd();
+    return $v_result;
+  }
+
+  @rewind($this->zip_fd);
+
+  $v_pos_entry = $v_central_dir['offset'];
+  @rewind($this->zip_fd);
+  if (@fseek($this->zip_fd, $v_pos_entry))
+  {
+    $this->privCloseFd();
+
+    PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
+
+    return PclZip::errorCode();
+  }
+
+  $v_header_list = array();
+  $j_start = 0;
+  for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++)
+  {
+
+    $v_header_list[$v_nb_extracted] = array();
+    if (($v_result = $this->privReadCentralFileHeader($v_header_list[$v_nb_extracted])) != 1)
+    {
+      $this->privCloseFd();
+
+      return $v_result;
+    }
+
+
+    $v_header_list[$v_nb_extracted]['index'] = $i;
+
+    $v_found = false;
+
+    if (   (isset($p_options[PCLZIP_OPT_BY_NAME]))
+        && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {
+
+        for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_found); $j++) {
+
+            if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") {
+
+                if (   (strlen($v_header_list[$v_nb_extracted]['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j]))
+                    && (substr($v_header_list[$v_nb_extracted]['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
+                    $v_found = true;
+                }
+                elseif (   (($v_header_list[$v_nb_extracted]['external']&0x00000010)==0x00000010)
+                        && ($v_header_list[$v_nb_extracted]['stored_filename'].'/' == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
+                    $v_found = true;
+                }
+            }
+            elseif ($v_header_list[$v_nb_extracted]['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {
+                $v_found = true;
+            }
+        }
+    }
+
+    else if (   (isset($p_options[PCLZIP_OPT_BY_EREG]))
+             && ($p_options[PCLZIP_OPT_BY_EREG] != "")) {
+
+        if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header_list[$v_nb_extracted]['stored_filename'])) {
+            $v_found = true;
+        }
+    }
+
+    else if (   (isset($p_options[PCLZIP_OPT_BY_PREG]))
+             && ($p_options[PCLZIP_OPT_BY_PREG] != "")) {
+
+        if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header_list[$v_nb_extracted]['stored_filename'])) {
+            $v_found = true;
+        }
+    }
+
+    else if (   (isset($p_options[PCLZIP_OPT_BY_INDEX]))
+             && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {
+
+        for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_found); $j++) {
+
+            if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) {
+                $v_found = true;
+            }
+            if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {
+                $j_start = $j+1;
+            }
+
+            if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) {
+                break;
+            }
+        }
+    }
+    else {
+      $v_found = true;
+    }
+
+    if ($v_found)
+    {
+      unset($v_header_list[$v_nb_extracted]);
+    }
+    else
+    {
+      $v_nb_extracted++;
+    }
+  }
+
+  if ($v_nb_extracted > 0) {
+
+      $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
+
+      $v_temp_zip = new PclZip($v_zip_temp_name);
+
+      if (($v_result = $v_temp_zip->privOpenFd('wb')) != 1) {
+          $this->privCloseFd();
+
+          return $v_result;
+      }
+
+      for ($i=0; $i<sizeof($v_header_list); $i++) {
+
+          @rewind($this->zip_fd);
+          if (@fseek($this->zip_fd,  $v_header_list[$i]['offset'])) {
+              $this->privCloseFd();
+              $v_temp_zip->privCloseFd();
+              @unlink($v_zip_temp_name);
+
+              PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
+
+              return PclZip::errorCode();
+          }
+
+          $v_local_header = array();
+          if (($v_result = $this->privReadFileHeader($v_local_header)) != 1) {
+              $this->privCloseFd();
+              $v_temp_zip->privCloseFd();
+              @unlink($v_zip_temp_name);
+
+              return $v_result;
+          }
+          
+          if ($this->privCheckFileHeaders($v_local_header,
+                                    $v_header_list[$i]) != 1) {
+          }
+          unset($v_local_header);
+
+          if (($v_result = $v_temp_zip->privWriteFileHeader($v_header_list[$i])) != 1) {
+              $this->privCloseFd();
+              $v_temp_zip->privCloseFd();
+              @unlink($v_zip_temp_name);
+
+              return $v_result;
+          }
+
+          if (($v_result = PclZipUtilCopyBlock($this->zip_fd, $v_temp_zip->zip_fd, $v_header_list[$i]['compressed_size'])) != 1) {
+              $this->privCloseFd();
+              $v_temp_zip->privCloseFd();
+              @unlink($v_zip_temp_name);
+
+              return $v_result;
+          }
+      }
+
+      $v_offset = @ftell($v_temp_zip->zip_fd);
+
+      for ($i=0; $i<sizeof($v_header_list); $i++) {
+          if (($v_result = $v_temp_zip->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
+              $v_temp_zip->privCloseFd();
+              $this->privCloseFd();
+              @unlink($v_zip_temp_name);
+
+              return $v_result;
+          }
+
+          $v_temp_zip->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
+      }
+
+
+      $v_comment = '';
+      if (isset($p_options[PCLZIP_OPT_COMMENT])) {
+        $v_comment = $p_options[PCLZIP_OPT_COMMENT];
+      }
+
+      $v_size = @ftell($v_temp_zip->zip_fd)-$v_offset;
+
+      if (($v_result = $v_temp_zip->privWriteCentralHeader(sizeof($v_header_list), $v_size, $v_offset, $v_comment)) != 1) {
+          unset($v_header_list);
+          $v_temp_zip->privCloseFd();
+          $this->privCloseFd();
+          @unlink($v_zip_temp_name);
+
+          return $v_result;
+      }
+
+      $v_temp_zip->privCloseFd();
+      $this->privCloseFd();
+
+      @unlink($this->zipname);
+
+      PclZipUtilRename($v_zip_temp_name, $this->zipname);
+  
+      unset($v_temp_zip);
+  }
+  
+  else if ($v_central_dir['entries'] != 0) {
+      $this->privCloseFd();
+
+      if (($v_result = $this->privOpenFd('wb')) != 1) {
+        return $v_result;
+      }
+
+      if (($v_result = $this->privWriteCentralHeader(0, 0, 0, '')) != 1) {
+        return $v_result;
+      }
+
+      $this->privCloseFd();
+  }
+
+  return $v_result;
+}
+
+function privDirCheck($p_dir, $p_is_dir=false)
+{
+  $v_result = 1;
+
+
+  if (($p_is_dir) && (substr($p_dir, -1)=='/'))
+  {
+    $p_dir = substr($p_dir, 0, strlen($p_dir)-1);
+  }
+
+  if ((is_dir($p_dir)) || ($p_dir == ""))
+  {
+    return 1;
+  }
+
+  $p_parent_dir = dirname($p_dir);
+
+  if ($p_parent_dir != $p_dir)
+  {
+    if ($p_parent_dir != "")
+    {
+      if (($v_result = $this->privDirCheck($p_parent_dir)) != 1)
+      {
+        return $v_result;
+      }
+    }
+  }
+
+  if (!@mkdir($p_dir, 0777))
+  {
+    PclZip::privErrorLog(PCLZIP_ERR_DIR_CREATE_FAIL, "Unable to create directory '$p_dir'");
+
+    return PclZip::errorCode();
+  }
+
+  return $v_result;
+}
+
+function privMerge(&$p_archive_to_add)
+{
+  $v_result=1;
+
+  if (!is_file($p_archive_to_add->zipname))
+  {
+
+    $v_result = 1;
+
+    return $v_result;
+  }
+
+  if (!is_file($this->zipname))
+  {
+
+    $v_result = $this->privDuplicate($p_archive_to_add->zipname);
+
+    return $v_result;
+  }
+
+  if (($v_result=$this->privOpenFd('rb')) != 1)
+  {
+    return $v_result;
+  }
+
+  $v_central_dir = array();
+  if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
+  {
+    $this->privCloseFd();
+    return $v_result;
+  }
+
+  @rewind($this->zip_fd);
+
+  if (($v_result=$p_archive_to_add->privOpenFd('rb')) != 1)
+  {
+    $this->privCloseFd();
+
+    return $v_result;
+  }
+
+  $v_central_dir_to_add = array();
+  if (($v_result = $p_archive_to_add->privReadEndCentralDir($v_central_dir_to_add)) != 1)
+  {
+    $this->privCloseFd();
+    $p_archive_to_add->privCloseFd();
+
+    return $v_result;
+  }
+
+  @rewind($p_archive_to_add->zip_fd);
+
+  $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
+
+  if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0)
+  {
+    $this->privCloseFd();
+    $p_archive_to_add->privCloseFd();
+
+    PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode');
+
+    return PclZip::errorCode();
+  }
+
+  $v_size = $v_central_dir['offset'];
+  while ($v_size != 0)
+  {
+    $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
+    $v_buffer = fread($this->zip_fd, $v_read_size);
+    @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
+    $v_size -= $v_read_size;
+  }
+
+  $v_size = $v_central_dir_to_add['offset'];
+  while ($v_size != 0)
+  {
+    $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
+    $v_buffer = fread($p_archive_to_add->zip_fd, $v_read_size);
+    @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
+    $v_size -= $v_read_size;
+  }
+
+  $v_offset = @ftell($v_zip_temp_fd);
+
+  $v_size = $v_central_dir['size'];
+  while ($v_size != 0)
+  {
+    $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
+    $v_buffer = @fread($this->zip_fd, $v_read_size);
+    @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
+    $v_size -= $v_read_size;
+  }
+
+  $v_size = $v_central_dir_to_add['size'];
+  while ($v_size != 0)
+  {
+    $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
+    $v_buffer = @fread($p_archive_to_add->zip_fd, $v_read_size);
+    @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
+    $v_size -= $v_read_size;
+  }
+
+  $v_comment = $v_central_dir['comment'].' '.$v_central_dir_to_add['comment'];
+
+  $v_size = @ftell($v_zip_temp_fd)-$v_offset;
+
+  $v_swap = $this->zip_fd;
+  $this->zip_fd = $v_zip_temp_fd;
+  $v_zip_temp_fd = $v_swap;
+
+  if (($v_result = $this->privWriteCentralHeader($v_central_dir['entries']+$v_central_dir_to_add['entries'], $v_size, $v_offset, $v_comment)) != 1)
+  {
+    $this->privCloseFd();
+    $p_archive_to_add->privCloseFd();
+    @fclose($v_zip_temp_fd);
+    $this->zip_fd = null;
+
+    unset($v_header_list);
+
+    return $v_result;
+  }
+
+  $v_swap = $this->zip_fd;
+  $this->zip_fd = $v_zip_temp_fd;
+  $v_zip_temp_fd = $v_swap;
+
+  $this->privCloseFd();
+  $p_archive_to_add->privCloseFd();
+
+  @fclose($v_zip_temp_fd);
+
+  @unlink($this->zipname);
+
+  PclZipUtilRename($v_zip_temp_name, $this->zipname);
+
+  return $v_result;
+}
+
+function privDuplicate($p_archive_filename)
+{
+  $v_result=1;
+
+  if (!is_file($p_archive_filename))
+  {
+
+    $v_result = 1;
+
+    return $v_result;
+  }
+
+  if (($v_result=$this->privOpenFd('wb')) != 1)
+  {
+    return $v_result;
+  }
+
+  if (($v_zip_temp_fd = @fopen($p_archive_filename, 'rb')) == 0)
+  {
+    $this->privCloseFd();
+
+    PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive file \''.$p_archive_filename.'\' in binary write mode');
+
+    return PclZip::errorCode();
+  }
+
+  $v_size = filesize($p_archive_filename);
+  while ($v_size != 0)
+  {
+    $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
+    $v_buffer = fread($v_zip_temp_fd, $v_read_size);
+    @fwrite($this->zip_fd, $v_buffer, $v_read_size);
+    $v_size -= $v_read_size;
+  }
+
+  $this->privCloseFd();
+
+  @fclose($v_zip_temp_fd);
+
+  return $v_result;
+}
+
+function privErrorLog($p_error_code=0, $p_error_string='')
+{
+  if (PCLZIP_ERROR_EXTERNAL == 1) {
+    PclError($p_error_code, $p_error_string);
+  }
+  else {
+    $this->error_code = $p_error_code;
+    $this->error_string = $p_error_string;
+  }
+}
+
+function privErrorReset()
+{
+  if (PCLZIP_ERROR_EXTERNAL == 1) {
+    PclErrorReset();
+  }
+  else {
+    $this->error_code = 0;
+    $this->error_string = '';
+  }
+}
+
+function privDecrypt($p_encryption_header, &$p_buffer, $p_size, $p_crc)
+{
+  $v_result=1;
+  
+  $v_pwd = "test";
+  
+  $p_buffer = PclZipUtilZipDecrypt($p_buffer, $p_size, $p_encryption_header,
+                                 $p_crc, $v_pwd);
+  
+  return $v_result;
+}
+
+function privDisableMagicQuotes()
+{
+  $v_result=1;
+
+  if (   (!function_exists("get_magic_quotes_runtime"))
+    || (!function_exists("set_magic_quotes_runtime"))) {
+    return $v_result;
+}
+
+  if ($this->magic_quotes_status != -1) {
+    return $v_result;
+}
+
+  $this->magic_quotes_status = @get_magic_quotes_runtime();
+
+  if ($this->magic_quotes_status == 1) {
+  @set_magic_quotes_runtime(0);
+}
+
+  return $v_result;
+}
+
+function privSwapBackMagicQuotes()
+{
+  $v_result=1;
+
+  if (   (!function_exists("get_magic_quotes_runtime"))
+    || (!function_exists("set_magic_quotes_runtime"))) {
+    return $v_result;
+}
+
+  if ($this->magic_quotes_status != -1) {
+    return $v_result;
+}
+
+  if ($this->magic_quotes_status == 1) {
+    @set_magic_quotes_runtime($this->magic_quotes_status);
+}
+
+  return $v_result;
+}
+
+}
+
+function PclZipUtilPathReduction($p_dir)
+{
+  $v_result = "";
+
+  if ($p_dir != "") {
+    $v_list = explode("/", $p_dir);
+
+    $v_skip = 0;
+    for ($i=sizeof($v_list)-1; $i>=0; $i--) {
+      if ($v_list[$i] == ".") {
+      }
+      else if ($v_list[$i] == "..") {
+    $v_skip++;
+      }
+      else if ($v_list[$i] == "") {
+        if ($i == 0) {
+          $v_result = "/".$v_result;
+      if ($v_skip > 0) {
+                  $v_result = $p_dir;
+              $v_skip = 0;
+      }
+    }
+        else if ($i == (sizeof($v_list)-1)) {
+          $v_result = $v_list[$i];
+    }
+        else {
+    }
+      }
+      else {
+        if ($v_skip > 0) {
+      $v_skip--;
+    }
+    else {
+          $v_result = $v_list[$i].($i!=(sizeof($v_list)-1)?"/".$v_result:"");
+    }
+      }
+    }
+    
+    if ($v_skip > 0) {
+      while ($v_skip > 0) {
+          $v_result = '../'.$v_result;
+          $v_skip--;
+      }
+    }
+  }
+
+  return $v_result;
+}
+
+function PclZipUtilPathInclusion($p_dir, $p_path)
+{
+  $v_result = 1;
+  
+  if (   ($p_dir == '.')
+      || ((strlen($p_dir) >=2) && (substr($p_dir, 0, 2) == './'))) {
+    $p_dir = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_dir, 1);
+  }
+  if (   ($p_path == '.')
+      || ((strlen($p_path) >=2) && (substr($p_path, 0, 2) == './'))) {
+    $p_path = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_path, 1);
+  }
+
+  $v_list_dir = explode("/", $p_dir);
+  $v_list_dir_size = sizeof($v_list_dir);
+  $v_list_path = explode("/", $p_path);
+  $v_list_path_size = sizeof($v_list_path);
+
+  $i = 0;
+  $j = 0;
+  while (($i < $v_list_dir_size) && ($j < $v_list_path_size) && ($v_result)) {
+
+    if ($v_list_dir[$i] == '') {
+      $i++;
+      continue;
+    }
+    if ($v_list_path[$j] == '') {
+      $j++;
+      continue;
+    }
+
+    if (($v_list_dir[$i] != $v_list_path[$j]) && ($v_list_dir[$i] != '') && ( $v_list_path[$j] != ''))  {
+      $v_result = 0;
+    }
+
+    $i++;
+    $j++;
+  }
+
+  if ($v_result) {
+    while (($j < $v_list_path_size) && ($v_list_path[$j] == '')) $j++;
+    while (($i < $v_list_dir_size) && ($v_list_dir[$i] == '')) $i++;
+
+    if (($i >= $v_list_dir_size) && ($j >= $v_list_path_size)) {
+      $v_result = 2;
+    }
+    else if ($i < $v_list_dir_size) {
+      $v_result = 0;
+    }
+  }
+
+  return $v_result;
+}
+
+function PclZipUtilCopyBlock($p_src, $p_dest, $p_size, $p_mode=0)
+{
+  $v_result = 1;
+
+  if ($p_mode==0)
+  {
+    while ($p_size != 0)
+    {
+      $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
+      $v_buffer = @fread($p_src, $v_read_size);
+      @fwrite($p_dest, $v_buffer, $v_read_size);
+      $p_size -= $v_read_size;
+    }
+  }
+  else if ($p_mode==1)
+  {
+    while ($p_size != 0)
+    {
+      $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
+      $v_buffer = @gzread($p_src, $v_read_size);
+      @fwrite($p_dest, $v_buffer, $v_read_size);
+      $p_size -= $v_read_size;
+    }
+  }
+  else if ($p_mode==2)
+  {
+    while ($p_size != 0)
+    {
+      $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
+      $v_buffer = @fread($p_src, $v_read_size);
+      @gzwrite($p_dest, $v_buffer, $v_read_size);
+      $p_size -= $v_read_size;
+    }
+  }
+  else if ($p_mode==3)
+  {
+    while ($p_size != 0)
+    {
+      $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
+      $v_buffer = @gzread($p_src, $v_read_size);
+      @gzwrite($p_dest, $v_buffer, $v_read_size);
+      $p_size -= $v_read_size;
+    }
+  }
+
+  return $v_result;
+}
+
+function PclZipUtilRename($p_src, $p_dest)
+{
+  $v_result = 1;
+
+  if (!@rename($p_src, $p_dest)) {
+
+    if (!@copy($p_src, $p_dest)) {
+      $v_result = 0;
+    }
+    else if (!@unlink($p_src)) {
+      $v_result = 0;
+    }
+  }
+
+  return $v_result;
+}
+
+function PclZipUtilOptionText($p_option)
+{
+  
+  $v_list = get_defined_constants();
+  for (reset($v_list); $v_key = key($v_list); next($v_list)) {
+  $v_prefix = substr($v_key, 0, 10);
+  if ((   ($v_prefix == 'PCLZIP_OPT')
+       || ($v_prefix == 'PCLZIP_CB_')
+       || ($v_prefix == 'PCLZIP_ATT'))
+      && ($v_list[$v_key] == $p_option)) {
+        return $v_key;
+    }
+  }
+  
+  $v_result = 'Unknown';
+
+  return $v_result;
+}
+
+function PclZipUtilTranslateWinPath($p_path, $p_remove_disk_letter=true)
+{
+  if (stristr(php_uname(), 'windows')) {
+    if (($p_remove_disk_letter) && (($v_position = strpos($p_path, ':')) != false)) {
+        $p_path = substr($p_path, $v_position+1);
+    }
+    if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0,1) == '\\')) {
+        $p_path = strtr($p_path, '\\', '/');
+    }
+  }
+  return $p_path;
+}
+?>
Index: /tags/2.0.2/admin/include/plugins.class.php
===================================================================
--- /tags/2.0.2/admin/include/plugins.class.php	(revision 3278)
+++ /tags/2.0.2/admin/include/plugins.class.php	(revision 3278)
@@ -0,0 +1,546 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+class plugins
+{
+  var $fs_plugins = array();
+  var $db_plugins_by_id = array();
+  var $server_plugins = array();
+
+  /**
+   * Initialize $fs_plugins and $db_plugins_by_id
+  */
+  function plugins()
+  {
+    $this->get_fs_plugins();
+
+    foreach (get_db_plugins() as $db_plugin)
+    {
+      $this->db_plugins_by_id[$db_plugin['id']] = $db_plugin;
+    }
+  }
+
+ /**
+   * Perform requested actions
+  *  @param string - action
+  * @param string - plugin id
+  * @param array - errors
+  */
+  function perform_action($action, $plugin_id)
+  {
+    if (isset($this->db_plugins_by_id[$plugin_id]))
+    {
+      $crt_db_plugin = $this->db_plugins_by_id[$plugin_id];
+    }
+    $file_to_include = PHPWG_PLUGINS_PATH . $plugin_id . '/maintain.inc.php';
+
+    $errors = array();
+
+    switch ($action)
+    {
+      case 'install':
+        if (!empty($crt_db_plugin))
+        {
+          array_push($errors, 'CANNOT INSTALL - ALREADY INSTALLED');
+          break;
+        }
+        if (!isset($this->fs_plugins[$plugin_id]))
+        {
+          array_push($errors, 'CANNOT INSTALL - NO SUCH PLUGIN');
+          break;
+        }
+        if (file_exists($file_to_include))
+        {
+          include_once($file_to_include);
+          if (function_exists('plugin_install'))
+          {
+            plugin_install($plugin_id, $this->fs_plugins[$plugin_id]['version'], $errors);
+          }
+        }
+        if (empty($errors))
+        {
+          $query = '
+INSERT INTO ' . PLUGINS_TABLE . ' (id,version) VALUES ("'
+. $plugin_id . '","' . $this->fs_plugins[$plugin_id]['version'] . '"
+)';
+          pwg_query($query);
+        }
+        break;
+
+      case 'activate':
+        if (!isset($crt_db_plugin))
+        {
+          array_push($errors, 'CANNOT ACTIVATE - NOT INSTALLED');
+          break;
+        }
+        if ($crt_db_plugin['state'] != 'inactive')
+        {
+          array_push($errors, 'invalid current state ' . $crt_db_plugin['state']);
+          break;
+        }
+        if (file_exists($file_to_include))
+        {
+          include_once($file_to_include);
+          if (function_exists('plugin_activate'))
+          {
+            plugin_activate($plugin_id, $crt_db_plugin['version'], $errors);
+          }
+        }
+        if (empty($errors))
+        {
+          $query = '
+UPDATE ' . PLUGINS_TABLE . '
+SET state="active", version="'.$this->fs_plugins[$plugin_id]['version'].'"
+WHERE id="' . $plugin_id . '"';
+          pwg_query($query);
+        }
+        break;
+
+      case 'deactivate':
+        if (!isset($crt_db_plugin))
+        {
+          die ('CANNOT DEACTIVATE - NOT INSTALLED');
+        }
+        if ($crt_db_plugin['state'] != 'active')
+        {
+          die('invalid current state ' . $crt_db_plugin['state']);
+        }
+        $query = '
+UPDATE ' . PLUGINS_TABLE . ' SET state="inactive" WHERE id="' . $plugin_id . '"';
+        pwg_query($query);
+        if (file_exists($file_to_include))
+        {
+          include_once($file_to_include);
+          if (function_exists('plugin_deactivate'))
+          {
+            plugin_deactivate($plugin_id);
+          }
+        }
+        break;
+
+      case 'uninstall':
+        if (!isset($crt_db_plugin))
+        {
+          die ('CANNOT UNINSTALL - NOT INSTALLED');
+        }
+        $query = '
+DELETE FROM ' . PLUGINS_TABLE . ' WHERE id="' . $plugin_id . '"';
+        pwg_query($query);
+        if (file_exists($file_to_include))
+        {
+          include_once($file_to_include);
+          if (function_exists('plugin_uninstall'))
+          {
+            plugin_uninstall($plugin_id);
+          }
+        }
+        break;
+
+      case 'delete':
+        if (!empty($crt_db_plugin))
+        {
+          array_push($errors, 'CANNOT DELETE - PLUGIN IS INSTALLED');
+          break;
+        }
+        if (!isset($this->fs_plugins[$plugin_id]))
+        {
+          array_push($errors, 'CANNOT DELETE - NO SUCH PLUGIN');
+          break;
+        }
+        if (!$this->deltree(PHPWG_PLUGINS_PATH . $plugin_id))
+        {
+          $this->send_to_trash(PHPWG_PLUGINS_PATH . $plugin_id);
+        }
+        break;
+    }
+    return $errors;
+  }
+
+  /**
+  *  Get plugins defined in the plugin directory
+  */  
+  function get_fs_plugins()
+  {
+    $dir = opendir(PHPWG_PLUGINS_PATH);
+    while ($file = readdir($dir))
+    {
+      if ($file!='.' and $file!='..')
+      {
+        $path = PHPWG_PLUGINS_PATH.$file;
+        if (is_dir($path) and !is_link($path)
+            and preg_match('/^[a-zA-Z0-9-_]+$/', $file )
+            and file_exists($path.'/main.inc.php')
+            )
+        {
+          $plugin = array(
+              'name'=>$file,
+              'version'=>'0',
+              'uri'=>'',
+              'description'=>'',
+              'author'=>'',
+            );
+          $plg_data = implode( '', file($path.'/main.inc.php') );
+
+          if ( preg_match("|Plugin Name: (.*)|", $plg_data, $val) )
+          {
+            $plugin['name'] = trim( $val[1] );
+          }
+          if (preg_match("|Version: (.*)|", $plg_data, $val))
+          {
+            $plugin['version'] = trim($val[1]);
+          }
+          if ( preg_match("|Plugin URI: (.*)|", $plg_data, $val) )
+          {
+            $plugin['uri'] = trim($val[1]);
+          }
+          if ( preg_match("|Description: (.*)|", $plg_data, $val) )
+          {
+            $plugin['description'] = trim($val[1]);
+          }
+          if ( preg_match("|Author: (.*)|", $plg_data, $val) )
+          {
+            $plugin['author'] = trim($val[1]);
+          }
+          if ( preg_match("|Author URI: (.*)|", $plg_data, $val) )
+          {
+            $plugin['author uri'] = trim($val[1]);
+          }
+          if (!empty($plugin['uri']) and strpos($plugin['uri'] , 'extension_view.php?eid='))
+          {
+            list( , $extension) = explode('extension_view.php?eid=', $plugin['uri']);
+            if (is_numeric($extension)) $plugin['extension'] = $extension;
+          }
+          // IMPORTANT SECURITY !
+          $plugin = array_map('htmlspecialchars', $plugin);
+          $this->fs_plugins[$file] = $plugin;
+        }
+      }
+    }
+    closedir($dir);
+  }
+
+  /**
+   * Sort fs_plugins
+   */
+  function sort_fs_plugins($order='name')
+  {
+    switch ($order)
+    {
+      case 'name':
+        uasort($this->fs_plugins, 'name_compare');
+        break;
+      case 'status':
+        $this->sort_plugins_by_state();
+        break;
+      case 'author':
+        uasort($this->fs_plugins, array($this, 'plugin_author_compare'));
+        break;
+      case 'id':
+        uksort($this->fs_plugins, 'strcasecmp');
+        break;
+    }
+  }
+
+  /**
+   * Retrieve PEM server datas to $server_plugins
+   */
+  function get_server_plugins($new=false)
+  {
+    global $user;
+
+    // Retrieve PEM versions
+    $version = PHPWG_VERSION;
+    $versions_to_check = array();
+    $url = PEM_URL . '/api/get_version_list.php?category_id=12&format=php';
+    if (fetchRemote($url, $result) and $pem_versions = @unserialize($result))
+    {
+      if (!preg_match('/^\d+\.\d+\.\d+/', $version))
+      {
+        $version = $pem_versions[0]['name'];
+      }
+      $branch = substr($version, 0, strrpos($version, '.'));
+      foreach ($pem_versions as $pem_version)
+      {
+        if (strpos($pem_version['name'], $branch) === 0)
+        {
+          $versions_to_check[] = $pem_version['id'];
+        }
+      }
+    }
+    if (empty($versions_to_check))
+    {
+      return false;
+    }
+
+    // Plugins to check
+    $plugins_to_check = array();
+    foreach($this->fs_plugins as $fs_plugin)
+    {
+      if (isset($fs_plugin['extension']))
+      {
+        $plugins_to_check[] = $fs_plugin['extension'];
+      }
+    }
+
+    // Retrieve PEM plugins infos
+    $url = PEM_URL . '/api/get_revision_list.php?category_id=12&format=php&last_revision_only=true';
+    $url .= '&version=' . implode(',', $versions_to_check);
+    $url .= '&lang=' . substr($user['language'], 0, 2);
+    $url .= '&get_nb_downloads=true';
+
+    if (!empty($plugins_to_check))
+    {
+      $url .= $new ? '&extension_exclude=' : '&extension_include=';
+      $url .= implode(',', $plugins_to_check);
+    }
+    if (fetchRemote($url, $result))
+    {
+      $pem_plugins = @unserialize($result);
+      if (!is_array($pem_plugins))
+      {
+        return false;
+      }
+      foreach ($pem_plugins as $plugin)
+      {
+        $this->server_plugins[$plugin['extension_id']] = $plugin;
+      }
+      return true;
+    }
+    return false;
+  }
+  
+  /**
+   * Sort $server_plugins
+   */
+  function sort_server_plugins($order='date')
+  {
+    switch ($order)
+    {
+      case 'date':
+        krsort($this->server_plugins);
+        break;
+      case 'revision':
+        usort($this->server_plugins, array($this, 'extension_revision_compare'));
+        break;
+      case 'name':
+        uasort($this->server_plugins, array($this, 'extension_name_compare'));
+        break;
+      case 'author':
+        uasort($this->server_plugins, array($this, 'extension_author_compare'));
+        break;
+      case 'downloads':
+        usort($this->server_plugins, array($this, 'extension_downloads_compare'));
+        break;
+    }
+  }
+
+  /**
+   * Extract plugin files from archive
+   * @param string - install or upgrade
+   *  @param string - archive URL
+    * @param string - plugin id or extension id
+   */
+  function extract_plugin_files($action, $revision, $dest)
+  {
+    if ($archive = tempnam( PHPWG_PLUGINS_PATH, 'zip'))
+    {
+      $url = PEM_URL . '/download.php?rid=' . $revision;
+      $url .= '&origin=piwigo_' . $action;
+
+      if ($handle = @fopen($archive, 'wb') and fetchRemote($url, $handle))
+      {
+        fclose($handle);
+        include(PHPWG_ROOT_PATH.'admin/include/pclzip.lib.php');
+        $zip = new PclZip($archive);
+        if ($list = $zip->listContent())
+        {
+          foreach ($list as $file)
+          {
+            // we search main.inc.php in archive
+            if (basename($file['filename']) == 'main.inc.php'
+              and (!isset($main_filepath)
+              or strlen($file['filename']) < strlen($main_filepath)))
+            {
+              $main_filepath = $file['filename'];
+            }
+          }
+          if (isset($main_filepath))
+          {
+            $root = dirname($main_filepath); // main.inc.php path in archive
+            if ($action == 'upgrade')
+            {
+              $extract_path = PHPWG_PLUGINS_PATH . $dest;
+            }
+            else
+            {
+              $extract_path = PHPWG_PLUGINS_PATH
+                  . ($root == '.' ? 'extension_' . $dest : basename($root));
+            }
+            if($result = $zip->extract(PCLZIP_OPT_PATH, $extract_path,
+                                       PCLZIP_OPT_REMOVE_PATH, $root,
+                                       PCLZIP_OPT_REPLACE_NEWER))
+            {
+              foreach ($result as $file)
+              {
+                if ($file['stored_filename'] == $main_filepath)
+                {
+                  $status = $file['status'];
+                  break;
+                }
+              }
+            }
+            else $status = 'extract_error';
+          }
+          else $status = 'archive_error';
+        }
+        else $status = 'archive_error';
+      }
+      else $status = 'dl_archive_error';
+    }
+    else $status = 'temp_path_error';
+
+    @unlink($archive);
+    return $status;
+  }
+  
+  /**
+   * delete $path directory
+   * @param string - path
+   */
+  function deltree($path)
+  {
+    if (is_dir($path))
+    {
+      $fh = opendir($path);
+      while ($file = readdir($fh))
+      {
+        if ($file != '.' and $file != '..')
+        {
+          $pathfile = $path . '/' . $file;
+          if (is_dir($pathfile))
+          {
+            $this->deltree($pathfile);
+          }
+          else
+          {
+            @unlink($pathfile);
+          }
+        }
+      }
+      closedir($fh);
+      return @rmdir($path);
+    }
+  }
+
+  /**
+   * send $path to trash directory
+   * @param string - path
+   */
+  function send_to_trash($path)
+  {
+    $trash_path = PHPWG_PLUGINS_PATH . 'trash';
+    if (!is_dir($trash_path))
+    {
+      @mkdir($trash_path);
+      $file = @fopen($trash_path . '/.htaccess', 'w');
+      @fwrite($file, 'deny from all');
+      @fclose($file);
+    }
+    while ($r = $trash_path . '/' . md5(uniqid(rand(), true)))
+    {
+      if (!is_dir($r))
+      {
+        @rename($path, $r);
+        break;
+      }
+    }
+  }
+
+  /**
+   * Sort functions
+   */
+  function plugin_version_compare($a, $b)
+  {
+    $pattern = array('/([a-z])/ei', '/\.+/', '/\.\Z|\A\./');
+    $replacement = array( "'.'.intval('\\1', 36).'.'", '.', '');
+
+    $array = preg_replace($pattern, $replacement, array($a, $b));
+
+    return version_compare($array[0], $array[1], '>=');
+  }
+
+  function extension_revision_compare($a, $b)
+  {
+    if ($a['revision_date'] < $b['revision_date']) return 1;
+    else return -1;
+  }
+
+  function extension_name_compare($a, $b)
+  {
+    return strcmp(strtolower($a['extension_name']), strtolower($b['extension_name']));
+  }
+
+  function extension_author_compare($a, $b)
+  {
+    $r = strcasecmp($a['author_name'], $b['author_name']);
+    if ($r == 0) return $this->extension_name_compare($a, $b);
+    else return $r;
+  }
+
+  function plugin_author_compare($a, $b)
+  {
+    $r = strcasecmp($a['author'], $b['author']);
+    if ($r == 0) return name_compare($a, $b);
+    else return $r;
+  }
+
+  function extension_downloads_compare($a, $b)
+  {
+    if ($a['extension_nb_downloads'] < $b['extension_nb_downloads']) return 1;
+    else return -1;
+  }
+
+  function sort_plugins_by_state()
+  {
+    uasort($this->fs_plugins, 'name_compare');
+
+    $active_plugins = array();
+    $inactive_plugins = array();
+    $not_installed = array();
+
+    foreach($this->fs_plugins as $plugin_id => $plugin)
+    {
+      if (isset($this->db_plugins_by_id[$plugin_id]))
+      {
+        $this->db_plugins_by_id[$plugin_id]['state'] == 'active' ?
+          $active_plugins[$plugin_id] = $plugin : $inactive_plugins[$plugin_id] = $plugin;
+      }
+      else
+      {
+        $not_installed[$plugin_id] = $plugin;
+      }
+    }
+    $this->fs_plugins = $active_plugins + $inactive_plugins + $not_installed;
+  }
+}
+?>
Index: /tags/2.0.2/admin/include/tabsheet.class.php
===================================================================
--- /tags/2.0.2/admin/include/tabsheet.class.php	(revision 3278)
+++ /tags/2.0.2/admin/include/tabsheet.class.php	(revision 3278)
@@ -0,0 +1,146 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+class tabsheet
+{
+  var $sheets;
+  var $name;
+  var $titlename;
+  var $selected;
+
+  /*
+    $name is the tabsheet's name inside the template .tpl file
+    $titlename in the template is affected by $titlename value
+  */
+  function tabsheet($name = 'TABSHEET', $titlename = 'TABSHEET_TITLE')
+  {
+    $this->sheets = array();
+    $this->name = $name;
+    $this->titlename = $titlename;
+    $this->selected = "";
+  }
+
+  /*
+     add a tab
+  */
+  function add($name, $caption, $url, $selected = false)
+  {
+    if (!isset($this->sheets[$name]))
+    {
+      $this->sheets[$name] = array('caption' => $caption,
+                                   'url' => $url);
+      if($selected)
+      {
+        $this->selected=$name;
+      }
+      return true;
+    }
+    return false;
+  }
+
+  /*
+     remove a tab
+  */
+  function delete($name)
+  {
+    if (isset($this->sheets[$name]))
+    {
+      array_splice($this->sheets, $name, 1);
+
+      if ($this->selected == $name)
+      {
+        $this->selected = "";
+      }
+      return true;
+    }
+    return false;
+  }
+
+  /*
+     select a tab to be active
+  */
+  function select($name)
+  {
+    $this->selected = $name;
+  }
+
+  /*
+    set $titlename value
+  */
+  function set_titlename($titlename)
+  {
+    $this->titlename = $titlename;
+    return $this->titlename;
+  }
+
+  /*
+    returns $titlename value
+  */
+  function get_titlename()
+  {
+    return $this->titlename;
+  }
+
+  /*
+    returns properties of selected tab
+  */
+  function get_selected()
+  {
+    if (!empty($this->selected))
+    {
+      return $this->sheets[$this->selected];
+    }
+    else
+    {
+      return null;
+    }
+  }
+
+  /*
+   * Build TabSheet and assign this content to current page
+   *
+   * Fill $this->$name {default value = TABSHEET} with HTML code for tabsheet
+   * Fill $this->titlename {default value = TABSHEET_TITLE} with formated caption of the selected tab
+   */
+  function assign()
+  {
+    global $template;
+
+    $template->set_filename('tabsheet', 'tabsheet.tpl');
+    $template->assign('tabsheet', $this->sheets);
+    $template->assign('tabsheet_selected', $this->selected);
+
+    $selected_tab = $this->get_selected();
+
+    if (isset($selected_tab))
+    {
+      $template->assign(
+        array($this->titlename => '['.$selected_tab['caption'].']'));
+    }
+
+    $template->assign_var_from_handle($this->name, 'tabsheet');
+    $template->clear_assign('tabsheet');
+  }
+}
+
+?>
Index: /tags/2.0.2/admin/index.php
===================================================================
--- /tags/2.0.2/admin/index.php	(revision 3278)
+++ /tags/2.0.2/admin/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/admin/intro.php
===================================================================
--- /tags/2.0.2/admin/intro.php	(revision 3278)
+++ /tags/2.0.2/admin/intro.php	(revision 3278)
@@ -0,0 +1,283 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die ("Hacking attempt!");
+}
+
+include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+include_once(PHPWG_ROOT_PATH.'admin/include/check_integrity.class.php');
+include_once(PHPWG_ROOT_PATH.'admin/include/c13y_internal.class.php');
+
+// +-----------------------------------------------------------------------+
+// | Check Access and exit when user status is not ok                      |
+// +-----------------------------------------------------------------------+
+check_status(ACCESS_ADMINISTRATOR);
+
+// +-----------------------------------------------------------------------+
+// |                                actions                                |
+// +-----------------------------------------------------------------------+
+
+// Check for upgrade : code inspired from punbb
+if (isset($_GET['action']) and 'check_upgrade' == $_GET['action'])
+{
+  if (!fetchRemote(PHPWG_URL.'/download/latest_version', $result))
+  {
+    array_push($page['errors'], l10n('Unable to check for upgrade.'));
+  }
+  else
+  {
+    $versions = array('current' => PHPWG_VERSION);
+    $lines = @explode("\r\n", $result);
+
+    // if the current version is a BSF (development branch) build, we check
+    // the first line, for stable versions, we check the second line
+    if (preg_match('/^BSF/', $versions{'current'}))
+    {
+      $versions{'latest'} = trim($lines[0]);
+
+      // because integer are limited to 4,294,967,296 we need to split BSF
+      // versions in date.time
+      foreach ($versions as $key => $value)
+      {
+        $versions{$key} =
+          preg_replace('/BSF_(\d{8})(\d{4})/', '$1.$2', $value);
+      }
+    }
+    else
+    {
+      $versions{'latest'} = trim($lines[1]);
+    }
+
+    if ('' == $versions{'latest'})
+    {
+      array_push(
+        $page['errors'],
+        l10n('Check for upgrade failed for unknown reasons.')
+        );
+    }
+    // concatenation needed to avoid automatic transformation by release
+    // script generator
+    else if ('%'.'PWGVERSION'.'%' == $versions{'current'})
+    {
+      array_push(
+        $page['infos'],
+        l10n('You are running on development sources, no check possible.')
+        );
+    }
+    else if (version_compare($versions{'current'}, $versions{'latest'}) < 0)
+    {
+      array_push(
+        $page['infos'],
+        l10n('A new version of Piwigo is available.')
+        );
+    }
+    else
+    {
+      array_push(
+        $page['infos'],
+        l10n('You are running the latest version of Piwigo.')
+        );
+    }
+  }
+}
+// Show phpinfo() output
+else if (isset($_GET['action']) and 'phpinfo' == $_GET['action'])
+{
+  phpinfo();
+  exit();
+}
+
+// +-----------------------------------------------------------------------+
+// |                             template init                             |
+// +-----------------------------------------------------------------------+
+
+$template->set_filenames(array('intro' => 'intro.tpl'));
+
+$php_current_timestamp = date("Y-m-d H:i:s");
+list($mysql_version, $db_current_timestamp) = mysql_fetch_row(pwg_query('SELECT VERSION(), CURRENT_TIMESTAMP;'));
+
+$query = '
+SELECT COUNT(*)
+  FROM '.IMAGES_TABLE.'
+;';
+list($nb_elements) = mysql_fetch_row(pwg_query($query));
+
+$query = '
+SELECT COUNT(*)
+  FROM '.CATEGORIES_TABLE.'
+;';
+list($nb_categories) = mysql_fetch_row(pwg_query($query));
+
+$query = '
+SELECT COUNT(*)
+  FROM '.CATEGORIES_TABLE.'
+  WHERE dir IS NULL
+;';
+list($nb_virtual) = mysql_fetch_row(pwg_query($query));
+
+$query = '
+SELECT COUNT(*)
+  FROM '.CATEGORIES_TABLE.'
+  WHERE dir IS NOT NULL
+;';
+list($nb_physical) = mysql_fetch_row(pwg_query($query));
+
+$query = '
+SELECT COUNT(*)
+  FROM '.IMAGE_CATEGORY_TABLE.'
+;';
+list($nb_image_category) = mysql_fetch_row(pwg_query($query));
+
+$query = '
+SELECT COUNT(*)
+  FROM '.TAGS_TABLE.'
+;';
+list($nb_tags) = mysql_fetch_row(pwg_query($query));
+
+$query = '
+SELECT COUNT(*)
+  FROM '.IMAGE_TAG_TABLE.'
+;';
+list($nb_image_tag) = mysql_fetch_row(pwg_query($query));
+
+$query = '
+SELECT COUNT(*)
+  FROM '.USERS_TABLE.'
+;';
+list($nb_users) = mysql_fetch_row(pwg_query($query));
+
+$query = '
+SELECT COUNT(*)
+  FROM '.GROUPS_TABLE.'
+;';
+list($nb_groups) = mysql_fetch_row(pwg_query($query));
+
+$query = '
+SELECT COUNT(*)
+  FROM '.COMMENTS_TABLE.'
+;';
+list($nb_comments) = mysql_fetch_row(pwg_query($query));
+
+$template->assign(
+  array(
+    'PHPWG_URL' => PHPWG_URL,
+    'PWG_VERSION' => PHPWG_VERSION,
+    'OS' => PHP_OS,
+    'PHP_VERSION' => phpversion(),
+    'MYSQL_VERSION' => $mysql_version,
+    'DB_ELEMENTS' => l10n_dec('%d element', '%d elements', $nb_elements),
+    'DB_CATEGORIES' =>
+      l10n_dec('cat_inclu_part1_S', 'cat_inclu_part1_P',
+        $nb_categories).
+      l10n_dec('cat_inclu_part2_S', 'cat_inclu_part2_P',
+        $nb_physical).
+      l10n_dec('cat_inclu_part3_S', 'cat_inclu_part3_P',
+        $nb_virtual),
+    'DB_IMAGE_CATEGORY' => l10n_dec('%d association', '%d associations', $nb_image_category),
+    'DB_TAGS' => l10n_dec('%d tag', '%d tags', $nb_tags),
+    'DB_IMAGE_TAG' => l10n_dec('%d association', '%d associations', $nb_image_tag),
+    'DB_USERS' => l10n_dec('%d user', '%d users', $nb_users),
+    'DB_GROUPS' => l10n_dec('%d group', '%d groups', $nb_groups),
+    'DB_COMMENTS' => l10n_dec('%d comment', '%d comments', $nb_comments),
+    'U_CHECK_UPGRADE' => PHPWG_ROOT_PATH.'admin.php?action=check_upgrade',
+    'U_PHPINFO' => PHPWG_ROOT_PATH.'admin.php?action=phpinfo',
+    'PHP_DATATIME' => $php_current_timestamp,
+    'DB_DATATIME' => $db_current_timestamp,
+    )
+  );
+
+if ($nb_elements > 0)
+{
+  $query = '
+SELECT MIN(date_available)
+  FROM '.IMAGES_TABLE.'
+;';
+  list($first_date) = mysql_fetch_row(pwg_query($query));
+
+  $template->assign(
+    'first_added',
+    array(
+      'DB_DATE' =>
+      sprintf(
+        l10n('first element added on %s'),
+        format_date($first_date)
+        )
+      )
+    );
+}
+
+// waiting elements
+$query = '
+SELECT COUNT(*)
+  FROM '.WAITING_TABLE.'
+  WHERE validated=\'false\'
+;';
+list($nb_waiting) = mysql_fetch_row(pwg_query($query));
+
+if ($nb_waiting > 0)
+{
+  $template->assign(
+    'waiting',
+    array(
+      'URL' => PHPWG_ROOT_PATH.'admin.php?page=upload',
+      'INFO' => sprintf(l10n('%d waiting for validation'), $nb_waiting)
+      )
+    );
+}
+
+// unvalidated comments
+$query = '
+SELECT COUNT(*)
+  FROM '.COMMENTS_TABLE.'
+  WHERE validated=\'false\'
+;';
+list($nb_comments) = mysql_fetch_row(pwg_query($query));
+
+if ($nb_comments > 0)
+{
+  $template->assign(
+    'unvalidated',
+    array(
+      'URL' => PHPWG_ROOT_PATH.'admin.php?page=comments',
+      'INFO' => sprintf(l10n('%d waiting for validation'), $nb_comments)
+      )
+    );
+}
+
+// +-----------------------------------------------------------------------+
+// |                           sending html code                           |
+// +-----------------------------------------------------------------------+
+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'intro');
+
+// Check integrity
+$c13y = new check_integrity();
+// add internal checks
+new c13y_internal();
+// check and display
+$c13y->check();
+$c13y->display();
+
+?>
Index: /tags/2.0.2/admin/maintenance.php
===================================================================
--- /tags/2.0.2/admin/maintenance.php	(revision 3278)
+++ /tags/2.0.2/admin/maintenance.php	(revision 3278)
@@ -0,0 +1,142 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die ("Hacking attempt!");
+}
+
+include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+
+// +-----------------------------------------------------------------------+
+// | Check Access and exit when user status is not ok                      |
+// +-----------------------------------------------------------------------+
+check_status(ACCESS_ADMINISTRATOR);
+
+// +-----------------------------------------------------------------------+
+// |                                actions                                |
+// +-----------------------------------------------------------------------+
+
+$action = (isset($_GET['action']) and !is_adviser()) ? $_GET['action'] : '';
+
+switch ($action)
+{
+  case 'categories' :
+  {
+    update_uppercats();
+    update_category('all');
+    update_global_rank();
+    invalidate_user_cache(true);
+    break;
+  }
+  case 'images' :
+  {
+    update_path();
+    update_average_rate();
+    break;
+  }
+  case 'history_detail' :
+  {
+    $query = '
+DELETE
+  FROM '.HISTORY_TABLE.'
+;';
+    pwg_query($query);
+    break;
+  }
+  case 'history_summary' :
+  {
+    $query = '
+DELETE
+  FROM '.HISTORY_SUMMARY_TABLE.'
+;';
+    pwg_query($query);
+    break;
+  }
+  case 'sessions' :
+  {
+    pwg_session_gc();
+    break;
+  }
+  case 'feeds' :
+  {
+    $query = '
+DELETE
+  FROM '.USER_FEED_TABLE.'
+  WHERE last_check IS NULL
+;';
+    pwg_query($query);
+    break;
+  }
+  case 'database' :
+  {
+    do_maintenance_all_tables();
+    break;
+  }
+  case 'c13y' :
+  {
+    include_once(PHPWG_ROOT_PATH.'admin/include/check_integrity.class.php');
+    $c13y = new check_integrity();
+    $c13y->maintenance();
+    break;
+  }
+  case 'compiled-templates' :
+  {
+    $template->delete_compiled_templates();
+    break;
+  }
+  default :
+  {
+    break;
+  }
+}
+
+// +-----------------------------------------------------------------------+
+// |                             template init                             |
+// +-----------------------------------------------------------------------+
+
+$template->set_filenames(array('maintenance'=>'maintenance.tpl'));
+
+$start_url = get_root_url().'admin.php?page=maintenance&amp;action=';
+
+$template->assign(
+  array(
+    'U_MAINT_CATEGORIES' => $start_url.'categories',
+    'U_MAINT_IMAGES' => $start_url.'images',
+    'U_MAINT_HISTORY_DETAIL' => $start_url.'history_detail',
+    'U_MAINT_HISTORY_SUMMARY' => $start_url.'history_summary',
+    'U_MAINT_SESSIONS' => $start_url.'sessions',
+    'U_MAINT_FEEDS' => $start_url.'feeds',
+    'U_MAINT_DATABASE' => $start_url.'database',
+    'U_MAINT_C13Y' => $start_url.'c13y',
+    'U_MAINT_COMPILED_TEMPLATES' => $start_url.'compiled-templates',
+    'U_HELP' => PHPWG_ROOT_PATH.'popuphelp.php?page=maintenance',
+    )
+  );
+
+// +-----------------------------------------------------------------------+
+// |                           sending html code                           |
+// +-----------------------------------------------------------------------+
+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'maintenance');
+?>
Index: /tags/2.0.2/admin/menubar.php
===================================================================
--- /tags/2.0.2/admin/menubar.php	(revision 3278)
+++ /tags/2.0.2/admin/menubar.php	(revision 3278)
@@ -0,0 +1,162 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die ("Hacking attempt!");
+}
+
+
+function abs_fn_cmp($a, $b)
+{
+  return abs($a)-abs($b);
+}
+
+function make_consecutive( &$orders, $step=50 )
+{
+  uasort( $orders, 'abs_fn_cmp' );
+  $crt = 1;
+  foreach( $orders as $id=>$pos)
+  {
+    $orders[$id] = $step * ($pos<0 ? -$crt : $crt);
+    $crt++;
+  }
+}
+
+
+global $template;
+
+include_once(PHPWG_ROOT_PATH.'include/block.class.php');
+
+$menu = new BlockManager('menubar');
+$menu->load_registered_blocks();
+$reg_blocks = $menu->get_registered_blocks();
+
+$mb_conf = @$conf[ 'blk_'.$menu->get_id() ];
+if ( is_string($mb_conf) )
+  $mb_conf = unserialize( $mb_conf );
+if ( !is_array($mb_conf) )
+  $mb_conf=array();
+
+foreach ($mb_conf as $id => $pos)
+{
+  if (!isset($reg_blocks[$id]))
+    unset($mb_conf[$id]);
+}
+
+if ( isset($_POST['reset']) and !is_adviser())
+{
+  $mb_conf = array();
+  $query = '
+UPDATE '.CONFIG_TABLE.'
+  SET value=""
+  WHERE param="blk_'.addslashes($menu->get_id()).'"
+  LIMIT 1';
+  pwg_query($query);
+}
+
+
+$idx=1;
+foreach ($reg_blocks as $id => $block)
+{
+  if ( !isset($mb_conf[$id]) )
+    $mb_conf[$id] = $idx*50;
+  $idx++;
+}
+
+
+if ( isset($_POST['submit']) and !is_adviser() )
+{
+  foreach ( $mb_conf as $id => $pos )
+  {
+    $hide = isset($_POST['hide_'.$id]);
+    $mb_conf[$id] = ($hide ? -1 : +1)*abs($pos);
+
+    $pos = (int)@$_POST['pos_'.$id];
+    if ($pos>0)
+      $mb_conf[$id] = $mb_conf[$id] > 0 ? $pos : -$pos;
+  }
+  make_consecutive( $mb_conf );
+
+  // BEGIN OPTIM - DONT ASK ABOUT THIS ALGO - but optimizes the size of the array we save in DB
+  $reg_keys = array_keys($reg_blocks);
+  $cnf_keys = array_keys($mb_conf);
+  $best_slice = array( 'len'=>0 );
+  for ($i=0; $i<count($reg_keys); $i++)
+  {
+    for ($j=0; $j<count($cnf_keys); $j++)
+    {
+      for ($k=0; max($i,$j)+$k<count($cnf_keys); $k++)
+      {
+        if ($cnf_keys[$j+$k] == $reg_keys[$i+$k] )
+        {
+          if ( 1+$k>$best_slice['len'])
+          {
+            $best_slice['len'] = 1+$k;
+            $best_slice['start_cnf'] = $j;
+          }
+        }
+        else
+          break;
+      }
+    }
+  }
+  $mb_conf_db = $mb_conf;
+  if ($best_slice['len'])
+  {
+    for ($j=0; $j<$best_slice['start_cnf']; $j++ )
+    {
+      $sign = $mb_conf_db[ $cnf_keys[$j] ] > 0 ? 1 : -1;
+      $mb_conf_db[ $cnf_keys[$j] ] = $sign * ( ($best_slice['start_cnf'])*50 - ($best_slice['start_cnf']-$j) );
+    }
+    for ($j=$best_slice['start_cnf']; $j<$best_slice['start_cnf']+$best_slice['len']; $j++ )
+    {
+      if ($mb_conf_db[ $cnf_keys[$j] ] > 0)
+        unset( $mb_conf_db[ $cnf_keys[$j] ] );
+    }
+  }
+  //var_export( $best_slice ); var_export($mb_conf);  var_export($mb_conf_db);
+  // END OPTIM
+
+  $query = '
+UPDATE '.CONFIG_TABLE.'
+  SET value="'.addslashes(serialize($mb_conf_db)).'"
+  WHERE param="blk_'.addslashes($menu->get_id()).'"
+  LIMIT 1';
+  pwg_query($query);
+}
+
+make_consecutive( $mb_conf );
+
+foreach ($mb_conf as $id => $pos )
+{
+  $template->append( 'blocks',
+      array(
+        'pos' => $pos/5,
+        'reg' => $reg_blocks[$id]
+      )
+     );
+}
+$template->set_filename( 'menubar_admin_content', 'menubar.tpl' );
+$template->assign_var_from_handle( 'ADMIN_CONTENT', 'menubar_admin_content');
+?>
Index: /tags/2.0.2/admin/notification_by_mail.php
===================================================================
--- /tags/2.0.2/admin/notification_by_mail.php	(revision 3278)
+++ /tags/2.0.2/admin/notification_by_mail.php	(revision 3278)
@@ -0,0 +1,738 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// +-----------------------------------------------------------------------+
+// | include                                                               |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die ("Hacking attempt!");
+}
+
+include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+include_once(PHPWG_ROOT_PATH.'admin/include/functions_notification_by_mail.inc.php');
+include_once(PHPWG_ROOT_PATH.'admin/include/tabsheet.class.php');
+include_once(PHPWG_ROOT_PATH.'include/common.inc.php');
+include_once(PHPWG_ROOT_PATH.'include/functions_notification.inc.php');
+include_once(PHPWG_ROOT_PATH.'include/functions_mail.inc.php');
+
+// +-----------------------------------------------------------------------+
+// | Check Access and exit when user status is not ok                      |
+// +-----------------------------------------------------------------------+
+check_status(ACCESS_ADMINISTRATOR);
+
+// +-----------------------------------------------------------------------+
+// | Initialization                                                        |
+// +-----------------------------------------------------------------------+
+$base_url = get_root_url().'admin.php';
+$must_repost = false;
+
+// +-----------------------------------------------------------------------+
+// | functions                                                             |
+// +-----------------------------------------------------------------------+
+
+/*
+ * Do timeout treatment in order to finish to send mails
+ *
+ * @param $post_keyname: key of check_key post array
+ * @param check_key_treated: array of check_key treated
+ * @return none
+ */
+function do_timeout_treatment($post_keyname, $check_key_treated = array())
+{
+  global $env_nbm, $base_url, $page, $must_repost;
+
+  if ($env_nbm['is_sendmail_timeout'])
+  {
+    if (isset($_POST[$post_keyname]))
+    {
+      $post_count = count($_POST[$post_keyname]);
+      $treated_count = count($check_key_treated);
+      if ($treated_count != 0)
+      {
+        $time_refresh = ceil((get_moment() - $env_nbm['start_time']) * $post_count / $treated_count);
+      }
+      else
+      {
+        $time_refresh = 0;
+      }
+      $_POST[$post_keyname] = array_diff($_POST[$post_keyname], $check_key_treated);
+
+      $must_repost = true;
+      array_push($page['errors'],
+        l10n_dec('nbm_background_treatment_redirect_second',
+                 'nbm_background_treatment_redirect_seconds',
+                  $time_refresh));
+    }
+  }
+
+}
+
+/*
+ * Get the authorized_status for each tab
+ * return corresponding status
+ */
+function get_tab_status($mode)
+{
+  $result = ACCESS_WEBMASTER;
+  switch ($mode)
+  {
+    case 'param':
+    case 'subscribe':
+      $result = ACCESS_WEBMASTER;
+      break;
+    case 'send':
+      $result = ACCESS_ADMINISTRATOR;
+      break;
+    default:
+      $result = ACCESS_WEBMASTER;
+      break;
+  }
+  return $result;
+}
+
+/*
+ * Inserting News users
+ */
+function insert_new_data_user_mail_notification()
+{
+  global $conf, $page, $env_nbm;
+
+  // Set null mail_address empty
+  $query = '
+update
+  '.USERS_TABLE.'
+set
+  '.$conf['user_fields']['email'].' = null
+where
+  trim('.$conf['user_fields']['email'].') = \'\';';
+  pwg_query($query);
+
+  // null mail_address are not selected in the list
+  $query = '
+select
+  u.'.$conf['user_fields']['id'].' as user_id,
+  u.'.$conf['user_fields']['username'].' as username,
+  u.'.$conf['user_fields']['email'].' as mail_address
+from
+  '.USERS_TABLE.' as u left join '.USER_MAIL_NOTIFICATION_TABLE.' as m on u.'.$conf['user_fields']['id'].' = m.user_id
+where
+  u.'.$conf['user_fields']['email'].' is not null and
+  m.user_id is null
+order by
+  user_id;';
+
+  $result = pwg_query($query);
+
+  if (mysql_num_rows($result) > 0)
+  {
+    $inserts = array();
+    $check_key_list = array();
+
+    while ($nbm_user = mysql_fetch_array($result))
+    {
+      // Calculate key
+      $nbm_user['check_key'] = find_available_check_key();
+
+      // Save key
+      array_push($check_key_list, $nbm_user['check_key']);
+
+      // Insert new nbm_users
+      array_push
+      (
+        $inserts,
+        array
+        (
+          'user_id' => $nbm_user['user_id'],
+          'check_key' => $nbm_user['check_key'],
+          'enabled' => 'false' // By default if false, set to true with specific functions
+        )
+      );
+
+      array_push
+      (
+        $page['infos'],
+        sprintf(
+          l10n('nbm_user_x_added'),
+          $nbm_user['username'],
+          get_email_address_as_display_text($nbm_user['mail_address'])
+        )
+      );
+    }
+
+    // Insert new nbm_users
+    mass_inserts(USER_MAIL_NOTIFICATION_TABLE, array('user_id', 'check_key', 'enabled'), $inserts);
+    // Update field enabled with specific function
+    $check_key_treated = do_subscribe_unsubscribe_notification_by_mail
+    (
+      true,
+      $conf['nbm_default_value_user_enabled'],
+      $check_key_list
+    );
+
+     // On timeout simulate like tabsheet send
+    if ($env_nbm['is_sendmail_timeout'])
+    {
+      $quoted_check_key_list = quote_check_key_list(array_diff($check_key_list, $check_key_treated));
+      if (count($quoted_check_key_list) != 0 )
+      {
+        $query = 'delete from '.USER_MAIL_NOTIFICATION_TABLE.' where check_key in ('.implode(",", $quoted_check_key_list).');';
+        $result = pwg_query($query);
+
+        redirect($base_url.get_query_string_diff(array(), false), l10n('nbm_redirect_msg'));
+      }
+    }
+  }
+}
+
+/*
+ * Apply global functions to mail content
+ * return customize mail content rendered
+ */
+function render_global_customize_mail_content($customize_mail_content)
+{
+  global $conf;
+
+  if ($conf['nbm_send_html_mail'] and !(strpos($customize_mail_content, '<') === 0))
+  {
+    // On HTML mail, detects if the content are HTML format.
+    // If it's plain text format, convert content to readable HTML
+    return nl2br(htmlspecialchars($customize_mail_content));
+  }
+  else
+  {
+    return $customize_mail_content;
+  }
+}
+
+/*
+ * Send mail for notification to all users
+ * Return list of "selected" users for 'list_to_send'
+ * Return list of "treated" check_key for 'send'
+ */
+function do_action_send_mail_notification($action = 'list_to_send', $check_key_list = array(), $customize_mail_content = '')
+{
+  global $conf, $page, $user, $lang_info, $lang, $env_nbm;
+  $return_list = array();
+
+  if (in_array($action, array('list_to_send', 'send')))
+  {
+    list($dbnow) = mysql_fetch_row(pwg_query('SELECT NOW();'));
+
+    $is_action_send = ($action == 'send');
+
+    // disabled and null mail_address are not selected in the list
+    $data_users = get_user_notifications('send', $check_key_list);
+
+    // List all if it's define on options or on timeout
+    $is_list_all_without_test = ($env_nbm['is_sendmail_timeout'] or $conf['nbm_list_all_enabled_users_to_send']);
+
+    // Check if exist news to list user or send mails
+    if ((!$is_list_all_without_test) or ($is_action_send))
+    {
+      if (count($data_users) > 0)
+      {
+        $datas = array();
+
+        if (!isset($customize_mail_content))
+        {
+          $customize_mail_content = $conf['nbm_complementary_mail_content'];
+        }
+
+        $customize_mail_content = 
+          trigger_event('nbm_render_global_customize_mail_content', $customize_mail_content);
+
+
+        // Prepare message after change language
+        if ($is_action_send)
+        {
+          $msg_break_timeout = l10n('nbm_break_timeout_send_mail');
+        }
+        else
+        {
+          $msg_break_timeout = l10n('nbm_break_timeout_list_user');
+        }
+
+        // Begin nbm users environment
+        begin_users_env_nbm($is_action_send);
+
+        foreach ($data_users as $nbm_user)
+        {
+          if ((!$is_action_send) and check_sendmail_timeout())
+          {
+            // Stop fill list on 'list_to_send', if the quota is override
+            array_push($page['infos'], $msg_break_timeout);
+            break;
+          }
+          if (($is_action_send) and check_sendmail_timeout())
+          {
+            // Stop fill list on 'send', if the quota is override
+            array_push($page['errors'], $msg_break_timeout);
+            break;
+          }
+
+          // set env nbm user
+          set_user_on_env_nbm($nbm_user, $is_action_send);
+
+          if ($is_action_send)
+          {
+            set_make_full_url();
+            // Fill return list of "treated" check_key for 'send'
+            array_push($return_list, $nbm_user['check_key']);
+
+            if ($conf['nbm_send_detailed_content'])
+            {
+               $news = news($nbm_user['last_send'], $dbnow, false, $conf['nbm_send_html_mail']);
+               $exist_data = count($news) > 0;
+            }
+            else
+            {
+              $exist_data = news_exists($nbm_user['last_send'], $dbnow);
+            }
+
+            if ($exist_data)
+            {
+              $subject = '['.$conf['gallery_title'].']: '.l10n('nbm_object_news');
+
+              // Assign current var for nbm mail
+              assign_vars_nbm_mail_content($nbm_user);
+
+              if (!is_null($nbm_user['last_send']))
+              {
+                $env_nbm['mail_template']->assign
+                (
+                  'content_new_elements_between',
+                  array
+                  (
+                    'DATE_BETWEEN_1' => $nbm_user['last_send'],
+                    'DATE_BETWEEN_2' => $dbnow,
+                  )
+                );
+              }
+              else
+              {
+                $env_nbm['mail_template']->assign
+                (
+                  'content_new_elements_single',
+                  array
+                  (
+                    'DATE_SINGLE' => $dbnow,
+                  )
+                );
+              }
+
+              if ($conf['nbm_send_detailed_content'])
+              {
+                $env_nbm['mail_template']->assign('global_new_lines', $news);
+              }
+
+              $nbm_user_customize_mail_content = 
+                trigger_event('nbm_render_user_customize_mail_content',
+                  $customize_mail_content, $nbm_user);
+              if (!empty($nbm_user_customize_mail_content))
+              {
+                $env_nbm['mail_template']->assign
+                (
+                  'custom_mail_content', $nbm_user_customize_mail_content
+                );
+              }
+
+              if ($conf['nbm_send_html_mail'] and $conf['nbm_send_recent_post_dates'])
+              {
+                $recent_post_dates = get_recent_post_dates_array(
+                  $conf['recent_post_dates']['NBM']);
+                foreach ($recent_post_dates as $date_detail)
+                {
+                  $env_nbm['mail_template']->append
+                  (
+                    'recent_posts',
+                    array
+                    (
+                      'TITLE' => get_title_recent_post_date($date_detail),
+                      'HTML_DATA' => get_html_description_recent_post_date($date_detail)
+                    )
+                  );
+                }
+              }
+
+              $env_nbm['mail_template']->assign
+              (
+                array
+                (
+                  'GOTO_GALLERY_TITLE' => $conf['gallery_title'],
+                  'GOTO_GALLERY_URL' => $conf['gallery_url'],
+                  'SEND_AS_NAME'      => $env_nbm['send_as_name'],
+                )
+              );
+
+              if (pwg_mail
+                  (
+                    format_email($nbm_user['username'], $nbm_user['mail_address']),
+                    array
+                    (
+                      'from' => $env_nbm['send_as_mail_formated'],
+                      'subject' => $subject,
+                      'email_format' => $env_nbm['email_format'],
+                      'content' => $env_nbm['mail_template']->parse('notification_by_mail', true),
+                      'content_format' => $env_nbm['email_format'],
+                      'template' => $nbm_user['template'],
+                      'theme' => $nbm_user['theme']
+                    )
+                  ))
+              {
+                inc_mail_sent_success($nbm_user);
+
+                $data = array('user_id' => $nbm_user['user_id'],
+                              'last_send' => $dbnow);
+                array_push($datas, $data);
+              }
+              else
+              {
+                inc_mail_sent_failed($nbm_user);
+              }
+
+              unset_make_full_url();
+            }
+          }
+          else
+          {
+            if (news_exists($nbm_user['last_send'], $dbnow))
+            {
+              // Fill return list of "selected" users for 'list_to_send'
+              array_push($return_list, $nbm_user);
+            }
+          }
+
+          // unset env nbm user
+          unset_user_on_env_nbm();
+        }
+
+        // Restore nbm environment
+        end_users_env_nbm();
+
+        if ($is_action_send)
+        {
+          mass_updates(
+            USER_MAIL_NOTIFICATION_TABLE,
+            array(
+              'primary' => array('user_id'),
+              'update' => array('last_send')
+             ),
+             $datas
+             );
+
+          display_counter_info();
+        }
+      }
+      else
+      {
+        if ($is_action_send)
+        {
+          array_push($page['errors'], l10n('nbm_no_user_to send_notifications_by_mail'));
+        }
+      }
+    }
+    else
+    {
+      // Quick List, don't check news
+      // Fill return list of "selected" users for 'list_to_send'
+      $return_list = $data_users;
+    }
+  }
+
+  // Return list of "selected" users for 'list_to_send'
+  // Return list of "treated" check_key for 'send'
+  return $return_list;
+}
+
+// +-----------------------------------------------------------------------+
+// | Main                                                                  |
+// +-----------------------------------------------------------------------+
+if (!isset($_GET['mode']))
+{
+  $page['mode'] = 'send';
+}
+else
+{
+  $page['mode'] = $_GET['mode'];
+}
+
+// +-----------------------------------------------------------------------+
+// | Check Access and exit when user status is not ok                      |
+// +-----------------------------------------------------------------------+
+check_status(get_tab_status($page['mode']));
+
+
+// +-----------------------------------------------------------------------+
+// | Add event handler                                                     |
+// +-----------------------------------------------------------------------+
+add_event_handler('nbm_render_global_customize_mail_content', 'render_global_customize_mail_content');
+trigger_action('nbm_event_handler_added');
+
+
+// +-----------------------------------------------------------------------+
+// | Insert new users with mails                                           |
+// +-----------------------------------------------------------------------+
+if (!isset($_POST) or (count($_POST) ==0))
+{
+  // No insert data in post mode
+  insert_new_data_user_mail_notification();
+}
+
+// +-----------------------------------------------------------------------+
+// | Treatment of tab post                                                 |
+// +-----------------------------------------------------------------------+
+switch ($page['mode'])
+{
+  case 'param' :
+  {
+    if (isset($_POST['param_submit']) and !is_adviser())
+    {
+      $updated_param_count = 0;
+      // Update param
+      $result = pwg_query('select param, value from '.CONFIG_TABLE.' where param like \'nbm\\_%\'');
+      while ($nbm_user = mysql_fetch_array($result))
+      {
+        if (isset($_POST[$nbm_user['param']]))
+        {
+          $value = $_POST[$nbm_user['param']];
+
+          $query = '
+update
+'.CONFIG_TABLE.'
+set
+  value = \''. str_replace("\'", "''", $value).'\'
+where
+  param = \''.$nbm_user['param'].'\';';
+          pwg_query($query);
+          $updated_param_count += 1;
+        }
+      }
+
+      array_push($page['infos'],
+        l10n_dec('nbm_updated_param_count', 'nbm_updated_params_count',
+          $updated_param_count));
+
+      // Reload conf with new values
+      load_conf_from_db('param like \'nbm\\_%\'');
+    }
+  }
+  case 'subscribe' :
+  {
+    if (!is_adviser())
+    {
+      if (isset($_POST['falsify']) and isset($_POST['cat_true']))
+      {
+        $check_key_treated = unsubscribe_notification_by_mail(true, $_POST['cat_true']);
+        do_timeout_treatment('cat_true', $check_key_treated);
+      }
+      else
+      if (isset($_POST['trueify']) and isset($_POST['cat_false']))
+      {
+        $check_key_treated = subscribe_notification_by_mail(true, $_POST['cat_false']);
+        do_timeout_treatment('cat_false', $check_key_treated);
+      }
+    }
+    break;
+  }
+
+  case 'send' :
+  {
+    if (isset($_POST['send_submit']) and isset($_POST['send_selection']) and isset($_POST['send_customize_mail_content']) and !is_adviser())
+    {
+      $check_key_treated = do_action_send_mail_notification('send', $_POST['send_selection'], stripslashes($_POST['send_customize_mail_content']));
+      do_timeout_treatment('send_selection', $check_key_treated);
+    }
+  }
+}
+
+// +-----------------------------------------------------------------------+
+// | template initialization                                               |
+// +-----------------------------------------------------------------------+
+$template->set_filenames
+(
+  array
+  (
+    'double_select' => 'double_select.tpl',
+    'notification_by_mail'=>'notification_by_mail.tpl'
+  )
+);
+
+$template->assign
+(
+  array
+  (
+    'U_HELP' => add_url_params(get_root_url().'popuphelp.php', array('page' => 'notification_by_mail')),
+    'F_ACTION'=> $base_url.get_query_string_diff(array())
+  )
+);
+
+if (is_autorize_status(ACCESS_WEBMASTER))
+{
+  // TabSheet
+  $tabsheet = new tabsheet();
+  // TabSheet initialization
+  $tabsheet->add('param', l10n('nbm_param_mode'),
+    add_url_params($base_url.get_query_string_diff(array('mode', 'select')),
+        array('mode' => 'param')));
+  $tabsheet->add('subscribe', l10n('nbm_subscribe_mode'),
+    add_url_params($base_url.get_query_string_diff(array('mode', 'select')),
+      array('mode' => 'subscribe')));
+  $tabsheet->add('send', l10n('nbm_send_mode'),
+    add_url_params($base_url.get_query_string_diff(array('mode', 'select')),
+      array('mode' => 'send')));
+  // TabSheet selection
+  $tabsheet->select($page['mode']);
+  // Assign tabsheet to template
+  $tabsheet->assign();
+}
+
+if ($must_repost)
+{
+  // Get name of submit button
+  $repost_submit_name = '';
+  if (isset($_POST['falsify']))
+  {
+    $repost_submit_name = 'falsify';
+  }
+  elseif (isset($_POST['trueify']))
+  {
+    $repost_submit_name = 'trueify';
+  }
+  elseif (isset($_POST['send_submit']))
+  {
+    $repost_submit_name = 'send_submit';
+  }
+
+  $template->assign('REPOST_SUBMIT_NAME', $repost_submit_name);
+}
+
+switch ($page['mode'])
+{
+  case 'param' :
+  {
+    $template->assign(
+      $page['mode'],
+      array(
+        'SEND_HTML_MAIL' => $conf['nbm_send_html_mail'],
+        'SEND_MAIL_AS' => $conf['nbm_send_mail_as'],
+        'SEND_DETAILED_CONTENT' => $conf['nbm_send_detailed_content'],
+        'COMPLEMENTARY_MAIL_CONTENT' => $conf['nbm_complementary_mail_content'],
+        'SEND_RECENT_POST_DATES' => $conf['nbm_send_recent_post_dates'],
+        ));
+    break;
+  }
+
+  case 'subscribe' :
+  {
+    $template->assign( $page['mode'], true );
+
+    $template->assign(
+      array(
+        'L_CAT_OPTIONS_TRUE' => l10n('nbm_subscribe_col'),
+        'L_CAT_OPTIONS_FALSE' => l10n('nbm_unsubscribe_col')
+        )
+      );
+
+    $data_users = get_user_notifications('subscribe');
+    
+    $opt_true = array();
+    $opt_true_selected = array();
+    $opt_false = array();
+    $opt_false_selected = array();
+    foreach ($data_users as $nbm_user)
+    {
+      if (get_boolean($nbm_user['enabled']))
+      {
+        $opt_true[ $nbm_user['check_key'] ] = $nbm_user['username'].'['.get_email_address_as_display_text($nbm_user['mail_address']).']';
+        if ((isset($_POST['falsify']) and isset($_POST['cat_true']) and in_array($nbm_user['check_key'], $_POST['cat_true'])))
+        {
+          $opt_true_selected[] = $nbm_user['check_key'];
+        }
+      }
+      else
+      {
+        $opt_false[ $nbm_user['check_key'] ] = $nbm_user['username'].'['.get_email_address_as_display_text($nbm_user['mail_address']).']';
+        if (isset($_POST['trueify']) and isset($_POST['cat_false']) and in_array($nbm_user['check_key'], $_POST['cat_false']))
+        {
+          $opt_false_selected[] = $nbm_user['check_key'];
+        }
+      }
+    }
+    $template->assign( array(
+        'category_option_true'          => $opt_true,
+        'category_option_true_selected' => $opt_true_selected,
+        'category_option_false'         => $opt_false,
+        'category_option_false_selected' => $opt_false_selected,
+        )
+    );
+    $template->assign_var_from_handle('DOUBLE_SELECT', 'double_select');
+    break;
+  }
+
+  case 'send' :
+  {
+    $tpl_var = array('users'=> array() );
+
+    $data_users = do_action_send_mail_notification('list_to_send');
+
+    $tpl_var['CUSTOMIZE_MAIL_CONTENT'] = 
+      isset($_POST['send_customize_mail_content']) 
+        ? stripslashes($_POST['send_customize_mail_content']) 
+        : $conf['nbm_complementary_mail_content'];
+
+    if  (count($data_users))
+    {
+      foreach ($data_users as $nbm_user)
+      {
+        if (
+            (!$must_repost) or // Not timeout, normal treatment
+            (($must_repost) and in_array($nbm_user['check_key'], $_POST['send_selection']))  // Must be repost, show only user to send
+            )
+        {
+          $tpl_var['users'][] = 
+            array(
+              'ID' => $nbm_user['check_key'],
+              'CHECKED' =>  ( // not check if not selected,  on init select<all
+                              isset($_POST['send_selection']) and // not init
+                              !in_array($nbm_user['check_key'], $_POST['send_selection']) // not selected
+                            )   ? '' : 'checked="checked"',
+              'USERNAME'=> $nbm_user['username'],
+              'EMAIL' => get_email_address_as_display_text($nbm_user['mail_address']),
+              'LAST_SEND'=> $nbm_user['last_send']
+              );
+        }
+      }
+    }
+    $template->assign($page['mode'], $tpl_var);
+    break;
+  }
+}
+
+// +-----------------------------------------------------------------------+
+// | Sending html code                                                     |
+// +-----------------------------------------------------------------------+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'notification_by_mail');
+
+?>
Index: /tags/2.0.2/admin/permalinks.php
===================================================================
--- /tags/2.0.2/admin/permalinks.php	(revision 3278)
+++ /tags/2.0.2/admin/permalinks.php	(revision 3278)
@@ -0,0 +1,179 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+function parse_sort_variables(
+    $sortable_by, $default_field,
+    $get_param, $get_rejects,
+    $template_var,
+    $anchor = '' )
+{
+  global $template;
+
+  $url_components = parse_url( $_SERVER['REQUEST_URI'] );
+
+  $base_url = $url_components['path'];
+
+  parse_str($url_components['query'], $vars);
+  $is_first = true;
+  foreach ($vars as $key => $value)
+  {
+    if (!in_array($key, $get_rejects) and $key!=$get_param)
+    {
+      $base_url .= $is_first ? '?' : '&amp;';
+      $is_first = false;
+      $base_url .= $key.'='.urlencode($value);
+    }
+  }
+
+  $ret = array();
+  foreach( $sortable_by as $field)
+  {
+    $url = $base_url;
+    $disp = '&dArr;'; // TODO: an small image is better
+
+    if ( $field !== @$_GET[$get_param] )
+    {
+      if ( !isset($default_field) or $default_field!=$field )
+      { // the first should be the default
+        $url = add_url_params($url, array($get_param=>$field) );
+      }
+      elseif (isset($default_field) and !isset($_GET[$get_param]) )
+      {
+        array_push($ret, $field);
+        $disp = '<em>'.$disp.'</em>';
+      }
+    }
+    else
+    {
+      array_push($ret, $field);
+      $disp = '<em>'.$disp.'</em>';
+    }
+    if ( isset($template_var) )
+    {
+      $template->assign( $template_var.strtoupper($field),
+            '<a href="'.$url.$anchor.'" title="'.l10n('Sort order').'">'.$disp.'</a>'
+         );
+    }
+  }
+  return $ret;
+}
+
+if (!defined('PHPWG_ROOT_PATH')) die('Hacking attempt!');
+
+include_once(PHPWG_ROOT_PATH.'admin/include/functions_permalinks.php');
+
+$selected_cat = array();
+if ( isset($_POST['set_permalink']) and $_POST['cat_id']>0 and !is_adviser() )
+{
+  $permalink = $_POST['permalink'];
+  if ( empty($permalink) )
+    delete_cat_permalink($_POST['cat_id'], isset($_POST['save']) );
+  else
+    set_cat_permalink($_POST['cat_id'], $permalink, isset($_POST['save']) );
+  $selected_cat = array( $_POST['cat_id'] );
+}
+elseif ( isset($_GET['delete_permanent']) and !is_adviser() )
+{
+  $query = '
+DELETE FROM '.OLD_PERMALINKS_TABLE.'
+  WHERE permalink="'.$_GET['delete_permanent'].'"
+  LIMIT 1';
+  pwg_query($query);
+  if (mysql_affected_rows()==0)
+    array_push($page['errors'], 'Cannot delete the old permalink !');
+}
+
+
+$template->set_filename('permalinks', 'permalinks.tpl' );
+
+$query = '
+SELECT
+  id,
+  CONCAT(id, " - ", name, IF(permalink IS NULL, "", " &radic;") ) AS name,
+  uppercats, global_rank
+FROM '.CATEGORIES_TABLE;
+
+display_select_cat_wrapper( $query, $selected_cat, 'categories', false );
+
+
+// --- generate display of active permalinks -----------------------------------
+$sort_by = parse_sort_variables(
+    array('id', 'name', 'permalink'), 'name',
+    'psf',
+    array('delete_permanent'),
+    'SORT_' );
+
+$query = '
+SELECT id, permalink, uppercats, global_rank
+  FROM '.CATEGORIES_TABLE.'
+  WHERE permalink IS NOT NULL
+';
+if ( $sort_by[0]=='id' or $sort_by[0]=='permalink' )
+{
+  $query .= ' ORDER BY '.$sort_by[0];
+}
+$categories=array();
+$result=pwg_query($query);
+while ( $row=mysql_fetch_assoc($result) )
+{
+  $row['name'] = get_cat_display_name_cache( $row['uppercats'] );
+  $categories[] = $row;
+}
+
+if ( $sort_by[0]=='name')
+{
+  usort($categories, 'global_rank_compare');
+}
+$template->assign( 'permalinks', $categories );
+
+// --- generate display of old permalinks --------------------------------------
+
+$sort_by = parse_sort_variables(
+    array('cat_id','permalink','date_deleted','last_hit','hit'), null,
+    'dpsf',
+    array('delete_permanent'),
+    'SORT_OLD_', '#old_permalinks' );
+
+$url_del_base = get_root_url().'admin.php?page=permalinks';
+$query = 'SELECT * FROM '.OLD_PERMALINKS_TABLE;
+if ( count($sort_by) )
+{
+  $query .= ' ORDER BY '.$sort_by[0];
+}
+$result = pwg_query($query);
+$deleted_permalinks=array();
+while ( $row=mysql_fetch_assoc($result) )
+{
+  $row['name'] = get_cat_display_name_cache($row['cat_id']);
+  $row['U_DELETE'] =
+      add_url_params(
+        $url_del_base,
+        array( 'delete_permanent'=> $row['permalink'] )
+      );
+  $deleted_permalinks[] = $row;
+}
+$template->assign('deleted_permalinks', $deleted_permalinks);
+$template->assign('U_HELP', get_root_url().'popuphelp.php?page=permalinks');
+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'permalinks');
+?>
Index: /tags/2.0.2/admin/picture_modify.php
===================================================================
--- /tags/2.0.2/admin/picture_modify.php	(revision 3278)
+++ /tags/2.0.2/admin/picture_modify.php	(revision 3278)
@@ -0,0 +1,450 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if(!defined("PHPWG_ROOT_PATH"))
+{
+  die('Hacking attempt!');
+}
+
+include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+
+// +-----------------------------------------------------------------------+
+// | Check Access and exit when user status is not ok                      |
+// +-----------------------------------------------------------------------+
+check_status(ACCESS_ADMINISTRATOR);
+
+// +-----------------------------------------------------------------------+
+// |                          synchronize metadata                         |
+// +-----------------------------------------------------------------------+
+
+if (isset($_GET['sync_metadata']) and !is_adviser())
+{
+  $query = '
+SELECT path
+  FROM '.IMAGES_TABLE.'
+  WHERE id = '.$_GET['image_id'].'
+;';
+  list($path) = mysql_fetch_row(pwg_query($query));
+  update_metadata(array($_GET['image_id'] => $path));
+
+  array_push($page['infos'], l10n('Metadata synchronized from file'));
+}
+
+//--------------------------------------------------------- update informations
+
+// first, we verify whether there is a mistake on the given creation date
+if (isset($_POST['date_creation_action'])
+    and 'set' == $_POST['date_creation_action'])
+{
+  if (!checkdate(
+        $_POST['date_creation_month'],
+        $_POST['date_creation_day'],
+        $_POST['date_creation_year'])
+    )
+  {
+    array_push($page['errors'], l10n('err_date'));
+  }
+}
+
+if (isset($_POST['submit']) and count($page['errors']) == 0 and !is_adviser())
+{
+  $data = array();
+  $data{'id'} = $_GET['image_id'];
+  $data{'name'} = $_POST['name'];
+  $data{'author'} = $_POST['author'];
+  $data['level'] = $_POST['level'];
+
+  if ($conf['allow_html_descriptions'])
+  {
+    $data{'comment'} = @$_POST['description'];
+  }
+  else
+  {
+    $data{'comment'} = strip_tags(@$_POST['description']);
+  }
+
+  if (isset($_POST['date_creation_action']))
+  {
+    if ('set' == $_POST['date_creation_action'])
+    {
+      $data{'date_creation'} = $_POST['date_creation_year']
+                                 .'-'.$_POST['date_creation_month']
+                                 .'-'.$_POST['date_creation_day'];
+    }
+    else if ('unset' == $_POST['date_creation_action'])
+    {
+      $data{'date_creation'} = '';
+    }
+  }
+
+  mass_updates(
+    IMAGES_TABLE,
+    array(
+      'primary' => array('id'),
+      'update' => array_diff(array_keys($data), array('id'))
+      ),
+    array($data)
+    );
+
+  set_tags(
+    isset($_POST['tags']) ? $_POST['tags'] : array(),
+    $_GET['image_id']
+    );
+
+  array_push($page['infos'], l10n('Picture informations updated'));
+}
+// associate the element to other categories than its storage category
+if (isset($_POST['associate'])
+    and isset($_POST['cat_dissociated'])
+    and count($_POST['cat_dissociated']) > 0
+    and !is_adviser()
+  )
+{
+  associate_images_to_categories(
+    array($_GET['image_id']),
+    $_POST['cat_dissociated']
+    );
+}
+// dissociate the element from categories (but not from its storage category)
+if (isset($_POST['dissociate'])
+    and isset($_POST['cat_associated'])
+    and count($_POST['cat_associated']) > 0
+    and !is_adviser()
+  )
+{
+  $query = '
+DELETE FROM '.IMAGE_CATEGORY_TABLE.'
+  WHERE image_id = '.$_GET['image_id'].'
+    AND category_id IN ('.implode(',', $_POST['cat_associated']).')
+';
+  pwg_query($query);
+
+  update_category($_POST['cat_associated']);
+}
+// elect the element to represent the given categories
+if (isset($_POST['elect'])
+    and isset($_POST['cat_dismissed'])
+    and count($_POST['cat_dismissed']) > 0
+    and !is_adviser()
+  )
+{
+  $datas = array();
+  foreach ($_POST['cat_dismissed'] as $category_id)
+  {
+    array_push($datas,
+               array('id' => $category_id,
+                     'representative_picture_id' => $_GET['image_id']));
+  }
+  $fields = array('primary' => array('id'),
+                  'update' => array('representative_picture_id'));
+  mass_updates(CATEGORIES_TABLE, $fields, $datas);
+}
+// dismiss the element as representant of the given categories
+if (isset($_POST['dismiss'])
+    and isset($_POST['cat_elected'])
+    and count($_POST['cat_elected']) > 0
+    and !is_adviser()
+  )
+{
+  set_random_representant($_POST['cat_elected']);
+}
+
+// retrieving direct information about picture
+$query = '
+SELECT *
+  FROM '.IMAGES_TABLE.'
+  WHERE id = '.$_GET['image_id'].'
+;';
+$row = mysql_fetch_array(pwg_query($query));
+
+$storage_category_id = null;
+if (!empty($row['storage_category_id']))
+{
+  $storage_category_id = $row['storage_category_id'];
+}
+
+$image_file = $row['file'];
+
+// tags
+$query = '
+SELECT tag_id
+  FROM '.IMAGE_TAG_TABLE.'
+  WHERE image_id = '.$_GET['image_id'].'
+;';
+$selected_tags = array_from_query($query, 'tag_id');
+
+// +-----------------------------------------------------------------------+
+// |                             template init                             |
+// +-----------------------------------------------------------------------+
+
+$template->set_filenames(
+  array(
+    'picture_modify' => 'picture_modify.tpl'
+    )
+  );
+
+$all_tags = get_all_tags();
+
+if (count($all_tags) > 0)
+{
+  $tag_selection = get_html_tag_selection(
+    $all_tags,
+    'tags',
+    $selected_tags
+    );
+}
+else
+{
+  $tag_selection =
+    '<p>'.
+    l10n('No tag defined. Use Administration>Pictures>Tags').
+    '</p>';
+}
+
+$template->assign(
+  array(
+    'U_SYNC' =>
+        get_root_url().'admin.php?page=picture_modify'.
+        '&amp;image_id='.$_GET['image_id'].
+        (isset($_GET['cat_id']) ? '&amp;cat_id='.$_GET['cat_id'] : '').
+        '&amp;sync_metadata=1',
+
+    'PATH'=>$row['path'],
+
+    'TN_SRC' => get_thumbnail_url($row),
+
+    'NAME' =>
+      isset($_POST['name']) ?
+        stripslashes($_POST['name']) : @$row['name'],
+
+    'DIMENSIONS' => @$row['width'].' * '.@$row['height'],
+
+    'FILESIZE' => @$row['filesize'].' KB',
+
+    'REGISTRATION_DATE' => format_date($row['date_available']),
+
+    'AUTHOR' => isset($_POST['author']) ? $_POST['author'] : @$row['author'],
+
+    'TAG_SELECTION' => $tag_selection,
+
+    'DESCRIPTION' =>
+      htmlspecialchars( isset($_POST['description']) ?
+        stripslashes($_POST['description']) : @$row['comment'] ),
+
+    'F_ACTION' =>
+        get_root_url().'admin.php'
+        .get_query_string_diff(array('sync_metadata'))
+    )
+  );
+
+if ($row['has_high'] == 'true')
+{
+  $template->assign(
+    'HIGH_FILESIZE',
+    isset($row['high_filesize'])
+        ? $row['high_filesize'].' KB'
+        : l10n('unknown')
+    );
+}
+
+// image level options
+$tpl_options = array();
+foreach ($conf['available_permission_levels'] as $level)
+{
+  $tpl_options[$level] = l10n( sprintf('Level %d', $level) ).' ('.$level.')';
+}
+$selected_level = isset($_POST['level']) ? $_POST['level'] : $row['level'];
+$template->assign(
+    array(
+      'level_options'=> $tpl_options,
+      'level_options_selected' => array($selected_level)
+    )
+  );
+
+// creation date
+unset($day, $month, $year);
+
+if (isset($_POST['date_creation_action'])
+    and 'set' == $_POST['date_creation_action'])
+{
+  foreach (array('day', 'month', 'year') as $varname)
+  {
+    $$varname = $_POST['date_creation_'.$varname];
+  }
+}
+else if (isset($row['date_creation']) and !empty($row['date_creation']))
+{
+  list($year, $month, $day) = explode('-', $row['date_creation']);
+}
+else
+{
+  list($year, $month, $day) = array('', 0, 0);
+}
+
+
+$month_list = $lang['month'];
+$month_list[0]='------------';
+ksort($month_list);
+
+$template->assign(
+    array(
+      'DATE_CREATION_DAY_VALUE' => $day,
+      'DATE_CREATION_MONTH_VALUE' => $month,
+      'DATE_CREATION_YEAR_VALUE' => $year,
+      'month_list' => $month_list,
+      )
+    );
+
+$query = '
+SELECT category_id, uppercats
+  FROM '.IMAGE_CATEGORY_TABLE.' AS ic
+    INNER JOIN '.CATEGORIES_TABLE.' AS c
+      ON c.id = ic.category_id
+  WHERE image_id = '.$_GET['image_id'].'
+;';
+$result = pwg_query($query);
+
+while ($row = mysql_fetch_array($result))
+{
+  $name =
+    get_cat_display_name_cache(
+      $row['uppercats'],
+      get_root_url().'admin.php?page=cat_modify&amp;cat_id=',
+      false
+      );
+
+  if ($row['category_id'] == $storage_category_id)
+  {
+    $template->assign('STORAGE_CATEGORY', $name);
+  }
+  else
+  {
+    $template->append('related_categories', $name);
+  }
+}
+
+// jump to link
+//
+// 1. find all linked categories that are reachable for the current user.
+// 2. if a category is available in the URL, use it if reachable
+// 3. if URL category not available or reachable, use the first reachable
+//    linked category
+// 4. if no category reachable, no jumpto link
+
+$query = '
+SELECT category_id
+  FROM '.IMAGE_CATEGORY_TABLE.'
+  WHERE image_id = '.$_GET['image_id'].'
+;';
+
+$authorizeds = array_diff(
+  array_from_query($query, 'category_id'),
+  explode(
+    ',',
+    calculate_permissions($user['id'], $user['status'])
+    )
+  );
+
+if (isset($_GET['cat_id'])
+    and in_array($_GET['cat_id'], $authorizeds))
+{
+  $url_img = make_picture_url(
+    array(
+      'image_id' => $_GET['image_id'],
+      'image_file' => $image_file,
+      'category' => $cache['cat_names'][ $_GET['cat_id'] ],
+      )
+    );
+}
+else
+{
+  foreach ($authorizeds as $category)
+  {
+    $url_img = make_picture_url(
+      array(
+        'image_id' => $_GET['image_id'],
+        'image_file' => $image_file,
+        'category' => $cache['cat_names'][ $category ],
+        )
+      );
+    break;
+  }
+}
+
+if (isset($url_img))
+{
+  $template->assign( 'U_JUMPTO', $url_img );
+}
+
+// associate to another category ?
+$query = '
+SELECT id,name,uppercats,global_rank
+  FROM '.CATEGORIES_TABLE.'
+    INNER JOIN '.IMAGE_CATEGORY_TABLE.' ON id = category_id
+  WHERE image_id = '.$_GET['image_id'];
+if (isset($storage_category_id))
+{
+  $query.= '
+    AND id != '.$storage_category_id;
+}
+$query.= '
+;';
+display_select_cat_wrapper($query, array(), 'associated_options');
+
+$result = pwg_query($query);
+$associateds = array();
+if (isset($storage_category_id))
+{
+  array_push($associateds, $storage_category_id);
+}
+while ($row = mysql_fetch_array($result))
+{
+  array_push($associateds, $row['id']);
+}
+$query = '
+SELECT id,name,uppercats,global_rank
+  FROM '.CATEGORIES_TABLE.'
+  WHERE id NOT IN ('.implode(',', $associateds).')
+;';
+display_select_cat_wrapper($query, array(), 'dissociated_options');
+
+// representing
+$query = '
+SELECT id,name,uppercats,global_rank
+  FROM '.CATEGORIES_TABLE.'
+  WHERE representative_picture_id = '.$_GET['image_id'].'
+;';
+display_select_cat_wrapper($query, array(), 'elected_options');
+
+$query = '
+SELECT id,name,uppercats,global_rank
+  FROM '.CATEGORIES_TABLE.'
+  WHERE representative_picture_id != '.$_GET['image_id'].'
+    OR representative_picture_id IS NULL
+;';
+display_select_cat_wrapper($query, array(), 'dismissed_options');
+
+//----------------------------------------------------------- sending html code
+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'picture_modify');
+?>
Index: /tags/2.0.2/admin/plugin.php
===================================================================
--- /tags/2.0.2/admin/plugin.php	(revision 3278)
+++ /tags/2.0.2/admin/plugin.php	(revision 3278)
@@ -0,0 +1,62 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if( !defined("PHPWG_ROOT_PATH") )
+{
+  die ("Hacking attempt!");
+}
+
+include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+check_status(ACCESS_ADMINISTRATOR);
+
+$sections = explode('/', $_GET['section'] );
+for ($i=0; $i<count($sections); $i++)
+{
+  if (empty($sections[$i]) or $sections[$i]=='..')
+  {
+    unset($sections[$i]);
+    $i--;
+  }
+}
+
+if (count($sections)<2)
+{
+  die('Invalid plugin URL');
+}
+
+$plugin_id = $sections[0];
+if ( !isset($pwg_loaded_plugins[$plugin_id]) )
+{
+  die('Invalid URL - plugin '.$plugin_id.' not active');
+}
+
+$filename = PHPWG_PLUGINS_PATH.implode('/', $sections);
+if (is_file($filename))
+{
+  include_once($filename);
+}
+else
+{
+  die('Missing file '.$filename);
+}
+?>
Index: /tags/2.0.2/admin/plugins_list.php
===================================================================
--- /tags/2.0.2/admin/plugins_list.php	(revision 3278)
+++ /tags/2.0.2/admin/plugins_list.php	(revision 3278)
@@ -0,0 +1,126 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if( !defined("PHPWG_ROOT_PATH") )
+{
+  die ("Hacking attempt!");
+}
+
+include_once(PHPWG_ROOT_PATH.'admin/include/plugins.class.php');
+
+$template->set_filenames(array('plugins' => 'plugins_list.tpl'));
+
+$order = isset($_GET['order']) ? $_GET['order'] : 'name';
+$base_url = get_root_url().'admin.php?page='.$page['page'].'&amp;order='.$order;
+
+$plugins = new plugins();
+
+//--------------------------------------------------perform requested actions
+if (isset($_GET['action']) and isset($_GET['plugin']) and !is_adviser())
+{
+  $page['errors'] =
+    $plugins->perform_action($_GET['action'], $_GET['plugin']);
+
+  if (empty($page['errors'])) redirect($base_url);
+}
+
+//--------------------------------------------------------------------Tabsheet
+set_plugins_tabsheet($page['page']);
+
+//---------------------------------------------------------------Order options
+$link = get_root_url().'admin.php?page='.$page['page'].'&amp;order=';
+$template->assign('order_options',
+  array(
+    $link.'name' => l10n('Name'),
+    $link.'status' => l10n('Status'),
+    $link.'author' => l10n('Author'),
+    $link.'id' => 'Id'));
+$template->assign('order_selected', $link.$order);
+
+// +-----------------------------------------------------------------------+
+// |                     start template output                             |
+// +-----------------------------------------------------------------------+
+$plugins->sort_fs_plugins($order);
+
+foreach($plugins->fs_plugins as $plugin_id => $fs_plugin)
+{
+  $display_name = $fs_plugin['name'];
+  if (!empty($fs_plugin['uri']))
+  {
+    $display_name = '<a href="' . $fs_plugin['uri']
+                    . '" onclick="window.open(this.href); return false;">'
+                    . $display_name . '</a>';
+  }
+  $desc = $fs_plugin['description'];
+  if (!empty($fs_plugin['author']))
+  {
+    $desc .= ' (<em>';
+    if (!empty($fs_plugin['author uri']))
+    {
+      $desc .= '<a href="' . $fs_plugin['author uri'] . '">'
+               . $fs_plugin['author'] . '</a>';
+    }
+    else
+    {
+      $desc .= $fs_plugin['author'];
+    }
+    $desc .= '</em>)';
+  }
+  $tpl_plugin =
+    array('NAME' => $display_name,
+          'VERSION' => $fs_plugin['version'],
+          'DESCRIPTION' => $desc,
+          'U_ACTION' => $base_url.'&amp;plugin='.$plugin_id);
+
+  if (isset($plugins->db_plugins_by_id[$plugin_id]))
+  {
+    $tpl_plugin['STATE'] = $plugins->db_plugins_by_id[$plugin_id]['state'];
+  }
+  else
+  {
+    $tpl_plugin['STATE'] = 'uninstalled';
+  }
+  $template->append('plugins', $tpl_plugin);
+}
+
+$missing_plugin_ids = array_diff(
+    array_keys($plugins->db_plugins_by_id), array_keys($plugins->fs_plugins)
+    );
+
+foreach($missing_plugin_ids as $plugin_id)
+{
+  $action_url = $base_url.'&amp;plugin='.$plugin_id;
+
+  $template->append( 'plugins',
+      array(
+        'NAME' => $plugin_id,
+        'VERSION' => $plugins->db_plugins_by_id[$plugin_id]['version'],
+        'DESCRIPTION' => "ERROR: THIS PLUGIN IS MISSING BUT IT IS INSTALLED! UNINSTALL IT NOW !",
+        'U_ACTION' => $base_url.'&amp;plugin='.$plugin_id,
+        'STATE' => 'missing'
+      )
+    );
+}
+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'plugins');
+?>
Index: /tags/2.0.2/admin/plugins_new.php
===================================================================
--- /tags/2.0.2/admin/plugins_new.php	(revision 3278)
+++ /tags/2.0.2/admin/plugins_new.php	(revision 3278)
@@ -0,0 +1,133 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if( !defined("PHPWG_ROOT_PATH") )
+{
+  die ("Hacking attempt!");
+}
+
+include_once(PHPWG_ROOT_PATH.'admin/include/plugins.class.php');
+
+$template->set_filenames(array('plugins' => 'plugins_new.tpl'));
+
+$order = isset($_GET['order']) ? $_GET['order'] : 'date';
+$base_url = get_root_url().'admin.php?page='.$page['page'].'&order='.$order;
+
+$plugins = new plugins();
+
+//------------------------------------------------------automatic installation
+if (isset($_GET['revision']) and isset($_GET['extension']) and !is_adviser())
+{
+  $install_status = $plugins->extract_plugin_files('install', $_GET['revision'], $_GET['extension']);
+
+  redirect($base_url.'&installstatus='.$install_status);
+}
+
+//--------------------------------------------------------------install result
+if (isset($_GET['installstatus']))
+{
+  switch ($_GET['installstatus'])
+  {
+    case 'ok':
+      array_push($page['infos'],
+        l10n('plugins_install_ok'),
+        l10n('plugins_install_need_activate'));
+      break;
+
+    case 'temp_path_error':
+      array_push($page['errors'], l10n('plugins_temp_path_error'));
+      break;
+
+    case 'dl_archive_error':
+      array_push($page['errors'], l10n('plugins_dl_archive_error'));
+      break;
+
+    case 'archive_error':
+      array_push($page['errors'], l10n('plugins_archive_error'));
+      break;
+
+    default:
+      array_push($page['errors'],
+        sprintf(l10n('plugins_extract_error'), $_GET['installstatus']),
+        l10n('plugins_check_chmod'));
+  }  
+}
+
+//--------------------------------------------------------------------Tabsheet
+set_plugins_tabsheet($page['page']);
+
+//---------------------------------------------------------------Order options
+$link = get_root_url().'admin.php?page='.$page['page'].'&amp;order=';
+$template->assign('order_options',
+  array(
+    $link.'date' => l10n('Post date'),
+    $link.'revision' => l10n('plugins_revisions'),
+    $link.'name' => l10n('Name'),
+    $link.'author' => l10n('Author'),
+    $link.'downloads' => l10n('Number of downloads')));
+$template->assign('order_selected', $link.$order);
+
+// +-----------------------------------------------------------------------+
+// |                     start template output                             |
+// +-----------------------------------------------------------------------+
+if ($plugins->get_server_plugins(true))
+{
+  $plugins->sort_server_plugins($order);
+
+  foreach($plugins->server_plugins as $plugin)
+  {
+    list($date, ) = explode(' ', $plugin['revision_date']);
+
+    $ext_desc = '<i>'.l10n('Downloads').':</i> '.$plugin['extension_nb_downloads']."\r\n"
+      ."\r\n"
+      .$plugin['extension_description'];
+
+    $rev_desc = '<i>'.l10n('Version').':</i> '.$plugin['revision_name']."\r\n"
+      .'<i>'.l10n('Released on').':</i> '.$date."\r\n"
+      .'<i>'.l10n('Downloads').':</i> '.$plugin['revision_nb_downloads']."\r\n"
+      ."\r\n"
+      .$plugin['revision_description'];
+
+    $url_auto_install = htmlentities($base_url)
+      . '&amp;revision=' . $plugin['revision_id']
+      . '&amp;extension=' . $plugin['extension_id'];
+
+    $template->append('plugins', array(
+      'EXT_NAME' => $plugin['extension_name'],
+      'EXT_URL' => PEM_URL.'/extension_view.php?eid='.$plugin['extension_id'],
+      'EXT_DESC' => $ext_desc,
+      'VERSION' => $plugin['revision_name'],
+      'DATE' => $date,
+      'VER_DESC' => $rev_desc,
+      'AUTHOR' => $plugin['author_name'],
+      'URL_INSTALL' => $url_auto_install,
+      'URL_DOWNLOAD' => $plugin['download_url'] . '&amp;origin=piwigo_download'));
+  }
+}
+else
+{
+  array_push($page['errors'], l10n('plugins_server_error'));
+}
+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'plugins');
+?>
Index: /tags/2.0.2/admin/plugins_update.php
===================================================================
--- /tags/2.0.2/admin/plugins_update.php	(revision 3278)
+++ /tags/2.0.2/admin/plugins_update.php	(revision 3278)
@@ -0,0 +1,164 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if( !defined("PHPWG_ROOT_PATH") )
+{
+  die ("Hacking attempt!");
+}
+
+include_once(PHPWG_ROOT_PATH.'admin/include/plugins.class.php');
+
+$template->set_filenames(array('plugins' => 'plugins_update.tpl'));
+
+$base_url = get_root_url().'admin.php?page='.$page['page'];
+
+$plugins = new plugins();
+
+//-----------------------------------------------------------automatic upgrade
+if (isset($_GET['plugin']) and isset($_GET['revision']) and !is_adviser())
+{
+  $plugin_id = $_GET['plugin'];
+  $revision = $_GET['revision'];
+
+  if (isset($plugins->db_plugins_by_id[$plugin_id])
+    and $plugins->db_plugins_by_id[$plugin_id]['state'] == 'active')
+  {
+    $plugins->perform_action('deactivate', $plugin_id);
+
+    redirect($base_url
+      . '&revision=' . $revision
+      . '&plugin=' . $plugin_id
+      . '&reactivate=true');
+  }
+
+  $upgrade_status = $plugins->extract_plugin_files('upgrade', $revision, $plugin_id);
+
+  if (isset($_GET['reactivate']))
+  {
+    $plugins->perform_action('activate', $plugin_id);
+  }
+  redirect($base_url.'&plugin='.$plugin_id.'&upgradestatus='.$upgrade_status);
+}
+
+//--------------------------------------------------------------upgrade result
+if (isset($_GET['upgradestatus']) and isset($_GET['plugin']))
+{
+  switch ($_GET['upgradestatus'])
+  {
+    case 'ok':
+      array_push($page['infos'],
+         sprintf(
+            l10n('plugins_upgrade_ok'),
+            $plugins->fs_plugins[$_GET['plugin']]['name']));
+      break;
+
+    case 'temp_path_error':
+      array_push($page['errors'], l10n('plugins_temp_path_error'));
+      break;
+
+    case 'dl_archive_error':
+      array_push($page['errors'], l10n('plugins_dl_archive_error'));
+      break;
+
+    case 'archive_error':
+      array_push($page['errors'], l10n('plugins_archive_error'));
+      break;
+
+    default:
+      array_push($page['errors'],
+        sprintf(l10n('plugins_extract_error'), $_GET['upgradestatus']),
+        l10n('plugins_check_chmod'));
+  }  
+}
+
+//--------------------------------------------------------------------Tabsheet
+set_plugins_tabsheet($page['page']);
+
+// +-----------------------------------------------------------------------+
+// |                     start template output                             |
+// +-----------------------------------------------------------------------+
+if ($plugins->get_server_plugins())
+{
+  foreach($plugins->fs_plugins as $plugin_id => $fs_plugin)
+  {
+    if (isset($fs_plugin['extension'])
+      and isset($plugins->server_plugins[$fs_plugin['extension']]))
+    {
+      $plugin_info = $plugins->server_plugins[$fs_plugin['extension']];
+
+      list($date, ) = explode(' ', $plugin_info['revision_date']);
+
+      $ext_desc = '<i>'.l10n('Downloads').':</i> '.$plugin_info['extension_nb_downloads']."\r\n"
+        ."\r\n"
+        .$plugin_info['extension_description'];
+
+      $rev_desc = '<i>'.l10n('Version').':</i> '.$plugin_info['revision_name']."\r\n"
+        .'<i>'.l10n('Released on').':</i> '.$date."\r\n"
+        .'<i>'.l10n('Downloads').':</i> '.$plugin_info['revision_nb_downloads']."\r\n"
+        ."\r\n"
+        .$plugin_info['revision_description'];
+
+      if ($plugins->plugin_version_compare($fs_plugin['version'], $plugin_info['revision_name']))
+      {
+        // Plugin is up to date
+        $template->append('plugins_uptodate', array(
+          'URL' => PEM_URL.'/extension_view.php?eid='.$plugin_info['extension_id'],
+          'NAME' => $fs_plugin['name'],
+          'EXT_DESC' => $ext_desc,
+          'VERSION' => $fs_plugin['version'],
+          'VER_DESC' => $rev_desc));
+      }
+      else
+      {
+        // Plugin need upgrade
+        $url_auto_update = $base_url
+          . '&amp;revision=' . $plugin_info['revision_id']
+          . '&amp;plugin=' . $plugin_id;
+
+        $template->append('plugins_not_uptodate', array(
+          'EXT_NAME' => $fs_plugin['name'],
+          'EXT_URL' => PEM_URL.'/extension_view.php?eid='.$plugin_info['extension_id'],
+          'EXT_DESC' => $ext_desc,
+          'VERSION' => $fs_plugin['version'],
+          'NEW_VERSION' => $plugin_info['revision_name'],
+          'NEW_VER_DESC' => $rev_desc,
+          'URL_UPDATE' => $url_auto_update,
+          'URL_DOWNLOAD' => $plugin_info['download_url'] . '&amp;origin=piwigo_download'));
+      }
+    }
+    else
+    {
+      // Can't check plugin
+      $template->append('plugins_cant_check', array(
+        'NAME' => $fs_plugin['name'],
+        'VERSION' => $fs_plugin['version']));
+    }
+  }
+}
+else
+{
+  array_push($page['errors'], l10n('plugins_server_error'));
+}
+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'plugins');
+?>
Index: /tags/2.0.2/admin/profile.php
===================================================================
--- /tags/2.0.2/admin/profile.php	(revision 3278)
+++ /tags/2.0.2/admin/profile.php	(revision 3278)
@@ -0,0 +1,46 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if( !defined("PHPWG_ROOT_PATH") ) die ("Hacking attempt!");
+
+$edit_user = build_user( $_GET['user_id'], false );
+
+include_once(PHPWG_ROOT_PATH.'profile.php');
+
+
+$errors = array();
+if ( !is_adviser() )
+{
+  save_profile_from_post($edit_user, $errors);
+}
+
+load_profile_in_template(
+  get_root_url().'admin.php?page=profile&amp;user_id='.$edit_user['id'],
+  get_root_url().'admin.php?page=user_list',
+  $edit_user
+  );
+$page['errors'] = array_merge($page['errors'], $errors);
+
+$template->set_filename('profile', 'profile.tpl');
+$template->assign_var_from_handle('ADMIN_CONTENT', 'profile');
+?>
Index: /tags/2.0.2/admin/rating.php
===================================================================
--- /tags/2.0.2/admin/rating.php	(revision 3278)
+++ /tags/2.0.2/admin/rating.php	(revision 3278)
@@ -0,0 +1,257 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die ("Hacking attempt!");
+}
+
+include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+
+// +-----------------------------------------------------------------------+
+// | Check Access and exit when user status is not ok                      |
+// +-----------------------------------------------------------------------+
+check_status(ACCESS_ADMINISTRATOR);
+
+// +-----------------------------------------------------------------------+
+// |                            initialization                             |
+// +-----------------------------------------------------------------------+
+if (isset($_GET['start']) and is_numeric($_GET['start']))
+{
+  $start = $_GET['start'];
+}
+else
+{
+  $start = 0;
+}
+
+$elements_per_page=10;
+if (isset($_GET['display']) and is_numeric($_GET['display']))
+{
+  $elements_per_page = $_GET['display'];
+}
+
+$order_by_index=0;
+if (isset($_GET['order_by']) and is_numeric($_GET['order_by']))
+{
+  $order_by_index = $_GET['order_by'];
+}
+
+$page['user_filter'] = '';
+if (isset($_GET['users']))
+{
+  if ($_GET['users'] == 'user')
+  {
+    $page['user_filter'] = ' AND r.user_id <> '.$conf['guest_id'];
+  }
+  elseif ($_GET['users'] == 'guest')
+  {
+    $page['user_filter'] = ' AND r.user_id = '.$conf['guest_id'];
+  }
+}
+
+if (isset($_GET['del']) and !is_adviser())
+{
+  $del_params = urldecode( $_GET['del'] );
+  parse_str($del_params, $vars);
+  if ( !is_numeric($vars['e']) or !is_numeric($vars['u']) )
+  {
+    die('Hacking attempt');
+  }
+  $query = '
+DELETE FROM '. RATE_TABLE .'
+WHERE element_id=' . $vars['e'] . '
+AND user_id=' . $vars['u'] . '
+AND anonymous_id=\'' . $vars['a'] . '\'
+;';
+  pwg_query($query);
+  update_average_rate( $vars['e'] );
+}
+
+$users = array();
+$query = '
+SELECT '.$conf['user_fields']['username'].' as username, '.$conf['user_fields']['id'].' as id
+  FROM '.USERS_TABLE.'
+;';
+$result = pwg_query($query);
+while ($row = mysql_fetch_array($result))
+{
+  $users[$row['id']]=$row['username'];
+}
+
+
+$query = 'SELECT COUNT(DISTINCT(i.id))
+FROM '.RATE_TABLE.' AS r, '.IMAGES_TABLE.' AS i
+WHERE r.element_id=i.id'. $page['user_filter'] .
+';';
+list($nb_images) = mysql_fetch_row(pwg_query($query));
+
+
+// +-----------------------------------------------------------------------+
+// |                             template init                             |
+// +-----------------------------------------------------------------------+
+
+$template->set_filename('rating', 'rating.tpl');
+
+$template->assign(
+  array(
+    'NAVBAR' => create_navigation_bar(
+      PHPWG_ROOT_PATH.'admin.php'.get_query_string_diff(array('start','del')),
+      $nb_images,
+      $start,
+      $elements_per_page
+      ),
+    'F_ACTION' => PHPWG_ROOT_PATH.'admin.php',
+    'DISPLAY' => $elements_per_page,
+    'NB_ELEMENTS' => $nb_images,
+    )
+  );
+
+
+
+$available_order_by= array(
+    array(l10n('Rate date'), 'recently_rated DESC'),
+    array(l10n('Average rate'), 'average_rate DESC'),
+    array(l10n('Number of rates'), 'nb_rates DESC'),
+    array(l10n('Sum of rates'), 'sum_rates DESC'),
+    array(l10n('Controversy'), 'std_rates DESC'),
+    array(l10n('File name'), 'file DESC'),
+    array(l10n('Creation date'), 'date_creation DESC'),
+    array(l10n('Post date'), 'date_available DESC'),
+
+  );
+
+for ($i=0; $i<count($available_order_by); $i++)
+{
+  $template->append(
+    'order_by_options',
+    $available_order_by[$i][0]
+    );
+}
+$template->assign('order_by_options_selected', array($order_by_index) );
+
+
+$user_options = array(
+  'all'   => l10n('all'),
+  'user'  => l10n('Users'),
+  'guest' => l10n('Guests'),
+  );
+
+$template->assign('user_options', $user_options );
+$template->assign('user_options_selected', array(@$_GET['users']) );
+
+
+$query = '
+SELECT i.id,
+       i.path,
+       i.file,
+       i.tn_ext,
+       i.average_rate,
+       MAX(r.date)          AS recently_rated,
+       COUNT(r.rate)        AS nb_rates,
+       SUM(r.rate)          AS sum_rates,
+       ROUND(STD(r.rate),2) AS std_rates
+  FROM '.RATE_TABLE.' AS r
+    LEFT JOIN '.IMAGES_TABLE.' AS i ON r.element_id = i.id
+  WHERE 1 = 1 ' . $page['user_filter'] . '
+  GROUP BY r.element_id
+  ORDER BY ' . $available_order_by[$order_by_index][1] .'
+  LIMIT '.$start.','.$elements_per_page.'
+;';
+
+$images = array();
+$result = pwg_query($query);
+while ($row = mysql_fetch_assoc($result))
+{
+  array_push($images, $row);
+}
+
+$template->assign( 'images', array() );
+foreach ($images as $image)
+{
+  $thumbnail_src = get_thumbnail_url($image);
+
+  $image_url = PHPWG_ROOT_PATH.'admin.php?page=picture_modify'.
+            '&amp;image_id='.$image['id'];
+
+  $query = 'SELECT *
+FROM '.RATE_TABLE.' AS r
+WHERE r.element_id='.$image['id'] . '
+ORDER BY date DESC;';
+  $result = pwg_query($query);
+  $nb_rates = mysql_num_rows($result);
+
+  $tpl_image = 
+     array(
+       'U_THUMB' => $thumbnail_src,
+       'U_URL' => $image_url,
+       'AVG_RATE' => $image['average_rate'],
+       'STD_RATE' => $image['std_rates'],
+       'SUM_RATE' => $image['sum_rates'],
+       'NB_RATES' => (int)$image['nb_rates'],
+       'NB_RATES_TOTAL' => (int)$nb_rates,
+       'FILE' => $image['file'],
+       'rates'  => array()
+   );
+
+  while ($row = mysql_fetch_array($result))
+  {
+
+    $url_del = PHPWG_ROOT_PATH.'admin.php'.
+                get_query_string_diff(array('del'));
+
+    $del_param = 'e='.$image['id'].
+                 '&u='.$row['user_id'].
+                 '&a='.$row['anonymous_id'];
+
+    $url_del .= '&amp;del='.urlencode(urlencode($del_param));
+
+    if ( isset($users[$row['user_id']]) )
+    {
+      $user_rate = $users[$row['user_id']];
+    }
+    else
+    {
+      $user_rate = '? '. $row['user_id'];
+    }
+    if ( strlen($row['anonymous_id'])>0 )
+    {
+      $user_rate .= '('.$row['anonymous_id'].')';
+    }
+
+    $tpl_image['rates'][] =
+       array(
+         'DATE' => format_date($row['date']),
+         'RATE' => $row['rate'],
+         'USER' => $user_rate,
+         'U_DELETE' => $url_del
+     );
+  }
+  $template->append( 'images', $tpl_image );
+}
+
+// +-----------------------------------------------------------------------+
+// |                           sending html code                           |
+// +-----------------------------------------------------------------------+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'rating');
+?>
Index: /tags/2.0.2/admin/site_manager.php
===================================================================
--- /tags/2.0.2/admin/site_manager.php	(revision 3278)
+++ /tags/2.0.2/admin/site_manager.php	(revision 3278)
@@ -0,0 +1,309 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die ("Hacking attempt!");
+}
+
+include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+
+// +-----------------------------------------------------------------------+
+// | Check Access and exit when user status is not ok                      |
+// +-----------------------------------------------------------------------+
+check_status(ACCESS_ADMINISTRATOR);
+
+/**
+ * requests the given $url (a remote create_listing_file.php) and fills a
+ * list of lines corresponding to request output
+ *
+ * @param string $url
+ * @return void
+ */
+function remote_output($url)
+{
+  global $template, $page;
+
+  if (fetchRemote($url, $result))
+  {
+    $lines = explode("\r\n", $result);
+    // cleaning lines from HTML tags
+    foreach ($lines as $line)
+    {
+      $line = trim(strip_tags($line));
+      if (preg_match('/^PWG-([A-Z]+)-/', $line, $matches))
+      {
+        $template->append(
+          'remote_output',
+          array(
+            'CLASS' => 'remote'.ucfirst(strtolower($matches[1])),
+            'CONTENT' => $line
+           )
+         );
+      }
+    }
+  }
+  else
+  {
+    array_push($page['errors'], l10n('site_err_remote_file_not_found'));
+  }
+}
+
+
+// +-----------------------------------------------------------------------+
+// |                             template init                             |
+// +-----------------------------------------------------------------------+
+$template->set_filenames(array('site_manager'=>'site_manager.tpl'));
+
+// +-----------------------------------------------------------------------+
+// |                        new site creation form                         |
+// +-----------------------------------------------------------------------+
+if (isset($_POST['submit']) and !empty($_POST['galleries_url'])
+    and !is_adviser() )
+{
+  $is_remote = url_is_remote( $_POST['galleries_url'] );
+  $url = preg_replace('/[\/]*$/', '', $_POST['galleries_url']);
+  $url.= '/';
+  if (! $is_remote)
+  {
+    if ( ! (strpos($url, '.') === 0 ) )
+    {
+      $url = './' . $url;
+    }
+  }
+
+  // site must not exists
+  $query = '
+SELECT COUNT(id) AS count
+  FROM '.SITES_TABLE.'
+  WHERE galleries_url = \''.$url.'\'
+;';
+  $row = mysql_fetch_array(pwg_query($query));
+  if ($row['count'] > 0)
+  {
+    array_push($page['errors'],
+      l10n('site_already_exists').' ['.$url.']');
+  }
+  if (count($page['errors']) == 0)
+  {
+    if ($is_remote)
+    {
+      if ( ! isset($_POST['no_check']) )
+      {
+        $clf_url = $url.'create_listing_file.php';
+        $clf_url.= '?action=test';
+        $clf_url.= '&version='.PHPWG_VERSION;
+        if (fetchRemote($clf_url, $result))
+        {
+          $lines = explode("\r\n", $result);
+          $first_line = strip_tags($lines[0]);
+          if (!preg_match('/^PWG-INFO-2:/', $first_line))
+          {
+            array_push($page['errors'],
+                       l10n('site_err').' : '.$first_line);
+          }
+        }
+        else
+        {
+          array_push($page['errors'], l10n('site_err_remote_file_not_found') );
+        }
+      }
+    }
+    else
+    { // local directory
+      if ( ! file_exists($url) )
+      {
+        array_push($page['errors'],
+          l10n('Directory does not exist').' ['.$url.']');
+      }
+    }
+  }
+
+  if (count($page['errors']) == 0)
+  {
+    $query = '
+INSERT INTO '.SITES_TABLE.'
+  (galleries_url)
+  VALUES
+  (\''.$url.'\')
+;';
+    pwg_query($query);
+    array_push($page['infos'],
+               $url.' '.l10n('site_created'));
+  }
+}
+
+// +-----------------------------------------------------------------------+
+// |                            actions on site                            |
+// +-----------------------------------------------------------------------+
+if (isset($_GET['site']) and is_numeric($_GET['site']))
+{
+  $page['site'] = $_GET['site'];
+}
+if (isset($_GET['action']) and isset($page['site']) and !is_adviser())
+{
+  $query = '
+SELECT galleries_url
+  FROM '.SITES_TABLE.'
+  WHERE id = '.$page['site'].'
+;';
+  list($galleries_url) = mysql_fetch_array(pwg_query($query));
+  switch($_GET['action'])
+  {
+    case 'generate' :
+    {
+      $title = $galleries_url.' : '.l10n('remote_site_generate');
+      remote_output($galleries_url.'create_listing_file.php?action=generate');
+      break;
+    }
+    case 'test' :
+    {
+      $title = $galleries_url.' : '.l10n('remote_site_test');
+      remote_output($galleries_url.'create_listing_file.php?action=test&version='.PHPWG_VERSION);
+      break;
+    }
+    case 'clean' :
+    {
+      $title = $galleries_url.' : '.l10n('remote_site_clean');
+      remote_output($galleries_url.'create_listing_file.php?action=clean');
+      break;
+    }
+    case 'delete' :
+    {
+      delete_site($page['site']);
+      array_push($page['infos'],
+                 $galleries_url.' '.l10n('site_deleted'));
+      break;
+    }
+  }
+}
+
+$template->assign( array(
+  'U_HELP'    => get_root_url().'popuphelp.php?page=site_manager',
+  'F_ACTION'  => get_root_url().'admin.php'
+                .get_query_string_diff( array('action','site') )
+  ) );
+
+// +-----------------------------------------------------------------------+
+// |                           remote sites list                           |
+// +-----------------------------------------------------------------------+
+
+if ( is_file(PHPWG_ROOT_PATH.'listing.xml') )
+{
+  $xml_content = getXmlCode(PHPWG_ROOT_PATH.'listing.xml');
+  $local_listing_site_url = getAttribute(
+          getChild($xml_content, 'informations'),
+          'url'
+        );
+  if ( !url_is_remote($local_listing_site_url) )
+  {
+    $local_listing_site_url = null;
+  }
+}
+
+$query = '
+SELECT c.site_id, COUNT(DISTINCT c.id) AS nb_categories, COUNT(i.id) AS nb_images
+  FROM '.CATEGORIES_TABLE.' AS c LEFT JOIN '.IMAGES_TABLE.' AS i
+  ON c.id=i.storage_category_id 
+  WHERE c.site_id IS NOT NULL
+  GROUP BY c.site_id
+;';
+$sites_detail = hash_from_query($query, 'site_id'); 
+
+$query = '
+SELECT *
+  FROM '.SITES_TABLE.'
+;';
+$result = pwg_query($query);
+
+while ($row = mysql_fetch_array($result))
+{
+  $is_remote = url_is_remote($row['galleries_url']);
+  $base_url = PHPWG_ROOT_PATH.'admin.php';
+  $base_url.= '?page=site_manager';
+  $base_url.= '&amp;site='.$row['id'];
+  $base_url.= '&amp;action=';
+
+  $update_url = PHPWG_ROOT_PATH.'admin.php';
+  $update_url.= '?page=site_update';
+  $update_url.= '&amp;site='.$row['id'];
+  
+  $tpl_var =
+    array(
+      'NAME' => $row['galleries_url'],
+      'TYPE' => l10n( $is_remote ? 'site_remote' : 'site_local' ),
+      'CATEGORIES' => (int)@$sites_detail[$row['id']]['nb_categories'],
+      'IMAGES' => (int)@$sites_detail[$row['id']]['nb_images'],
+      'U_SYNCHRONIZE' => $update_url
+     );
+     
+   if ($is_remote)
+   {
+     $tpl_var['remote'] =
+       array(
+         'U_TEST' => $base_url.'test',
+         'U_GENERATE' => $row['galleries_url'].'create_listing_file.php?action=generate',
+         'U_CLEAN' => $base_url.'clean',
+         );
+   }
+
+  if ($row['id'] != 1)
+  {
+    $tpl_var['U_DELETE'] = $base_url.'delete';
+  }
+
+  $plugin_links = array();
+  //$plugin_links is array of array composed of U_HREF, U_HINT & U_CAPTION
+  $plugin_links =
+    trigger_event('get_admins_site_links',
+      $plugin_links, $row['id'], $is_remote);
+  $tpl_var['plugin_links'] = $plugin_links;
+
+  $template->append('sites', $tpl_var);
+
+  if ( isset($local_listing_site_url) and
+       $row['galleries_url']==$local_listing_site_url )
+  {
+    $local_listing_site_id = $row['id'];
+    $template->assign( 'local_listing',
+        array(
+          'URL' =>  $local_listing_site_url,
+          'U_SYNCHRONIZE' => $update_url.'&amp;local_listing=1'
+        )
+      );
+  }
+}
+
+if ( isset($local_listing_site_url) and !isset($local_listing_site_id) )
+{
+  $template->assign( 'local_listing',
+      array(
+        'URL' =>  $local_listing_site_url,
+        'CREATE' => true
+      )
+    );
+}
+
+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'site_manager');
+?>
Index: /tags/2.0.2/admin/site_reader_local.php
===================================================================
--- /tags/2.0.2/admin/site_reader_local.php	(revision 3278)
+++ /tags/2.0.2/admin/site_reader_local.php	(revision 3278)
@@ -0,0 +1,265 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// provides data for site synchronization from the local file system
+class LocalSiteReader
+{
+
+var $site_url;
+
+function LocalSiteReader($url)
+{
+  $this->site_url = $url;
+}
+
+/**
+ * Is this local site ok ?
+ *
+ * @return true on success, false otherwise
+ */
+function open()
+{
+  global $errors;
+
+  if (!is_dir($this->site_url))
+  {
+    array_push(
+      $errors,
+      array(
+        'path' => $this->site_url,
+        'type' => 'PWG-ERROR-NO-FS'
+        )
+      );
+
+    return false;
+  }
+
+  return true;
+}
+
+// retrieve file system sub-directories fulldirs
+function get_full_directories($basedir)
+{
+  $fs_fulldirs = get_fs_directories($basedir);
+  return $fs_fulldirs;
+}
+
+/**
+ * Returns an array with all file system files according to $conf['file_ext']
+ * and $conf['picture_ext']
+ * @param string $path recurse in this directory
+ * @return array like "pic.jpg"=>array('tn_ext'=>'jpg' ... )
+ */
+function get_elements($path)
+{
+  global $conf;
+  if (!isset($conf['flip_file_ext']))
+  {
+    $conf['flip_file_ext'] = array_flip($conf['file_ext']);
+  }
+
+  $subdirs = array();
+  $fs = array();
+  if (is_dir($path) && $contents = opendir($path) )
+  {
+    while (($node = readdir($contents)) !== false)
+    {
+      if (is_file($path.'/'.$node))
+      {
+        $extension = get_extension($node);
+        $filename_wo_ext = get_filename_wo_extension($node);
+
+        if ( isset($conf['flip_file_ext'][$extension]) )
+        {
+          $tn_ext = $this->get_tn_ext($path, $filename_wo_ext);
+          $fs[ $path.'/'.$node ] = array(
+            'tn_ext' => $tn_ext,
+            );
+        }
+      }
+      elseif (is_dir($path.'/'.$node)
+               and $node != '.'
+               and $node != '..'
+               and $node != 'pwg_high'
+               and $node != 'pwg_representative'
+               and $node != 'thumbnail' )
+      {
+        array_push($subdirs, $node);
+      }
+    } //end while readdir
+    closedir($contents);
+
+    foreach ($subdirs as $subdir)
+    {
+      $tmp_fs = $this->get_elements($path.'/'.$subdir);
+      $fs = array_merge($fs, $tmp_fs);
+    }
+  } //end if is_dir
+  return $fs;
+}
+
+// returns the name of the attributes that are supported for
+// files update/synchronization
+function get_update_attributes()
+{
+  return array('tn_ext', 'has_high', 'representative_ext');
+}
+
+function get_element_update_attributes($file)
+{
+  global $conf;
+  $data = array();
+
+  $filename = basename($file);
+  $dirname = dirname($file);
+  $filename_wo_ext = get_filename_wo_extension($filename);
+  $extension = get_extension($filename);
+
+  $data['tn_ext'] = $this->get_tn_ext($dirname, $filename_wo_ext);
+  $data['has_high'] = $this->get_has_high($dirname, $filename);
+
+  if ( !isset($conf['flip_picture_ext'][$extension]) )
+  {
+    $data['representative_ext'] = $this->get_representative_ext(
+        $dirname, $filename_wo_ext
+      );
+  }
+  return $data;
+}
+
+// returns the name of the attributes that are supported for
+// metadata update/synchronization according to configuration
+function get_metadata_attributes()
+{
+  global $conf;
+
+  $update_fields = array('filesize', 'width', 'height', 'high_filesize');
+
+  if ($conf['use_exif'])
+  {
+    $update_fields =
+      array_merge(
+        $update_fields,
+        array_keys($conf['use_exif_mapping'])
+        );
+  }
+
+  if ($conf['use_iptc'])
+  {
+    $update_fields =
+      array_merge(
+        $update_fields,
+        array_keys($conf['use_iptc_mapping'])
+        );
+  }
+
+  return $update_fields;
+}
+
+// returns a hash of attributes (metadata+filesize+width,...) for file
+function get_element_metadata($file, $has_high = false)
+{
+  global $conf;
+  if (!is_file($file))
+  {
+    return null;
+  }
+
+  $data = array();
+
+  $data['filesize'] = floor(filesize($file)/1024);
+
+  if ($image_size = @getimagesize($file))
+  {
+    $data['width'] = $image_size[0];
+    $data['height'] = $image_size[1];
+  }
+
+  if ($has_high)
+  {
+    $high_file = dirname($file).'/pwg_high/'.basename($file);
+    
+    $data['high_filesize'] = floor(filesize($high_file)/1024);
+  }
+  
+  if ($conf['use_exif'])
+  {
+    $data = array_merge($data, get_sync_exif_data($file) );
+  }
+
+  if ($conf['use_iptc'])
+  {
+    $data = array_merge($data, get_sync_iptc_data($file) );
+  }
+
+  return $data;
+}
+
+
+//-------------------------------------------------- private functions --------
+function get_representative_ext($path, $filename_wo_ext)
+{
+  global $conf;
+  $base_test = $path.'/pwg_representative/'.$filename_wo_ext.'.';
+  foreach ($conf['picture_ext'] as $ext)
+  {
+    $test = $base_test.$ext;
+    if (is_file($test))
+    {
+      return $ext;
+    }
+  }
+  return null;
+}
+
+function get_tn_ext($path, $filename_wo_ext)
+{
+  global $conf;
+
+  $base_test =
+    $path.'/thumbnail/'.$conf['prefix_thumbnail'].$filename_wo_ext.'.';
+
+  foreach ($conf['picture_ext'] as $ext)
+  {
+    $test = $base_test.$ext;
+    if (is_file($test))
+    {
+      return $ext;
+    }
+  }
+
+  return null;
+}
+
+function get_has_high($path, $filename)
+{
+  if (is_file($path.'/pwg_high/'.$filename))
+  {
+    return 'true';
+  }
+
+  return null;
+}
+
+}
+?>
Index: /tags/2.0.2/admin/site_reader_remote.php
===================================================================
--- /tags/2.0.2/admin/site_reader_remote.php	(revision 3278)
+++ /tags/2.0.2/admin/site_reader_remote.php	(revision 3278)
@@ -0,0 +1,249 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+
+// provides data for site synchronization from a remote listing.xml
+class RemoteSiteReader
+{
+
+var $site_url;
+var $listing_url;
+var $site_dirs;
+var $site_files;
+var $insert_attributes;
+var $metadata_attributes;
+
+function RemoteSiteReader($url, $listing_url)
+{
+  $this->site_url = $url;
+  $this->insert_attributes = array(
+    'tn_ext',
+    );
+  $this->update_attributes = array(
+    'tn_ext', 'representative_ext', 'has_high',
+    );
+  $this->metadata_attributes = array(
+    'filesize', 'width', 'height', 'high_filesize'
+    );
+
+  if (!isset($listing_url))
+  {
+    $this->listing_url = $this->site_url.'listing.xml';
+  }
+  else
+  {
+    $this->listing_url = $listing_url;
+  }
+}
+
+/**
+ * Is this remote site ok ?
+ *
+ * @return true on success, false otherwise
+ */
+function open()
+{
+  global $errors;
+
+  if ($xml_content = getXmlCode($this->listing_url))
+  {
+    $this->site_dirs = array();
+    $this->site_files = array();
+    $info_xml_element = getChild($xml_content, 'informations');
+    if (getAttribute($info_xml_element , 'phpwg_version') != PHPWG_VERSION)
+    {
+      array_push(
+        $errors,
+        array(
+          'path' => $this->listing_url,
+          'type' => 'PWG-ERROR-VERSION'
+          )
+        );
+
+      return false;
+    }
+
+    $additional_metadata = getAttribute($info_xml_element, 'metadata');
+
+    if ($additional_metadata != '')
+    {
+      $this->metadata_attributes = array_merge(
+        $this->metadata_attributes,
+        explode(',', $additional_metadata)
+        );
+    }
+    
+    $this->build_structure($xml_content, '', 0);
+
+    return true;
+  }
+  else
+  {
+    array_push(
+      $errors,
+      array(
+        'path' => $this->listing_url,
+        'type' => 'PWG-ERROR-NOLISTING'
+        )
+      );
+
+    return false;
+  }
+}
+
+// retrieve xml sub-directories fulldirs
+function get_full_directories($basedir)
+{
+  $dirs = array();
+  foreach ( array_keys($this->site_dirs) as $dir)
+  {
+    $full_dir = $this->site_url . $dir;
+    if ($full_dir != $basedir
+        and strpos($full_dir, $basedir) === 0
+      )
+    {
+      array_push($dirs, $full_dir);
+    }
+  }
+  return $dirs;
+}
+
+/**
+ * Returns a hash with all elements (images and files) inside the full $path
+ * according to listing.xml
+ * @param string $path recurse in this directory only
+ * @return array like "pic.jpg"=>array('tn_ext'=>'jpg' ... )
+ */
+function get_elements($path)
+{
+  $elements = array();
+  foreach ( $this->site_dirs as $dir=>$files)
+  {
+    $full_dir = $this->site_url . $dir;
+    if (strpos($full_dir, $path) === 0)
+    {
+      foreach ($files as $file)
+      {
+        $data = $this->get_element_attributes(
+          $file,
+          $this->insert_attributes
+          );
+        $elements[$file] = $data;
+      }
+    }
+  }
+
+  return $elements;
+}
+
+// returns the name of the attributes that are supported for
+// files update/synchronization
+function get_update_attributes()
+{
+  return $this->update_attributes;
+}
+
+function get_element_update_attributes($file)
+{
+  return $this->get_element_attributes(
+    $file,
+    $this->update_attributes
+    );
+}
+
+// returns the name of the attributes that are supported for
+// metadata update/synchronization according to listing.xml
+function get_metadata_attributes()
+{
+  return $this->metadata_attributes;
+}
+
+// returns a hash of attributes (metadata+width,...) for file
+function get_element_metadata($file, $has_high = false)
+{
+  return $this->get_element_attributes(
+    $file,
+    $this->metadata_attributes
+    );
+}
+
+//-------------------------------------------------- private functions --------
+/**
+ * Returns a hash of image/file attributes
+ * @param string $file fully qualified file name
+ * @param array $attributes specifies which attributes to retrieve
+ *  returned
+*/
+function get_element_attributes($file, $attributes)
+{
+  $xml_element = $this->site_files[$file];
+  if (!isset($xml_element))
+  {
+    return null;
+  }
+  $data = array();
+  foreach($attributes as $att)
+  {
+    if (getAttribute($xml_element, $att) != '')
+    {
+      $val = getAttribute($xml_element, $att);
+      $data[$att] = addslashes($val);
+    }
+  }
+  return $data;
+}
+
+// recursively parse the xml_content for later usage
+function build_structure($xml_content, $basedir, $level)
+{
+  $temp_dirs = getChildren($xml_content, 'dir'.$level);
+  foreach ($temp_dirs as $temp_dir)
+  {
+    $dir_name = $basedir;
+    if ($dir_name != '' )
+    {
+      $dir_name .= '/';
+    }
+    $dir_name .= getAttribute($temp_dir, 'name');
+    $this->site_dirs[ $dir_name ] = array();
+    $this->build_structure($temp_dir, $dir_name, $level+1);
+  }
+
+  if ($basedir != '')
+  {
+    $xml_elements = getChildren(
+      getChild($xml_content, 'root'),
+      'element'
+      );
+    foreach ($xml_elements as $xml_element)
+    {
+      $path = getAttribute($xml_element, 'path');
+      $this->site_files[$path] = $xml_element;
+      array_push($this->site_dirs[$basedir], $path);
+    }
+  }
+}
+
+}
+
+?>
Index: /tags/2.0.2/admin/site_update.php
===================================================================
--- /tags/2.0.2/admin/site_update.php	(revision 3278)
+++ /tags/2.0.2/admin/site_update.php	(revision 3278)
@@ -0,0 +1,959 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+
+// +-----------------------------------------------------------------------+
+// | Check Access and exit when user status is not ok                      |
+// +-----------------------------------------------------------------------+
+check_status(ACCESS_ADMINISTRATOR);
+
+if (!is_numeric($_GET['site']))
+{
+  die ('site param missing or invalid');
+}
+$site_id = $_GET['site'];
+
+$query='
+SELECT galleries_url
+  FROM '.SITES_TABLE.'
+  WHERE id = '.$site_id;
+list($site_url) = mysql_fetch_row(pwg_query($query));
+if (!isset($site_url))
+{
+  die('site '.$site_id.' does not exist');
+}
+$site_is_remote = url_is_remote($site_url);
+
+list($dbnow) = mysql_fetch_row(pwg_query('SELECT NOW();'));
+define('CURRENT_DATE', $dbnow);
+
+$error_labels = array(
+  'PWG-UPDATE-1' => array(
+    l10n('update_wrong_dirname_short'),
+    l10n('update_wrong_dirname_info')
+    ),
+  'PWG-UPDATE-2' => array(
+    l10n('update_missing_tn_short'),
+    l10n('update_missing_tn_info').implode(',', $conf['picture_ext'])
+    ),
+  'PWG-ERROR-NO-FS' => array(
+    l10n('update_missing_file_or_dir'),
+    l10n('update_missing_file_or_dir_info')
+    ),
+  'PWG-ERROR-VERSION' => array(
+    l10n('update_err_pwg_version_differs'),
+    l10n('update_err_pwg_version_differs_info')
+    ),
+  'PWG-ERROR-NOLISTING' => array(
+    l10n('update_err_remote_listing_not_found'),
+    l10n('update_err_remote_listing_not_found_info')
+    )
+  );
+$errors = array();
+$infos = array();
+
+if ($site_is_remote)
+{
+  include_once(PHPWG_ROOT_PATH.'admin/site_reader_remote.php');
+  $local_listing = null;
+  if ( isset($_GET['local_listing'])
+      and $_GET['local_listing'] )
+  {
+    $local_listing = PHPWG_ROOT_PATH.'listing.xml';
+  }
+  $site_reader = new RemoteSiteReader($site_url, $local_listing);
+}
+else
+{
+  include_once( PHPWG_ROOT_PATH.'admin/site_reader_local.php');
+  $site_reader = new LocalSiteReader($site_url);
+}
+
+$general_failure = true;
+if (isset($_POST['submit']))
+{
+  if (!isset($conf['flip_picture_ext']))
+  {
+    $conf['flip_picture_ext'] = array_flip($conf['picture_ext']);
+  }
+  if ($site_reader->open())
+  {
+    $general_failure = false;
+  }
+
+  // shall we simulate only
+  if ((isset($_POST['simulate']) and $_POST['simulate'] == 1) or is_adviser())
+  {
+    $simulate = true;
+  }
+  else
+  {
+    $simulate = false;
+  }
+}
+
+// +-----------------------------------------------------------------------+
+// |                      directories / categories                         |
+// +-----------------------------------------------------------------------+
+if (isset($_POST['submit'])
+    and ($_POST['sync'] == 'dirs' or $_POST['sync'] == 'files'))
+{
+  $counts['new_categories'] = 0;
+  $counts['del_categories'] = 0;
+  $counts['del_elements'] = 0;
+  $counts['new_elements'] = 0;
+  $counts['upd_elements'] = 0;
+}
+
+
+if (isset($_POST['submit'])
+    and ($_POST['sync'] == 'dirs' or $_POST['sync'] == 'files')
+    and !$general_failure)
+{
+  $start = get_moment();
+  // which categories to update ?
+  $query = '
+SELECT id, uppercats, global_rank, status, visible
+  FROM '.CATEGORIES_TABLE.'
+  WHERE dir IS NOT NULL
+    AND site_id = '.$site_id;
+  if (isset($_POST['cat']) and is_numeric($_POST['cat']))
+  {
+    if (isset($_POST['subcats-included']) and $_POST['subcats-included'] == 1)
+    {
+      $query.= '
+    AND uppercats REGEXP \'(^|,)'.$_POST['cat'].'(,|$)\'
+';
+    }
+    else
+    {
+      $query.= '
+    AND id = '.$_POST['cat'].'
+';
+    }
+  }
+  $db_categories = hash_from_query($query, 'id');
+
+  // get categort full directories in an array for comparison with file
+  // system directory tree
+  $db_fulldirs = get_fulldirs(array_keys($db_categories));
+
+  // what is the base directory to search file system sub-directories ?
+  if (isset($_POST['cat']) and is_numeric($_POST['cat']))
+  {
+    $basedir = $db_fulldirs[$_POST['cat']];
+  }
+  else
+  {
+    $basedir = preg_replace('#/*$#', '', $site_url);
+  }
+
+  // we need to have fulldirs as keys to make efficient comparison
+  $db_fulldirs = array_flip($db_fulldirs);
+
+  // finding next rank for each id_uppercat. By default, each category id
+  // has 1 for next rank on its sub-categories to create
+  $next_rank['NULL'] = 1;
+
+  $query = '
+SELECT id
+  FROM '.CATEGORIES_TABLE;
+  $result = pwg_query($query);
+  while ($row = mysql_fetch_array($result))
+  {
+    $next_rank[$row['id']] = 1;
+  }
+
+  // let's see if some categories already have some sub-categories...
+  $query = '
+SELECT id_uppercat, MAX(rank)+1 AS next_rank
+  FROM '.CATEGORIES_TABLE.'
+  GROUP BY id_uppercat';
+  $result = pwg_query($query);
+  while ($row = mysql_fetch_array($result))
+  {
+    // for the id_uppercat NULL, we write 'NULL' and not the empty string
+    if (!isset($row['id_uppercat']) or $row['id_uppercat'] == '')
+    {
+      $row['id_uppercat'] = 'NULL';
+    }
+    $next_rank[$row['id_uppercat']] = $row['next_rank'];
+  }
+
+  // next category id available
+  $query = '
+SELECT IF(MAX(id)+1 IS NULL, 1, MAX(id)+1) AS next_id
+  FROM '.CATEGORIES_TABLE;
+  list($next_id) = mysql_fetch_array(pwg_query($query));
+
+  // retrieve sub-directories fulldirs from the site reader
+  $fs_fulldirs = $site_reader->get_full_directories($basedir);
+
+  // get_full_directories doesn't include the base directory, so if it's a
+  // category directory, we need to include it in our array
+  if (isset($_POST['cat']))
+  {
+    array_push($fs_fulldirs, $basedir);
+  }
+  // If $_POST['subcats-included'] != 1 ("Search in subcategories" is unchecked)
+  // $db_fulldirs doesn't include any subdirectories and $fs_fulldirs does
+  // So $fs_fulldirs will be limited to the selected basedir
+  // (if that one is in $fs_fulldirs)
+  if (!isset($_POST['subcats-included']) or $_POST['subcats-included'] != 1)
+  {
+    $fs_fulldirs = array_intersect($fs_fulldirs, array_keys($db_fulldirs));
+  }
+  $inserts = array();
+  // new categories are the directories not present yet in the database
+  foreach (array_diff($fs_fulldirs, array_keys($db_fulldirs)) as $fulldir)
+  {
+    $dir = basename($fulldir);
+    if (preg_match('/^[a-zA-Z0-9-_.]+$/', $dir))
+    {
+      $insert = array(
+        'id'          => $next_id++,
+        'dir'         => $dir,
+        'name'        => str_replace('_', ' ', $dir),
+        'site_id'     => $site_id,
+        'commentable' =>
+          boolean_to_string($conf['newcat_default_commentable']),
+        'uploadable'  => $site_is_remote
+          ? 'false'
+          : boolean_to_string($conf['newcat_default_uploadable']),
+        'status'      => $conf{'newcat_default_status'},
+        'visible'     => boolean_to_string($conf{'newcat_default_visible'}),
+        );
+
+      if (isset($db_fulldirs[dirname($fulldir)]))
+      {
+        $parent = $db_fulldirs[dirname($fulldir)];
+
+        $insert{'id_uppercat'} = $parent;
+        $insert{'uppercats'} =
+          $db_categories[$parent]['uppercats'].','.$insert{'id'};
+        $insert{'rank'} = $next_rank[$parent]++;
+        $insert{'global_rank'} =
+          $db_categories[$parent]['global_rank'].'.'.$insert{'rank'};
+        if ('private' == $db_categories[$parent]['status'])
+        {
+          $insert{'status'} = 'private';
+        }
+        if ('false' == $db_categories[$parent]['visible'])
+        {
+          $insert{'visible'} = 'false';
+        }
+      }
+      else
+      {
+        $insert{'uppercats'} = $insert{'id'};
+        $insert{'rank'} = $next_rank['NULL']++;
+        $insert{'global_rank'} = $insert{'rank'};
+      }
+
+      array_push($inserts, $insert);
+      array_push(
+        $infos,
+        array(
+          'path' => $fulldir,
+          'info' => l10n('update_research_added')
+          )
+        );
+
+      // add the new category to $db_categories and $db_fulldirs array
+      $db_categories[$insert{'id'}] =
+        array(
+          'id' => $insert{'id'},
+          'status' => $insert{'status'},
+          'visible' => $insert{'visible'},
+          'uppercats' => $insert{'uppercats'},
+          'global_rank' => $insert{'global_rank'}
+          );
+      $db_fulldirs[$fulldir] = $insert{'id'};
+      $next_rank[$insert{'id'}] = 1;
+    }
+    else
+    {
+      array_push(
+        $errors,
+        array(
+          'path' => $fulldir,
+          'type' => 'PWG-UPDATE-1'
+          )
+        );
+    }
+  }
+
+  if (count($inserts) > 0)
+  {
+    if (!$simulate)
+    {
+      $dbfields = array(
+        'id','dir','name','site_id','id_uppercat','uppercats','commentable',
+        'uploadable','visible','status','rank','global_rank'
+        );
+      mass_inserts(CATEGORIES_TABLE, $dbfields, $inserts);
+    }
+
+    $counts['new_categories'] = count($inserts);
+  }
+
+  // to delete categories
+  $to_delete = array();
+  foreach (array_diff(array_keys($db_fulldirs), $fs_fulldirs) as $fulldir)
+  {
+    array_push($to_delete, $db_fulldirs[$fulldir]);
+    unset($db_fulldirs[$fulldir]);
+    array_push($infos, array('path' => $fulldir,
+                             'info' => l10n('update_research_deleted')));
+  }
+  if (count($to_delete) > 0)
+  {
+    if (!$simulate)
+    {
+      delete_categories($to_delete);
+    }
+    $counts['del_categories'] = count($to_delete);
+  }
+
+  $template->append('footer_elements', '<!-- scanning dirs : '
+    . get_elapsed_time($start, get_moment())
+    . ' -->' );
+}
+// +-----------------------------------------------------------------------+
+// |                           files / elements                            |
+// +-----------------------------------------------------------------------+
+if (isset($_POST['submit']) and $_POST['sync'] == 'files'
+      and !$general_failure)
+{
+  $start_files = get_moment();
+  $start= $start_files;
+
+  $fs = $site_reader->get_elements($basedir);
+  $template->append('footer_elements', '<!-- get_elements: '
+    . get_elapsed_time($start, get_moment())
+    . ' -->' );
+
+  $cat_ids = array_diff(array_keys($db_categories), $to_delete);
+
+  $db_elements = array();
+  $db_unvalidated = array();
+
+  if (count($cat_ids) > 0)
+  {
+    $query = '
+SELECT id, path
+  FROM '.IMAGES_TABLE.'
+  WHERE storage_category_id IN ('
+      .wordwrap(
+        implode(', ', $cat_ids),
+        80,
+        "\n"
+        ).')';
+    $db_elements = simple_hash_from_query($query, 'id', 'path');
+
+    // searching the unvalidated waiting elements (they must not be taken into
+    // account)
+    $query = '
+SELECT file,storage_category_id
+  FROM '.WAITING_TABLE.'
+  WHERE storage_category_id IN (
+'.wordwrap(implode(', ', $cat_ids), 80, "\n").')
+    AND validated = \'false\'';
+    $result = pwg_query($query);
+    while ($row = mysql_fetch_array($result))
+    {
+      array_push(
+        $db_unvalidated,
+        array_search(
+          $row['storage_category_id'],
+          $db_fulldirs)
+        .'/'.$row['file']
+        );
+    }
+  }
+
+  // next element id available
+  $query = '
+SELECT IF(MAX(id)+1 IS NULL, 1, MAX(id)+1) AS next_element_id
+  FROM '.IMAGES_TABLE;
+  list($next_element_id) = mysql_fetch_array(pwg_query($query));
+
+  $start = get_moment();
+
+  $inserts = array();
+  $insert_links = array();
+
+  foreach (array_diff(array_keys($fs), $db_elements, $db_unvalidated) as $path)
+  {
+    $insert = array();
+    // storage category must exist
+    $dirname = dirname($path);
+    if (!isset($db_fulldirs[$dirname]))
+    {
+      continue;
+    }
+    $filename = basename($path);
+    if (!preg_match('/^[a-zA-Z0-9-_.]+$/', $filename))
+    {
+      array_push(
+        $errors,
+        array(
+          'path' => $path,
+          'type' => 'PWG-UPDATE-1'
+          )
+        );
+
+      continue;
+    }
+
+    if ( isset( $conf['flip_picture_ext'][get_extension($filename)] )
+          and !isset($fs[$path]['tn_ext']) )
+    { // For a picture thumbnail is mandatory and for non picture element,
+      // thumbnail and representative are optionnal
+      array_push(
+        $errors,
+        array(
+          'path' => $path,
+          'type' => 'PWG-UPDATE-2'
+          )
+        );
+    }
+    else
+    {
+      $insert = array(
+        'id'             => $next_element_id++,
+        'file'           => $filename,
+        'date_available' => CURRENT_DATE,
+        'path'           => $path,
+        'tn_ext'         => isset($fs[$path]['tn_ext'])
+          ? $fs[$path]['tn_ext']
+          : null,
+        'storage_category_id' => $db_fulldirs[$dirname],
+        );
+
+      if ( $_POST['privacy_level']!=0 )
+      {
+        $insert['level'] = $_POST['privacy_level'];
+      }
+
+      array_push(
+        $inserts,
+        $insert
+        );
+
+      array_push(
+        $insert_links,
+        array(
+          'image_id'    => $insert{'id'},
+          'category_id' => $insert['storage_category_id'],
+          )
+        );
+
+      array_push(
+        $infos,
+        array(
+          'path' => $insert{'path'},
+          'info' => l10n('update_research_added')
+          )
+        );
+
+      $caddiables[] = $insert['id'];
+    }
+  }
+
+  if (count($inserts) > 0)
+  {
+    if (!$simulate)
+    {
+      // inserts all new elements
+      mass_inserts(
+        IMAGES_TABLE,
+        array_keys($inserts[0]),
+        $inserts
+        );
+
+      // inserts all links between new elements and their storage category
+      mass_inserts(
+        IMAGE_CATEGORY_TABLE,
+        array_keys($insert_links[0]),
+        $insert_links
+        );
+
+      // add new elements to caddie
+      if (isset($_POST['add_to_caddie']) and $_POST['add_to_caddie'] == 1)
+      {
+        fill_caddie($caddiables);
+      }
+    }
+    $counts['new_elements'] = count($inserts);
+  }
+
+  // delete elements that are in database but not in the filesystem
+  $to_delete_elements = array();
+  foreach (array_diff($db_elements, array_keys($fs)) as $path)
+  {
+    array_push($to_delete_elements, array_search($path, $db_elements));
+    array_push($infos, array('path' => $path,
+                             'info' => l10n('update_research_deleted')));
+  }
+  if (count($to_delete_elements) > 0)
+  {
+    if (!$simulate)
+    {
+      delete_elements($to_delete_elements);
+    }
+    $counts['del_elements'] = count($to_delete_elements);
+  }
+
+  $template->append('footer_elements', '<!-- scanning files : '
+    . get_elapsed_time($start_files, get_moment())
+    . ' -->' );
+
+  // retrieving informations given by uploaders
+  if (!$simulate and count($cat_ids) > 0)
+  {
+    $query = '
+SELECT id,file,storage_category_id,infos
+  FROM '.WAITING_TABLE.'
+  WHERE storage_category_id IN (
+'.wordwrap(implode(', ', $cat_ids), 80, "\n").')
+    AND validated = \'true\'';
+    $result = pwg_query($query);
+
+    $datas = array();
+    $fields =
+      array(
+        'primary' => array('id'),
+        'update'  => array('date_creation', 'author', 'name', 'comment')
+        );
+
+    $waiting_to_delete = array();
+
+    while ($row = mysql_fetch_array($result))
+    {
+      $data = array();
+
+      $query = '
+SELECT id
+  FROM '.IMAGES_TABLE.'
+  WHERE storage_category_id = '.$row['storage_category_id'].'
+    AND file = \''.$row['file'].'\'';
+      list($data['id']) = mysql_fetch_array(pwg_query($query));
+
+      foreach ($fields['update'] as $field)
+      {
+        $data[$field] = addslashes( getAttribute($row['infos'], $field) );
+      }
+
+      array_push($datas, $data);
+      array_push($waiting_to_delete, $row['id']);
+    }
+
+    if (count($datas) > 0)
+    {
+      mass_updates(IMAGES_TABLE, $fields, $datas);
+
+      // delete now useless waiting elements
+      $query = '
+DELETE
+  FROM '.WAITING_TABLE.'
+  WHERE id IN ('.implode(',', $waiting_to_delete).')
+;';
+      pwg_query($query);
+    }
+  }
+}
+
+// +-----------------------------------------------------------------------+
+// |                          synchronize files                            |
+// +-----------------------------------------------------------------------+
+if (isset($_POST['submit'])
+    and ($_POST['sync'] == 'dirs' or $_POST['sync'] == 'files')
+    and !$general_failure )
+{
+  if (!$simulate)
+  {
+    $start = get_moment();
+    update_category('all');
+    $template->append('footer_elements', '<!-- update_category(all) : '
+      . get_elapsed_time($start,get_moment())
+      . ' -->' );
+    $start = get_moment();
+    update_global_rank();
+    $template->append('footer_elements', '<!-- ordering categories : '
+      . get_elapsed_time($start, get_moment())
+      . ' -->');
+  }
+
+  if ($_POST['sync'] == 'files')
+  {
+    $start = get_moment();
+    $opts['category_id'] = '';
+    $opts['recursive'] = true;
+    if (isset($_POST['cat']))
+    {
+      $opts['category_id'] = $_POST['cat'];
+      if (!isset($_POST['subcats-included']) or $_POST['subcats-included'] != 1)
+      {
+        $opts['recursive'] = false;
+      }
+    }
+    $files = get_filelist($opts['category_id'], $site_id,
+                          $opts['recursive'],
+                          false);
+    $template->append('footer_elements', '<!-- get_filelist : '
+      . get_elapsed_time($start, get_moment())
+      . ' -->');
+    $start = get_moment();
+
+    $datas = array();
+    foreach ( $files as $id=>$file )
+    {
+      $data = $site_reader->get_element_update_attributes($file);
+      if ( !is_array($data) )
+      {
+        continue;
+      }
+      $extension = get_extension($file);
+      if ( isset($conf['flip_picture_ext'][$extension]) )
+      {
+        if ( !isset($data['tn_ext']) )
+        {
+          array_push(
+            $errors,
+            array(
+              'path' => $file,
+              'type' => 'PWG-UPDATE-2'
+              )
+            );
+          continue;
+        }
+      }
+
+      $data['id']=$id;
+      array_push($datas, $data);
+    } // end foreach file
+
+    $counts['upd_elements'] = count($datas);
+    if (!$simulate and count($datas)>0 )
+    {
+      mass_updates(
+        IMAGES_TABLE,
+        // fields
+        array(
+          'primary' => array('id'),
+          'update'  => $site_reader->get_update_attributes(),
+          ),
+        $datas
+        );
+    }
+    $template->append('footer_elements', '<!-- update files : '
+      . get_elapsed_time($start,get_moment())
+      . ' -->');
+  }// end if sync files
+}
+
+// +-----------------------------------------------------------------------+
+// |                          synchronize files                            |
+// +-----------------------------------------------------------------------+
+if (isset($_POST['submit'])
+    and ($_POST['sync'] == 'dirs' or $_POST['sync'] == 'files'))
+{
+  $template->assign(
+    'update_result',
+    array(
+      'NB_NEW_CATEGORIES'=>$counts['new_categories'],
+      'NB_DEL_CATEGORIES'=>$counts['del_categories'],
+      'NB_NEW_ELEMENTS'=>$counts['new_elements'],
+      'NB_DEL_ELEMENTS'=>$counts['del_elements'],
+      'NB_UPD_ELEMENTS'=>$counts['upd_elements'],
+      'NB_ERRORS'=>count($errors),
+      ));
+}
+
+// +-----------------------------------------------------------------------+
+// |                          synchronize metadata                         |
+// +-----------------------------------------------------------------------+
+if (isset($_POST['submit']) and isset($_POST['sync_meta'])
+         and !$general_failure)
+{
+  // sync only never synchronized files ?
+  $opts['only_new'] = isset($_POST['meta_all']) ? false : true;
+  $opts['category_id'] = '';
+  $opts['recursive'] = true;
+
+  if (isset($_POST['cat']))
+  {
+    $opts['category_id'] = $_POST['cat'];
+    // recursive ?
+    if (!isset($_POST['subcats-included']) or $_POST['subcats-included'] != 1)
+    {
+      $opts['recursive'] = false;
+    }
+  }
+  $start = get_moment();
+  $files = get_filelist($opts['category_id'], $site_id,
+                        $opts['recursive'],
+                        $opts['only_new']);
+
+  $template->append('footer_elements', '<!-- get_filelist : '
+    . get_elapsed_time($start, get_moment())
+    . ' -->');
+
+  $start = get_moment();
+  $datas = array();
+  $tags_of = array();
+
+  $has_high_images = array();
+
+  $image_ids = array();
+  foreach ($files as $id => $file)
+  {
+    array_push($image_ids, $id);
+  }
+
+  if (count($image_ids) > 0)
+  {
+    $query = '
+SELECT id
+  FROM '.IMAGES_TABLE.'
+  WHERE has_high = \'true\'
+    AND id IN (
+'.wordwrap(implode(', ', $image_ids), 80, "\n").'
+)';
+    $has_high_images = array_from_query($query, 'id' );
+  }
+
+  foreach ( $files as $id=>$file )
+  {
+    $data = $site_reader->get_element_metadata(
+      $file,
+      in_array($id, $has_high_images)
+      );
+
+    if ( is_array($data) )
+    {
+      $data['date_metadata_update'] = CURRENT_DATE;
+      $data['id']=$id;
+      array_push($datas, $data);
+
+      foreach (array('keywords', 'tags') as $key)
+      {
+        if (isset($data[$key]))
+        {
+          if (!isset($tags_of[$id]))
+          {
+            $tags_of[$id] = array();
+          }
+
+          foreach (explode(',', $data[$key]) as $tag_name)
+          {
+            array_push(
+              $tags_of[$id],
+              tag_id_from_tag_name($tag_name)
+              );
+          }
+        }
+      }
+    }
+    else
+    {
+      array_push($errors, array('path' => $file, 'type' => 'PWG-ERROR-NO-FS'));
+    }
+  }
+
+  if (!$simulate)
+  {
+    if (count($datas) > 0)
+    {
+      mass_updates(
+        IMAGES_TABLE,
+        // fields
+        array(
+          'primary' => array('id'),
+          'update'  => array_unique(
+            array_merge(
+              array_diff(
+                $site_reader->get_metadata_attributes(),
+                // keywords and tags fields are managed separately
+                array('keywords', 'tags')
+                ),
+              array('date_metadata_update'))
+            )
+          ),
+        $datas,
+        isset($_POST['meta_empty_overrides']) ? 0 : MASS_UPDATES_SKIP_EMPTY
+        );
+    }
+    set_tags_of($tags_of);
+  }
+
+  $template->append('footer_elements', '<!-- metadata update : '
+    . get_elapsed_time($start, get_moment())
+    . ' -->');
+
+  $template->assign(
+    'metadata_result',
+    array(
+      'NB_ELEMENTS_DONE' => count($datas),
+      'NB_ELEMENTS_CANDIDATES' => count($files),
+      'NB_ERRORS' => count($errors),
+      ));
+}
+
+// +-----------------------------------------------------------------------+
+// |                        template initialization                        |
+// +-----------------------------------------------------------------------+
+$template->set_filenames(array('update'=>'site_update.tpl'));
+$result_title = '';
+if (isset($simulate) and $simulate)
+{
+  $result_title.= l10n('update_simulation_title').' ';
+}
+
+// used_metadata string is displayed to inform admin which metadata will be
+// used from files for synchronization
+$used_metadata = implode( ', ', $site_reader->get_metadata_attributes());
+if ($site_is_remote and !isset($_POST['submit']) )
+{
+  $used_metadata.= ' + ...';
+}
+
+$template->assign(
+  array(
+    'SITE_URL'=>$site_url,
+    'U_SITE_MANAGER'=> get_root_url().'admin.php?page=site_manager',
+    'L_RESULT_UPDATE'=>$result_title.l10n('update_part_research'),
+    'L_RESULT_METADATA'=>$result_title.l10n('update_result_metadata'),
+    'METADATA_LIST' => $used_metadata,
+    'U_HELP' => get_root_url().'popuphelp.php?page=synchronize',
+    ));
+
+// +-----------------------------------------------------------------------+
+// |                        introduction : choices                         |
+// +-----------------------------------------------------------------------+
+if (isset($_POST['submit']))
+{
+  $tpl_introduction = array(
+      'sync'  => $_POST['sync'],
+      'sync_meta'  => isset($_POST['sync_meta']) ? true : false,
+      'display_info' => isset($_POST['display_info']) and $_POST['display_info']==1,
+      'add_to_caddie' => isset($_POST['add_to_caddie']) and $_POST['add_to_caddie']==1,
+      'subcats_included' => isset($_POST['subcats-included']) and $_POST['subcats-included']==1,
+      'privacy_level_selected' => (int)@$_POST['privacy_level'],
+      'meta_all'  => isset($_POST['meta_all']) ? true : false,
+      'meta_empty_overrides'  => isset($_POST['meta_empty_overrides']) ? true : false,
+    );
+
+  if (isset($_POST['cat']) and is_numeric($_POST['cat']))
+  {
+    $cat_selected = array($_POST['cat']);
+  }
+  else
+  {
+    $cat_selected = array();
+  }
+}
+else
+{
+  $tpl_introduction = array(
+      'sync'  => 'dirs',
+      'sync_meta'  => true,
+      'display_info' => false,
+      'add_to_caddie' => false,
+      'subcats_included' => true,
+      'privacy_level_selected' => 0,
+      'meta_all'  => false,
+      'meta_empty_overrides'  => false,
+    );
+
+  $cat_selected = array();
+}
+
+$tpl_introduction['privacy_level_options']=array();
+foreach ($conf['available_permission_levels'] as $level)
+{
+  $tpl_introduction['privacy_level_options'][$level] = l10n( sprintf('Level %d', $level) );
+}
+
+$template->assign('introduction', $tpl_introduction);
+
+$query = '
+SELECT id,name,uppercats,global_rank
+  FROM '.CATEGORIES_TABLE.'
+  WHERE site_id = '.$site_id;
+display_select_cat_wrapper($query,
+                           $cat_selected,
+                           'category_options',
+                           false);
+
+
+if (count($errors) > 0)
+{
+  foreach ($errors as $error)
+  {
+    $template->append(
+      'sync_errors',
+      array(
+        'ELEMENT' => $error['path'],
+        'LABEL' => $error['type'].' ('.$error_labels[$error['type']][0].')'
+        ));
+  }
+
+  foreach ($error_labels as $error_type=>$error_description)
+  {
+    $template->append(
+      'sync_error_captions',
+      array(
+        'TYPE' => $error_type,
+        'LABEL' => $error_description[1]
+        ));
+  }
+}
+
+if (count($infos) > 0
+    and isset($_POST['display_info'])
+    and $_POST['display_info'] == 1)
+{
+  foreach ($infos as $info)
+  {
+    $template->append(
+      'sync_infos',
+      array(
+        'ELEMENT' => $info['path'],
+        'LABEL' => $info['info']
+        ));
+  }
+}
+
+// +-----------------------------------------------------------------------+
+// |                          sending html code                            |
+// +-----------------------------------------------------------------------+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'update');
+?>
Index: /tags/2.0.2/admin/stats.php
===================================================================
--- /tags/2.0.2/admin/stats.php	(revision 3278)
+++ /tags/2.0.2/admin/stats.php	(revision 3278)
@@ -0,0 +1,514 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined("PHPWG_ROOT_PATH"))
+{
+  die ("Hacking attempt!");
+}
+
+include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+include_once(PHPWG_ROOT_PATH.'admin/include/functions_history.inc.php');
+
+// +-----------------------------------------------------------------------+
+// | Functions                                                             |
+// +-----------------------------------------------------------------------+
+
+function get_summary($year = null, $month = null, $day = null)
+{
+  $query = '
+SELECT
+    year,
+    month,
+    day,
+    hour,
+    nb_pages
+  FROM '.HISTORY_SUMMARY_TABLE;
+
+  if (isset($day))
+  {
+    $query.= '
+  WHERE year = '.$year.'
+    AND month = '.$month.'
+    AND day = '.$day.'
+    AND hour IS NOT NULL
+  ORDER BY
+    year ASC,
+    month ASC,
+    day ASC,
+    hour ASC
+;';
+  }
+  elseif (isset($month))
+  {
+    $query.= '
+  WHERE year = '.$year.'
+    AND month = '.$month.'
+    AND day IS NOT NULL
+    AND hour IS NULL
+  ORDER BY
+    year ASC,
+    month ASC,
+    day ASC
+;';
+  }
+  elseif (isset($year))
+  {
+    $query.= '
+  WHERE year = '.$year.'
+    AND month IS NOT NULL
+    AND day IS NULL
+  ORDER BY
+    year ASC,
+    month ASC
+;';
+  }
+  else
+  {
+    $query.= '
+  WHERE year IS NOT NULL
+    AND month IS NULL
+  ORDER BY
+    year ASC
+;';
+  }
+
+  $result = pwg_query($query);
+
+  $output = array();
+  while ($row = mysql_fetch_array($result))
+  {
+    array_push($output, $row);
+  }
+
+  return $output;
+}
+
+// +-----------------------------------------------------------------------+
+// | Check Access and exit when user status is not ok                      |
+// +-----------------------------------------------------------------------+
+
+check_status(ACCESS_ADMINISTRATOR);
+
+// +-----------------------------------------------------------------------+
+// | Refresh summary from details                                          |
+// +-----------------------------------------------------------------------+
+
+$query = '
+SELECT
+    date,
+    HOUR(time) AS hour,
+    MAX(id) AS max_id,
+    COUNT(*) AS nb_pages
+  FROM '.HISTORY_TABLE.'
+  WHERE summarized = \'false\'
+  GROUP BY
+    date ASC,
+    HOUR(time) ASC
+;';
+$result = pwg_query($query);
+
+$need_update = array();
+
+$max_id = 0;
+$is_first = true;
+$first_time_key = null;
+
+while ($row = mysql_fetch_array($result))
+{
+  $time_keys = array(
+    substr($row['date'], 0, 4), //yyyy
+    substr($row['date'], 0, 7), //yyyy-mm
+    substr($row['date'], 0, 10),//yyyy-mm-dd
+    sprintf(
+      '%s-%02u',
+      $row['date'], $row['hour']
+      ),
+    );
+
+  foreach ($time_keys as $time_key)
+  {
+    if (!isset($need_update[$time_key]))
+    {
+      $need_update[$time_key] = 0;
+    }
+    $need_update[$time_key] += $row['nb_pages'];
+  }
+
+  if ($row['max_id'] > $max_id)
+  {
+    $max_id = $row['max_id'];
+  }
+
+  if ($is_first)
+  {
+    $is_first = false;
+    $first_time_key = $time_keys[3];
+  }
+}
+
+// Only the oldest time_key might be already summarized, so we have to
+// update the 4 corresponding lines instead of simply inserting them.
+//
+// For example, if the oldest unsummarized is 2005.08.25.21, the 4 lines
+// that can be updated are:
+//
+// +---------------+----------+
+// | id            | nb_pages |
+// +---------------+----------+
+// | 2005          |   241109 |
+// | 2005-08       |    20133 |
+// | 2005-08-25    |      620 |
+// | 2005-08-25-21 |      151 |
+// +---------------+----------+
+
+
+$updates = array();
+$inserts = array();
+
+if (isset($first_time_key))
+{
+  list($year, $month, $day, $hour) = explode('-', $first_time_key);
+
+  $query = '
+SELECT *
+  FROM '.HISTORY_SUMMARY_TABLE.'
+  WHERE year='.$year.'
+    AND ( month IS NULL
+      OR ( month='.$month.'
+        AND ( day is NULL 
+          OR (day='.$day.'
+            AND (hour IS NULL OR hour='.$hour.')
+          )
+        )
+      )
+    )
+;';
+  $result = pwg_query($query);
+  while ($row = mysql_fetch_assoc($result))
+  {
+    $key = sprintf('%4u', $row['year']);
+    if ( isset($row['month']) )
+    {
+      $key .= sprintf('-%02u', $row['month']);
+      if ( isset($row['day']) )
+      {
+        $key .= sprintf('-%02u', $row['day']);
+        if ( isset($row['hour']) )
+        {
+          $key .= sprintf('-%02u', $row['hour']);
+        }
+      }
+    }
+
+    if (isset($need_update[$key]))
+    {
+      $row['nb_pages'] += $need_update[$key];
+      array_push($updates, $row);
+      unset($need_update[$key]);
+    }
+  }
+}
+
+foreach ($need_update as $time_key => $nb_pages)
+{
+  $time_tokens = explode('-', $time_key);
+
+  array_push(
+      $inserts,
+      array(
+        'year'     => $time_tokens[0],
+        'month'    => @$time_tokens[1],
+        'day'      => @$time_tokens[2],
+        'hour'     => @$time_tokens[3],
+        'nb_pages' => $nb_pages,
+        )
+      );
+}
+
+if (count($updates) > 0)
+{
+  mass_updates(
+    HISTORY_SUMMARY_TABLE,
+    array(
+      'primary' => array('year','month','day','hour'),
+      'update'  => array('nb_pages'),
+      ),
+    $updates
+    );
+}
+
+if (count($inserts) > 0)
+{
+  mass_inserts(
+    HISTORY_SUMMARY_TABLE,
+    array_keys($inserts[0]),
+    $inserts
+    );
+}
+
+if ($max_id != 0)
+{
+  $query = '
+UPDATE '.HISTORY_TABLE.'
+  SET summarized = \'true\'
+  WHERE summarized = \'false\'
+    AND id <= '.$max_id.'
+;';
+  pwg_query($query);
+}
+
+// +-----------------------------------------------------------------------+
+// | Page parameters check                                                 |
+// +-----------------------------------------------------------------------+
+
+foreach (array('day', 'month', 'year') as $key)
+{
+  if (isset($_GET[$key]))
+  {
+    $page[$key] = (int)$_GET[$key];
+  }
+}
+
+if (isset($page['day']))
+{
+  if (!isset($page['month']))
+  {
+    die('month is missing in URL');
+  }
+}
+
+if (isset($page['month']))
+{
+  if (!isset($page['year']))
+  {
+    die('year is missing in URL');
+  }
+}
+
+$summary_lines = get_summary(
+  @$page['year'],
+  @$page['month'],
+  @$page['day']
+  );
+
+// +-----------------------------------------------------------------------+
+// | Display statistics header                                             |
+// +-----------------------------------------------------------------------+
+
+// page title creation
+$title_parts = array();
+
+$url = PHPWG_ROOT_PATH.'admin.php?page=stats';
+
+array_push(
+  $title_parts,
+  '<a href="'.$url.'">'.l10n('Overall').'</a>'
+  );
+
+$period_label = l10n('Year');
+
+if (isset($page['year']))
+{
+  $url.= '&amp;year='.$page['year'];
+
+  array_push(
+    $title_parts,
+    '<a href="'.$url.'">'.$page['year'].'</a>'
+    );
+
+  $period_label = l10n('Month');
+}
+
+if (isset($page['month']))
+{
+  $url.= '&amp;month='.$page['month'];
+
+  array_push(
+    $title_parts,
+    '<a href="'.$url.'">'.$lang['month'][$page['month']].'</a>'
+    );
+
+  $period_label = l10n('Day');
+}
+
+if (isset($page['day']))
+{
+  $url.= '&amp;day='.$page['day'];
+
+  $time = mktime(12, 0, 0, $page['month'], $page['day'], $page['year']);
+
+  $day_title = sprintf(
+    '%u (%s)',
+    $page['day'],
+    $lang['day'][date('w', $time)]
+    );
+
+  array_push(
+    $title_parts,
+    '<a href="'.$url.'">'.$day_title.'</a>'
+    );
+
+  $period_label = l10n('Hour');
+}
+
+$template->set_filename('stats', 'stats.tpl');
+
+// TabSheet initialization
+history_tabsheet();
+
+$base_url = get_root_url().'admin.php?page=history';
+
+$template->assign(
+  array(
+    'L_STAT_TITLE' => implode($conf['level_separator'], $title_parts),
+    'PERIOD_LABEL' => $period_label,
+    'U_HELP' => get_root_url().'popuphelp.php?page=history',
+    'F_ACTION' => $base_url,
+    )
+  );
+
+// +-----------------------------------------------------------------------+
+// | Display statistic rows                                                |
+// +-----------------------------------------------------------------------+
+
+$max_width = 400;
+
+$datas = array();
+
+if (isset($page['day']))
+{
+  $key = 'hour';
+  $min_x = 0;
+  $max_x = 23;
+}
+elseif (isset($page['month']))
+{
+  $key = 'day';
+  $min_x = 1;
+  $max_x = date(
+    't',
+    mktime(12, 0, 0, $page['month'], 1, $page['year'])
+    );
+}
+elseif (isset($page['year']))
+{
+  $key = 'month';
+  $min_x = 1;
+  $max_x = 12;
+}
+else
+{
+  $key = 'year';
+}
+
+$max_pages = 1;
+foreach ($summary_lines as $line)
+{
+  if ($line['nb_pages'] > $max_pages)
+  {
+    $max_pages = $line['nb_pages'];
+  }
+
+  $datas[ $line[$key] ] = $line['nb_pages'];
+}
+
+if (!isset($min_x) and !isset($max_x) and count($datas) > 0)
+{
+  $min_x = min(array_keys($datas));
+  $max_x = max(array_keys($datas));
+}
+
+if (count($datas) > 0)
+{
+  for ($i = $min_x; $i <= $max_x; $i++)
+  {
+    if (!isset($datas[$i]))
+    {
+      $datas[$i] = 0;
+    }
+
+    $url = null;
+
+    if (isset($page['day']))
+    {
+      $value = sprintf('%02u', $i);
+    }
+    else if (isset($page['month']))
+    {
+      $url =
+        get_root_url().'admin.php'
+        .'?page=stats'
+        .'&amp;year='.$page['year']
+        .'&amp;month='.$page['month']
+        .'&amp;day='.$i
+        ;
+
+      $time = mktime(12, 0, 0, $page['month'], $i, $page['year']);
+
+      $value = $i.' ('.$lang['day'][date('w', $time)].')';
+    }
+    else if (isset($page['year']))
+    {
+      $url =
+        get_root_url().'admin.php'
+        .'?page=stats'
+        .'&amp;year='.$page['year']
+        .'&amp;month='.$i
+        ;
+
+      $value = $lang['month'][$i];
+    }
+    else
+    {
+      // at least the year is defined
+      $url =
+        get_root_url().'admin.php'
+        .'?page=stats'
+        .'&amp;year='.$i
+        ;
+
+      $value = $i;
+    }
+
+    if ($datas[$i] != 0 and isset($url))
+    {
+      $value = '<a href="'.$url.'">'.$value.'</a>';
+    }
+
+    $template->append(
+      'statrows',
+      array(
+        'VALUE' => $value,
+        'PAGES' => $datas[$i],
+        'WIDTH' => ceil(($datas[$i] * $max_width) / $max_pages ),
+        )
+      );
+  }
+}
+
+// +-----------------------------------------------------------------------+
+// | Sending html code                                                     |
+// +-----------------------------------------------------------------------+
+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'stats');
+?>
Index: /tags/2.0.2/admin/tags.php
===================================================================
--- /tags/2.0.2/admin/tags.php	(revision 3278)
+++ /tags/2.0.2/admin/tags.php	(revision 3278)
@@ -0,0 +1,246 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if( !defined("PHPWG_ROOT_PATH") )
+{
+  die ("Hacking attempt!");
+}
+
+include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+check_status(ACCESS_ADMINISTRATOR);
+
+// +-----------------------------------------------------------------------+
+// |                                edit tags                              |
+// +-----------------------------------------------------------------------+
+
+if (isset($_POST['submit']) and !is_adviser())
+{
+  $query = '
+SELECT name
+  FROM '.TAGS_TABLE.'
+;';
+  $existing_names = array_from_query($query, 'name');
+  
+
+  $current_name_of = array();
+  $query = '
+SELECT id, name
+  FROM '.TAGS_TABLE.'
+  WHERE id IN ('.$_POST['edit_list'].')
+;';
+  $result = pwg_query($query);
+  while ($row = mysql_fetch_array($result))
+  {
+    $current_name_of[ $row['id'] ] = $row['name'];
+  }
+  
+  $updates = array();
+  // we must not rename tag with an already existing name
+  foreach (explode(',', $_POST['edit_list']) as $tag_id)
+  {
+    $tag_name = stripslashes($_POST['tag_name-'.$tag_id]);
+
+    if ($tag_name != $current_name_of[$tag_id])
+    {
+      if (in_array($tag_name, $existing_names))
+      {
+        array_push(
+          $page['errors'],
+          sprintf(
+            l10n('Tag "%s" already exists'),
+            $tag_name
+            )
+          );
+      }
+      else if (!empty($tag_name))
+      {
+        array_push(
+          $updates,
+          array(
+            'id' => $tag_id,
+            'name' => addslashes($tag_name),
+            'url_name' => str2url($tag_name),
+            )
+          );
+      }
+    }
+  }
+  mass_updates(
+    TAGS_TABLE,
+    array(
+      'primary' => array('id'),
+      'update' => array('name', 'url_name'),
+      ),
+    $updates
+    );
+}
+
+// +-----------------------------------------------------------------------+
+// |                               delete tags                             |
+// +-----------------------------------------------------------------------+
+
+if (isset($_POST['delete']) and isset($_POST['tags']) and !is_adviser())
+{
+  $query = '
+SELECT name
+  FROM '.TAGS_TABLE.'
+  WHERE id IN ('.implode(',', $_POST['tags']).')
+;';
+  $tag_names = array_from_query($query, 'name');
+  
+  $query = '
+DELETE
+  FROM '.IMAGE_TAG_TABLE.'
+  WHERE tag_id IN ('.implode(',', $_POST['tags']).')
+;';
+  pwg_query($query);
+  
+  $query = '
+DELETE
+  FROM '.TAGS_TABLE.'
+  WHERE id IN ('.implode(',', $_POST['tags']).')
+;';
+  pwg_query($query);
+  
+  array_push(
+    $page['infos'],
+    l10n_dec(
+      'The %d following tag were deleted', 
+      'The %d following tags were deleted',
+      count($tag_names)).' : '.
+      implode(', ', $tag_names)
+    );
+}
+
+// +-----------------------------------------------------------------------+
+// |                               add a tag                               |
+// +-----------------------------------------------------------------------+
+
+if (isset($_POST['add']) and !empty($_POST['add_tag']) and !is_adviser())
+{
+  $tag_name = $_POST['add_tag'];
+
+  // does the tag already exists?
+  $query = '
+SELECT id
+  FROM '.TAGS_TABLE.'
+  WHERE name = \''.$tag_name.'\'
+;';
+  $existing_tags = array_from_query($query, 'id');
+
+  if (count($existing_tags) == 0)
+  {
+    mass_inserts(
+      TAGS_TABLE,
+      array('name', 'url_name'),
+      array(
+        array(
+          'name' => $tag_name,
+          'url_name' => str2url($tag_name),
+          )
+        )
+      );
+    
+    array_push(
+      $page['infos'],
+      sprintf(
+        l10n('Tag "%s" was added'),
+        stripslashes($tag_name)
+        )
+      );
+  }
+  else
+  {
+    array_push(
+      $page['errors'],
+      sprintf(
+        l10n('Tag "%s" already exists'),
+        stripslashes($tag_name)
+        )
+      );
+  }
+}
+
+// +-----------------------------------------------------------------------+
+// |                             template init                             |
+// +-----------------------------------------------------------------------+
+
+$template->set_filenames(array('tags' => 'tags.tpl'));
+
+$template->assign(
+  array(
+    'F_ACTION' => PHPWG_ROOT_PATH.'admin.php?page=tags'
+    )
+  );
+
+// +-----------------------------------------------------------------------+
+// |                             form creation                             |
+// +-----------------------------------------------------------------------+
+
+$template->assign(
+  array(
+    'TAG_SELECTION' => get_html_tag_selection(
+      get_all_tags(),
+      'tags'
+      ),
+    )
+  );
+
+if (isset($_POST['edit']) and isset($_POST['tags']))
+{
+  $template->assign(
+    array(
+      'EDIT_TAGS_LIST' => implode(',', $_POST['tags']),
+      )
+    );
+
+  $query = '
+SELECT id, name
+  FROM '.TAGS_TABLE.'
+  WHERE id IN ('.implode(',', $_POST['tags']).')
+;';
+  $result = pwg_query($query);
+  while ($row = mysql_fetch_array($result))
+  {
+    $name_of[ $row['id'] ] = $row['name'];
+  }
+
+  foreach ($_POST['tags'] as $tag_id)
+  {
+    $template->append(
+      'tags',
+      array(
+        'ID' => $tag_id,
+        'NAME' => $name_of[$tag_id],
+        )
+      );
+  }
+}
+
+// +-----------------------------------------------------------------------+
+// |                           sending html code                           |
+// +-----------------------------------------------------------------------+
+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'tags');
+
+?>
Index: /tags/2.0.2/admin/template/goto/admin.tpl
===================================================================
--- /tags/2.0.2/admin/template/goto/admin.tpl	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/admin.tpl	(revision 3278)
@@ -0,0 +1,133 @@
+{* $Id$ *}
+{known_script id="jquery.ui" src=$ROOT_URL|@cat:"template-common/lib/ui/ui.core.packed.js" }
+{known_script id="jquery.ui.accordion" src=$ROOT_URL|@cat:"template-common/lib/ui/ui.accordion.packed.js" }
+
+<script type="text/javascript">
+jQuery().ready(function(){ldelim}
+  jQuery('#menubar').accordion({ldelim}
+    header: "dt.rdion",
+    event: "click",
+    active: {$U_ACTIVE_MENU|default:$themeconf.selected_admin_menu}
+  });
+});
+</script>
+
+<div id="menubar">
+  <dl class="first">
+    <dt class="rdion"><span>{'Links'|@translate}&nbsp;</span></dt>
+    <dd>
+      <ul>
+        <li><a href="{$U_RETURN}">{'home'|@translate}</a></li>
+        <li><a href="{$U_FAQ}">{'instructions'|@translate}</a></li>
+        <li><a href="{$U_ADMIN}" title="{'hint_admin'|@translate}">{'admin'|@translate}</a></li>
+{if isset($pwgmenu)}
+        <li class="external"><a class="external" href="{$pwgmenu.WIKI}" onclick="window.open(this.href, ''); 
+          return false;">{'WIKI / DOC'|@translate}</a></li>
+        <li class="external"><a class="external" href="{$pwgmenu.FORUM}" onclick="window.open(this.href, '');
+          return false;">{'FORUM'|@translate}</a></li>
+{/if}
+        
+      </ul>
+    </dd>
+  </dl>
+  <dl>
+    <dt class="rdion"><span>{'config'|@translate}&nbsp;</span></dt>
+    <dd>
+      <ul>
+        <li><a href="{$U_CONFIG_GENERAL}">{'conf_general'|@translate}</a></li>
+        <li><a href="{$U_CONFIG_DISPLAY}">{'conf_display'|@translate}</a></li>
+        <li><a href="{$U_CONFIG_MENUBAR}">{'title_menu'|@translate}</a></li>
+        <li><a href="{$U_CONFIG_EXTENTS}">{'conf_extents'|@translate}</a></li>
+      </ul>
+    </dd>
+  </dl>
+  <dl>
+    <dt class="rdion"><span>{'Categories'|@translate}&nbsp;</span></dt>
+    <dd>
+      <ul>
+        <li><a href="{$U_SITE_MANAGER}">{'Site manager'|@translate}</a></li>
+        <li><a href="{$U_CAT_UPDATE}">{'update'|@translate}</a></li>
+        <li><a href="{$U_CATEGORIES}">{'manage'|@translate}</a></li>
+        <li><a href="{$U_MOVE}">{'Move'|@translate}</a></li>
+        <li><a href="{$U_CAT_OPTIONS}">{'cat_options_title'|@translate}</a></li>
+        <li><a href="{$U_PERMALINKS}">{'Permalinks'|@translate}</a></li>
+      </ul>
+    </dd>
+  </dl>
+  <dl>
+    <dt class="rdion"><span>{'Pictures'|@translate}&nbsp;</span></dt>
+    <dd>
+      <ul>
+        <li><a href="{$U_WAITING}">{'waiting'|@translate}</a></li>
+        <li><a href="{$U_THUMBNAILS}">{'thumbnails'|@translate}</a></li>
+        <li><a href="{$U_RATING}">{'Rating'|@translate}</a></li>
+        <li><a href="{$U_TAGS}">{'Tags'|@translate}</a></li>
+        <li><a href="{$U_CADDIE}">{'Caddie'|@translate}</a></li>
+        <li><a href="{$U_RECENT_SET}">{'recent_pics_cat'|@translate}</a></li>
+      </ul>
+    </dd>
+  </dl>
+  <dl>
+    <dt class="rdion"><span>{'identification'|@translate}&nbsp;</span></dt>
+    <dd>
+      <ul>
+        <li><a href="{$U_USERS}">{'users'|@translate}</a></li>
+        <li><a href="{$U_GROUPS}">{'groups'|@translate}</a></li>
+        <li><a href="{$U_NOTIFICATION_BY_MAIL}">{'nbm_item_notification'|@translate}</a></li>
+      </ul>
+    </dd>
+  </dl>
+  <dl>
+    <dt class="rdion"><span>{'special_admin_menu'|@translate}&nbsp;</span></dt>
+    <dd>
+      <ul>
+        <li><a href="{$U_HISTORY_STAT}">{'History'|@translate}</a></li>
+        <li><a href="{$U_MAINTENANCE}">{'Maintenance'|@translate}</a></li>
+        <li><a href="{$U_ADVANCED_FEATURE}">{'Advanced_features'|@translate}</a></li>
+        <li><a href="{$U_PLUGINS}">{'Plugins'|@translate}</a>
+        {if !empty($plugin_menu_items)}
+          <ul class="scroll">
+          {foreach from=$plugin_menu_items item=menu_item}
+            <li><a href="{$menu_item.URL}">{$menu_item.NAME}</a></li>
+          {/foreach}
+          </ul>
+        {/if}
+        </li>
+      </ul>
+    </dd>
+  </dl>
+</div> <!-- menubar -->
+
+<div id="content" class="content">
+
+  {if isset($TABSHEET)}
+  {$TABSHEET}
+  {/if}
+  {if isset($U_HELP)}
+  <ul class="HelpActions">
+    <li><a href="{$U_HELP}" onclick="popuphelp(this.href); return false;" title="{'Help'|@translate}"><img src="{$ROOT_URL}{$themeconf.admin_icon_dir}/help.png" class="button" alt="(?)"></a></li>
+  </ul>
+  {/if}
+  
+  {if isset($errors)}
+  <div class="errors">
+    <ul>
+      {foreach from=$errors item=error}
+      <li>{$error}</li>
+      {/foreach}
+    </ul>
+  </div>
+  {/if}
+
+  {if isset($infos)}
+  <div class="infos">
+    <ul>
+      {foreach from=$infos item=info}
+      <li>{$info}</li>
+      {/foreach}
+    </ul>
+  </div>
+  {/if}
+
+  {$ADMIN_CONTENT}
+</div>
Index: /tags/2.0.2/admin/template/goto/advanced_feature.tpl
===================================================================
--- /tags/2.0.2/admin/template/goto/advanced_feature.tpl	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/advanced_feature.tpl	(revision 3278)
@@ -0,0 +1,10 @@
+{* $Id$ *}
+<div class="titrePage">
+  <h2>{'Advanced_features'|@translate}</h2>
+</div>
+
+<ul>
+  {foreach from=$advanced_features item=feature}
+    <li><a href="{$feature.URL}" {$TAG_INPUT_ENABLED}>{$feature.CAPTION}</a></li>
+  {/foreach}
+</ul>
Index: /tags/2.0.2/admin/template/goto/cat_list.tpl
===================================================================
--- /tags/2.0.2/admin/template/goto/cat_list.tpl	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/cat_list.tpl	(revision 3278)
@@ -0,0 +1,92 @@
+{* $Id$ *}
+{known_script id="jquery" src=$ROOT_URL|@cat:"template-common/lib/jquery.packed.js"}
+{known_script id="jquery.ui" src=$ROOT_URL|@cat:"template-common/lib/ui/ui.core.packed.js" }
+{known_script id="jquery.ui.sortable" src=$ROOT_URL|@cat:"template-common/lib/ui/ui.sortable.packed.js" }
+
+<script type="text/javascript">
+  jQuery().ready(function(){ldelim}
+    jQuery(".catPos").hide();
+    jQuery(".drag_button").show();
+    jQuery(".categoryLi").css("cursor","move");
+    jQuery(".categoryUl").sortable({ldelim}
+      axis: "y",
+      opacity: 0.8
+    });
+    jQuery("#categoryOrdering").submit(function(){ldelim}
+      ar = jQuery('.categoryUl').sortable('toArray');
+      for(i=0;i<ar.length;i++) {ldelim}
+        cat = ar[i].split('cat_');
+        document.getElementsByName('catOrd[' + cat[1] + ']')[0].value = i;
+      }
+    });
+  });
+</script>
+
+<h2>{'title_categories'|@translate}</h2>
+
+<h3>{$CATEGORIES_NAV}</h3>
+
+<form id="addVirtual" action="{$F_ACTION}" method="post">
+  <p>
+    {'cat_add'|@translate} : <input type="text" name="virtual_name" />
+    <input class="submit" type="submit" value="{'Submit'|@translate}" name="submitAdd" {$TAG_INPUT_ENABLED} />
+    {if count($categories)>9 }
+    <a href="#EoP" class="button" style="border:0;">
+		<img src="{$themeconf.admin_icon_dir}/page_end.png" title="{'Page end'|@translate}" class="button" alt="page_end" style="margin-bottom:-0.6em;"/></a>
+    {/if}
+  </p>
+</form>
+
+{if count($categories) }
+<form id="categoryOrdering" action="{$F_ACTION}" method="post">
+  <p>
+    <input class="submit" name="submitOrder" type="submit" value="{'Save order'|@translate}" {$TAG_INPUT_ENABLED} />
+    <input class="submit" name="submitOrderAlphaNum" type="submit" value="{'Order alphanumerically'|@translate}" {$TAG_INPUT_ENABLED} />
+  </p>
+  <ul class="categoryUl">
+
+    {foreach from=$categories item=category}
+    <li class="categoryLi{if $category.IS_VIRTUAL} virtual_cat{/if}" id="cat_{$category.ID}">
+      <!-- category {$category.ID} -->
+      <ul class="categoryActions">
+        {if cat_admin_access($category.ID)}
+        <li><a href="{$category.U_JUMPTO}" title="{'jump to category'|@translate}"><img src="{$themeconf.admin_icon_dir}/category_jump-to.png" class="button" alt="{'jump to category'|@translate}" /></a></li>
+        {/if}
+        <li><a href="{$category.U_EDIT}" title="{'edit category informations'|@translate}"><img src="{$themeconf.admin_icon_dir}/category_edit.png" class="button" alt="{'edit'|@translate}"/></a></li>
+        {if isset($category.U_MANAGE_ELEMENTS) }
+        <li><a href="{$category.U_MANAGE_ELEMENTS}" title="{'manage category elements'|@translate}"><img src="{$themeconf.admin_icon_dir}/category_elements.png" class="button" alt="{'elements'|@translate}" /></a></li>
+        {/if}
+        <li><a href="{$category.U_CHILDREN}" title="{'manage sub-categories'|@translate}"><img src="{$themeconf.admin_icon_dir}/category_children.png" class="button" alt="{'sub-categories'|@translate}" /></a></li>
+        {if isset($category.U_MANAGE_PERMISSIONS) }
+        <li><a href="{$category.U_MANAGE_PERMISSIONS}" title="{'edit category permissions'|@translate}" ><img src="{$themeconf.admin_icon_dir}/category_permissions.png" class="button" alt="{'permissions'|@translate}" /></a></li>
+        {/if}
+        {if isset($category.U_DELETE) }
+        <li><a href="{$category.U_DELETE}" title="{'delete category'|@translate}" onclick="return confirm('{'Are you sure?'|@translate|@escape:javascript}');"><img src="{$themeconf.admin_icon_dir}/category_delete.png" class="button" alt="{'delete'|@translate}" /></a></li>
+        {/if}
+      </ul>
+
+      <p>
+      <img src="{$themeconf.admin_icon_dir}/cat_move.png" class="button drag_button" style="display:none;" alt="{'Drag to re-order'|@translate}" title="{'Drag to re-order'|@translate}"/>
+      <strong><a href="{$category.U_CHILDREN}" title="{'manage sub-categories'|@translate}">{$category.NAME}</a></strong>
+      {if $category.IS_VIRTUAL}
+      <img src="{$themeconf.admin_icon_dir}/virt_category.png" class="button" alt="{'virtual_category'|@translate}" />
+      {/if}
+      </p>
+
+      <p class="catPos">
+        <label>
+          {'Position'|@translate} :
+          <input type="text" size="4" name="catOrd[{$category.ID}]" maxlength="4" value="{$category.RANK}" />
+        </label>
+      </p>
+
+    </li>
+    {/foreach}
+  </ul>
+  <p>
+    <input class="submit" name="submitOrder" type="submit" value="{'Save order'|@translate}" {$TAG_INPUT_ENABLED} />
+    <input class="submit" name="submitOrderAlphaNum" type="submit" value="{'Order alphanumerically'|@translate}" {$TAG_INPUT_ENABLED} />
+  </p>
+
+</form>
+{/if}
Index: /tags/2.0.2/admin/template/goto/cat_modify.tpl
===================================================================
--- /tags/2.0.2/admin/template/goto/cat_modify.tpl	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/cat_modify.tpl	(revision 3278)
@@ -0,0 +1,233 @@
+{* $Id$ *}
+
+{include file='include/autosize.inc.tpl'}
+{include file='include/resize.inc.tpl'}
+
+<div class="titrePage">
+  <h2>{'title_edit_cat'|@translate}</h2>
+</div>
+
+<h3>{$CATEGORIES_NAV}</h3>
+
+<ul class="categoryActions">
+  {if cat_admin_access($CAT_ID)}
+  <li><a href="{$U_JUMPTO}" title="{'jump to category'|@translate}"><img src="{$themeconf.admin_icon_dir}/category_jump-to.png" class="button" alt="{'jump to category'|@translate}" /></a></li>
+  {/if}
+  {if isset($U_MANAGE_ELEMENTS) }
+  <li><a href="{$U_MANAGE_ELEMENTS}" title="{'manage category elements'|@translate}"><img src="{$ROOT_URL}{$themeconf.admin_icon_dir}/category_elements.png" class="button" alt="{'elements'|@translate}" /></a></li>
+  <li><a href="{$U_MANAGE_RANKS}" title="{'manage image ranks'|@translate}"><img src="{$ROOT_URL}{$themeconf.admin_icon_dir}/ranks.png" class="button" alt="{'ranks'|@translate}" /></a></li>
+  {/if}
+  <li><a href="{$U_CHILDREN}" title="{'manage sub-categories'|@translate}"><img src="{$ROOT_URL}{$themeconf.admin_icon_dir}/category_children.png" class="button" alt="{'sub-categories'|@translate}" /></a></li>
+  {if isset($U_MANAGE_PERMISSIONS) }
+  <li><a href="{$U_MANAGE_PERMISSIONS}" title="{'edit category permissions'|@translate}" ><img src="{$ROOT_URL}{$themeconf.admin_icon_dir}/category_permissions.png" class="button" alt="{'permissions'|@translate}" /></a></li>
+  {/if}
+  {if isset($U_DELETE) }
+  <li><a href="{$U_DELETE}" title="{'delete category'|@translate}" onclick="return confirm('{'Are you sure?'|@translate|@escape:'javascript'}');"><img src="{$ROOT_URL}{$themeconf.admin_icon_dir}/category_delete.png" class="button" alt="{'delete'|@translate}" /></a></li>
+  {/if}
+</ul>
+
+<form action="{$F_ACTION}" method="POST" id="catModify">
+
+<fieldset>
+  <legend>{'Informations'|@translate}</legend>
+  <table>
+
+    {if isset($CAT_FULL_DIR) }
+    <tr>
+      <td><strong>{'storage'|@translate}</strong></td>
+      <td class="row1">{$CAT_FULL_DIR}</td>
+    </tr>
+    {/if}
+    
+    <tr>
+      <td><strong>{'Name'|@translate}</strong></td>
+      <td>
+        <input type="text" class="large" name="name" value="{$CAT_NAME}" maxlength="60"/>
+      </td>
+    </tr>
+    <tr>
+      <td><strong>{'Description'|@translate}</strong></td>
+      <td>
+        <textarea cols="50" rows="5" name="comment" id="comment" class="description">{$CAT_COMMENT}</textarea>
+      </td>
+    </tr>
+  </table>
+</fieldset>
+
+{if isset($move_cat_options) }
+<fieldset id="move">
+  <legend>{'Move'|@translate}</legend>
+  {'Parent category'|@translate}
+  <select class="categoryDropDown" name="parent">
+    <option value="0">------------</option>
+    {html_options options=$move_cat_options selected=$move_cat_options_selected }
+  </select>
+</fieldset>
+{/if}
+
+<fieldset id="options">
+  <legend>{'Options'|@translate}</legend>
+  <table>
+    <tr>
+      <td><strong>{'conf_access'|@translate}</strong>
+      <td>
+        {html_radios name='status' values=$status_values output=$status_values|translate selected=$CAT_STATUS}
+      </td>
+    </tr>
+    <tr>
+      <td><strong>{'lock'|@translate}</strong>
+      <td>
+        {html_radios name='visible' values='true,false'|@explode output='No,Yes'|@explode|translate selected=$CAT_VISIBLE}
+      </td>
+    </tr>
+    <tr>
+      <td><strong>{'comments'|@translate}</strong>
+      <td>
+        {html_radios name='commentable' values='false,true'|@explode output='No,Yes'|@explode|translate selected=$CAT_COMMENTABLE}
+      </td>
+    </tr>
+    {if isset($SHOW_UPLOADABLE) }
+    <tr>
+      <td><strong>{'editcat_uploadable'|@translate}</strong>
+      <td>
+        {html_radios name='uploadable' values='false,true'|@explode output='No,Yes'|@explode|translate selected=$CAT_UPLOADABLE}
+      </td>
+    </tr>
+    {/if}
+  </table>
+</fieldset>
+
+<fieldset id="image_order">
+  <legend>{'Sort order'|@translate}</legend>
+  <input type="checkbox" name="image_order_default" id="image_order_default" {$IMG_ORDER_DEFAULT} />
+  <label for="image_order_default">{'Use default sort order'|@translate}</label>
+  <br/>
+  <input type="checkbox" name="image_order_subcats" id="image_order_subcats" />
+  <label for="image_order_subcats">{'Apply to subcategories'|@translate}</label>
+  <br/>
+  
+  {foreach from=$image_orders item=order}
+    <select name="order_field_{$order.ID}">
+      {html_options options=$image_order_field_options selected=$order.FIELD }
+    </select>
+    <select name="order_direction_{$order.ID}">
+      {html_options options=$image_order_direction_options selected=$order.DIRECTION }
+    </select><br/>
+  {/foreach}
+  
+</fieldset>
+
+<p style="text-align:center;">
+  <input class="submit" type="submit" value="{'Submit'|@translate}" name="submit" {$TAG_INPUT_ENABLED}/>
+  <input class="submit" type="reset" value="{'Reset'|@translate}" name="reset" />
+</p>
+
+{if isset($representant) }
+<fieldset id="representant">
+  <legend>{'Representant'|@translate}</legend>
+  <table>
+    <tr>
+      <td align="center">
+        {if isset($representant.picture) }
+        <a href="{$representant.picture.URL}"><img src="{$representant.picture.SRC}" alt="" class="miniature" /></a>
+        {else}
+        <img src="{$ROOT_URL}{$themeconf.admin_icon_dir}/category_representant_random.png" class="button" alt="{'Random picture'|@translate}" class="miniature" />
+        {/if}
+      </td>
+      <td>
+        {if $representant.ALLOW_SET_RANDOM }
+        <p><input class="submit" type="submit" name="set_random_representant" value="{'cat_representant'|@translate}" {$TAG_INPUT_ENABLED}/></p>
+        {/if}
+
+        {if isset($representant.ALLOW_DELETE) }
+        <p><input class="submit" type="submit" name="delete_representant" value="{'Delete Representant'|@translate}" /></p>
+        {/if}
+      </td>
+    </tr>
+  </table>
+</fieldset>
+{/if}
+
+</form>
+
+<form action="{$F_ACTION}" method="POST" id="links">
+
+<fieldset id="linkAllNew">
+  <legend>{'Link all category elements to a new category'|@translate}</legend>
+
+  <table>
+    <tr>
+      <td>{'Virtual category name'|@translate}</td>
+      <td><input type="text" class="large" name="virtual_name"></td>
+    </tr>
+
+    <tr>
+      <td>{'Parent category'|@translate}</td>
+      <td>
+        <select class="categoryDropDown" name="parent">
+          <option value="0">------------</option>
+          {html_options options=$create_new_parent_options }
+        </select>
+      </td>
+    </tr>
+  </table>
+
+  <p>
+    <input class="submit" type="submit" value="{'Submit'|@translate}" name="submitAdd" {$TAG_INPUT_ENABLED}/>
+    <input class="submit" type="reset" value="{'Reset'|@translate}" name="reset" />
+  </p>
+
+</fieldset>
+
+<fieldset id="linkAllExist">
+  <legend>{'Link all category elements to some existing categories'|@translate}</legend>
+
+  <table>
+    <tr>
+      <td>{'Categories'|@translate}</td>
+      <td>
+        <select class="categoryList" name="destinations[]" multiple="multiple" size="5">
+          {html_options options=$category_destination_options }
+        </select>
+      </td>
+    </tr>
+  </table>
+
+  <p>
+    <input class="submit" type="submit" value="{'Submit'|@translate}" name="submitDestinations" {$TAG_INPUT_ENABLED}/>
+    <input class="submit" type="reset" value="{'Reset'|@translate}" name="reset" />
+  </p>
+
+</fieldset>
+
+{if isset($group_mail_options)}
+<fieldset id="emailCatInfo">
+  <legend>{'Send an information email to group members'|@translate}</legend>
+
+  <table>
+    <tr>
+      <td><strong>{'Group'|@translate}</strong></td>
+      <td>
+        <select name="group">
+          {html_options options=$group_mail_options}
+        </select>
+      </td>
+    </tr>
+    <tr>
+      <td><strong>{'mail_content'|@translate}</strong></td>
+      <td>
+        <textarea cols="50" rows="5" name="mail_content" id="mail_content" class="description">{$MAIL_CONTENT}</textarea>
+      </td>
+    </tr>
+
+  </table>
+
+  <p>
+    <input class="submit" type="submit" value="{'Submit'|@translate}" name="submitEmail" {$TAG_INPUT_ENABLED}/>
+    <input class="submit" type="reset" value="{'Reset'|@translate}" name="reset" />
+  </p>
+
+</fieldset>
+{/if}
+
+</form>
Index: /tags/2.0.2/admin/template/goto/cat_move.tpl
===================================================================
--- /tags/2.0.2/admin/template/goto/cat_move.tpl	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/cat_move.tpl	(revision 3278)
@@ -0,0 +1,37 @@
+{* $Id$ *}
+
+{include file='include/resize.inc.tpl'}
+
+<div class="titrePage">
+  <h2>{'Move categories'|@translate}</h2>
+</div>
+
+<form method="post" action="{$F_ACTION}" class="filter" id="catMove">
+  <fieldset>
+    <legend>{'Virtual categories movement'|@translate}</legend>
+
+    <label>
+      {'Virtual categories to move'|@translate}
+
+      <select class="categoryList" name="selection[]" multiple="multiple">
+        {html_options options=$category_to_move_options}
+      </select>
+    </label>
+
+    <label>
+      {'New parent category'|@translate}
+
+      <select class="categoryDropDown" name="parent">
+        <option value="0">------------</option>
+        {html_options options=$category_parent_options}
+      </select>
+    </label>
+
+  </fieldset>
+
+  <p>
+    <input class="submit" type="submit" name="submit" value="{'Submit'|@translate}" {$TAG_INPUT_ENABLED}>
+    <input class="submit" type="reset" name="reset" value="{'Reset'|@translate}">
+  </p>
+
+</form>
Index: /tags/2.0.2/admin/template/goto/cat_options.tpl
===================================================================
--- /tags/2.0.2/admin/template/goto/cat_options.tpl	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/cat_options.tpl	(revision 3278)
@@ -0,0 +1,12 @@
+{* $Id$ *}
+<div class="titrePage">
+  <h2>{'cat_options_title'|@translate} {$TABSHEET_TITLE}</h2>
+</div>
+
+<form method="post" action="{$F_ACTION}" id="cat_options">
+  <fieldset>
+    <legend>{$L_SECTION}</legend>
+    {$DOUBLE_SELECT}
+  </fieldset>
+</form>
+
Index: /tags/2.0.2/admin/template/goto/cat_perm.tpl
===================================================================
--- /tags/2.0.2/admin/template/goto/cat_perm.tpl	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/cat_perm.tpl	(revision 3278)
@@ -0,0 +1,65 @@
+{* $Id$ *}
+<div class="titrePage">
+  <h2>{'Manage permissions for a category'|@translate}</h2>
+</div>
+
+<h3>{$CATEGORIES_NAV}</h3>
+
+<form action="{$F_ACTION}" method="post" id="categoryPermissions">
+
+  <h4>{'Groups'|@translate}</h4>
+
+  <fieldset>
+    <legend>{'Permission granted'|@translate}</legend>
+    <ul>
+      {foreach from=$group_granted_ids item=id}
+      <li><label><input type="checkbox" name="deny_groups[]" value="{$id}" /> {$all_groups[$id]}</label></li>
+      {/foreach}
+    </ul>
+    <input class="submit" type="submit" name="deny_groups_submit" value="{'Deny selected groups'|@translate}" {$TAG_INPUT_ENABLED}/>
+  </fieldset>
+
+  <fieldset>
+    <legend>{'Permission denied'|@translate}</legend>
+    <ul>
+      {foreach from=$group_denied_ids item=id}
+      <li><label><input type="checkbox" name="grant_groups[]" value="{$id}"> {$all_groups[$id]}</label></li>
+      {/foreach}
+    </ul>
+    <input class="submit" type="submit" name="grant_groups_submit" value="{'Grant selected groups'|@translate}" {$TAG_INPUT_ENABLED}/>
+  </fieldset>
+
+  <h4>{'Users'|@translate}</h4>
+
+  <fieldset>
+    <legend>{'Permission granted'|@translate}</legend>
+    <ul>
+      {foreach from=$user_granted_direct_ids item=id}
+      <li><label><input type="checkbox" name="deny_users[]" value="{$id}" /> {$all_users[$id]}</label></li>
+      {/foreach}
+    </ul>
+    <input class="submit" type="submit" name="deny_users_submit" value="{'Deny selected users'|@translate}" {$TAG_INPUT_ENABLED}/>
+  </fieldset>
+
+  <fieldset>
+    <legend>{'Permission granted thanks to a group'|@translate}</legend>
+    {if isset($user_granted_indirects) }
+    <ul>
+      {foreach from=$user_granted_indirects item=user_group}
+      <li>{$user_group.USER} ({$user_group.GROUP})</li>
+      {/foreach}
+    </ul>
+    {/if}
+  </fieldset>
+
+  <fieldset>
+    <legend>{'Permission denied'|@translate}</legend>
+    <ul>
+      {foreach from=$user_denied_ids item=id}
+      <li><label><input type="checkbox" name="grant_users[]" value="{$id}"> {$all_users[$id]}</label></li>
+      {/foreach}
+    </ul>
+    <input class="submit" type="submit" name="grant_users_submit" value="{'Grant selected users'|@translate}" {$TAG_INPUT_ENABLED}/>
+  </fieldset>
+
+</form>
Index: /tags/2.0.2/admin/template/goto/check_integrity.tpl
===================================================================
--- /tags/2.0.2/admin/template/goto/check_integrity.tpl	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/check_integrity.tpl	(revision 3278)
@@ -0,0 +1,84 @@
+{* $Id$ *}
+<dl>
+  <dt>{'c13y_title'|@translate}</dt>
+  <dd>
+    <ul>
+      <form method="post" name="c13y" id="c13y" action="">
+      <fieldset>
+        <table class="table2">
+          <tr class="throw">
+            <th></th>
+            <th>{'c13y_Anomaly'|@translate}</th>
+            <th>{'c13y_Correction'|@translate}</th>
+          </tr>
+          {if isset($c13y_list)}
+            {foreach from=$c13y_list item=c13y name=c13y_loop}
+              <tr class="{if $smarty.foreach.c13y_loop.index is odd}row1{else}row2{/if}">
+                <td>
+                  {if $c13y.can_select}
+                    <input type="checkbox" name="c13y_selection[]" value="{$c13y.id}" id="c13y_selection-{$c13y.id}" /><label for="c13y_selection-{$c13y.id}"></label>
+                  {/if}
+                </td>
+                <td><label for="c13y_selection-{$c13y.id}">{$c13y.anomaly}</label></td>
+                <td>
+                  <label for="c13y_selection-{$c13y.id}">
+                    {if $c13y.show_ignore_msg}
+                      {'c13y_ignore_msg1'|@translate}
+                      <br />
+                      {'c13y_ignore_msg2'|@translate}
+                    {/if}
+                    {if $c13y.show_correction_fct}
+                      {'c13y_Automatic_correction'|@translate}
+                    {/if}
+                    {if $c13y.show_correction_bad_fct}
+                      {'c13y_Impossible_automatic_correction'|@translate}
+                    {/if}
+                    {if $c13y.show_correction_success_fct}
+                      {'c13y_Correction_applied_success'|@translate}
+                    {/if}
+                    {if !empty($c13y.correction_error_fct)}
+                      {'c13y_Correction_applied_error'|@translate}
+                      <br />
+                      {$c13y.c13y.correction_error_fct}
+                    {/if}
+                    {if !empty($c13y.correction_msg)}
+                      {if $c13y.show_correction_success_fct or !empty($c13y.correction_error_fct) or $c13y.show_correction_fct or $c13y.show_correction_bad_fct }
+                        <br />
+                      {/if}
+                      {$c13y.correction_msg|@nl2br}
+                    {/if}
+                  </label>
+                </td>
+              </tr>
+            {/foreach}
+          {/if}
+        </table>
+
+        <p>
+          {if $c13y_show_submit_ignore}
+              <a href="#" onclick="SelectAll(document.getElementById('c13y')); return false;">{'Check all'|@translate}</a>
+            / <a href="#" onclick="DeselectAll(document.getElementById('c13y')); return false;">{'Uncheck all'|@translate}</a>
+          {/if}
+          {if isset($c13y_do_check)}
+            / <a href="#" onclick="DeselectAll(document.getElementById('c13y'));
+            {foreach from=$c13y_do_check item=ID}
+              document.getElementById('c13y_selection-{$ID}').checked = true;
+            {/foreach}
+            return false;">{'c13y_check_auto'|@translate}</a>
+          {/if}
+        </p>
+
+        <p>
+          {if $c13y_show_submit_automatic_correction}
+            <input class="submit" type="submit" value="{'c13y_submit_correction'|@translate}" name="c13y_submit_correction" {$TAG_INPUT_ENABLED} />
+          {/if}
+          {if $c13y_show_submit_ignore}
+            <input class="submit" type="submit" value="{'c13y_submit_ignore'|@translate}" name="c13y_submit_ignore" {$TAG_INPUT_ENABLED} />
+          {/if}
+          <input class="submit" type="submit" value="{'c13y_submit_refresh'|@translate}" name="c13y_submit_refresh" />
+          </p>
+
+      </fieldset>
+      </form>
+    </ul>
+  </dd>
Index: /tags/2.0.2/admin/template/goto/comments.tpl
===================================================================
--- /tags/2.0.2/admin/template/goto/comments.tpl	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/comments.tpl	(revision 3278)
@@ -0,0 +1,32 @@
+{* $Id$ *}
+<div class="titrePage">
+  <h2>{'waiting'|@translate} {$TABSHEET_TITLE}</h2>
+</div>
+
+<h3>{'User comments validation'|@translate}</h3>
+
+{if !empty($comments) }
+<form method="post" action="{$F_ACTION}">
+  
+  {foreach from=$comments item=comment}
+  <div class="comment">
+    <a class="illustration" href="{$comment.U_PICTURE}"><img src="{$comment.TN_SRC}" /></a>
+    <p class="commentHeader"><strong>{$comment.AUTHOR}</strong> - <em>{$comment.DATE}</em></p>
+    <blockquote>{$comment.CONTENT}</blockquote>
+  </div>
+    <ul class="actions">
+      <li><label><input type="radio" name="action-{$comment.ID}" value="reject" />{'Reject'|@translate}</label></li>
+      <li><label><input type="radio" name="action-{$comment.ID}" value="validate" />{'Validate'|@translate}</label></li>
+    </ul>
+  {/foreach}
+
+  <p class="bottomButtons">
+    <input type="hidden" name="list" value="{$LIST}" />
+    <input class="submit" type="submit" name="submit" value="{'Submit'|@translate}" {$TAG_INPUT_ENABLED}/>
+    <input class="submit" type="submit" name="validate-all" value="{'Validate All'|@translate}" {$TAG_INPUT_ENABLED}/>
+    <input class="submit" type="submit" name="reject-all" value="{'Reject All'|@translate}" {$TAG_INPUT_ENABLED}/>
+    <input class="submit" type="reset" value="{'Reset'|@translate}" />
+  </p>
+
+</form>
+{/if}
Index: /tags/2.0.2/admin/template/goto/configuration.tpl
===================================================================
--- /tags/2.0.2/admin/template/goto/configuration.tpl	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/configuration.tpl	(revision 3278)
@@ -0,0 +1,178 @@
+{* $Id$ *}
+
+{include file='include/autosize.inc.tpl'}
+
+<div class="titrePage">
+  <h2>{'title_configuration'|@translate} {$TABSHEET_TITLE}</h2>
+</div>
+
+<form method="post" action="{$F_ACTION}" class="properties">
+
+{if isset($main)}
+<fieldset id="mainConf">
+  <ul>
+    <li>
+      <span class="property">
+        <label for="gallery_title">{'Gallery title'|@translate}</label>
+      </span>
+      <input type="text" maxlength="255" size="50" name="gallery_title" id="gallery_title" value="{$main.CONF_GALLERY_TITLE}" />
+    </li>
+
+    <li>
+      <span class="property">
+        <label for="page_banner">{'Page banner'|@translate}</label>
+      </span>
+      <textarea class="description" name="page_banner" id="page_banner">{$main.CONF_PAGE_BANNER}</textarea>
+    </li>
+
+    <li>
+      <span class="property">
+        <label for="gallery_url">{'Gallery URL'|@translate}</label>
+      </span>
+      <input type="text" maxlength="255" size="50" name="gallery_url" id="gallery_url" value="{$main.CONF_GALLERY_URL}" />
+    </li>
+  </ul>
+</fieldset>
+
+<fieldset id="mainConfCheck">
+  <ul>
+
+    <li>
+      <label>
+        <span class="property">{'Lock gallery'|@translate}</span>
+        <input type="checkbox" name="gallery_locked" {if ($main.gallery_locked)}checked="checked"{/if} />
+      </label>
+    </li>
+
+    <li>
+      <label>
+        <span class="property">{'Rating'|@translate}</span>
+        <input type="checkbox" name="rate" {if ($main.rate)}checked="checked"{/if} />
+      </label>
+    </li>
+
+    <li>
+      <label>
+        <span class="property">{'Rating by guests'|@translate}</span>
+        <input type="checkbox" name="rate_anonymous" {if ($main.rate_anonymous)}checked="checked"{/if} />
+      </label>
+    </li>
+
+    <li>
+      <label>
+        <span class="property">{'Allow user registration'|@translate}</span>
+        <input type="checkbox" name="allow_user_registration" {if ($main.allow_user_registration)}checked="checked"{/if} />
+      </label>
+    </li>
+
+    <li>
+      <label>
+        <span class="property">{'obligatory_user_mail_address'|@translate}</span>
+        <input type="checkbox" name="obligatory_user_mail_address" {if ($main.obligatory_user_mail_address)}checked="checked"{/if} />
+      </label>
+    </li>
+
+    <li>
+      <label>
+        <span class="property">{'Email administrators when a new user registers'|@translate}</span>
+        <input type="checkbox" name="email_admin_on_new_user" {if ($main.email_admin_on_new_user)}checked="checked"{/if} />
+      </label>
+    </li>
+  </ul>
+</fieldset>
+{/if}
+
+{if isset($history)}
+<fieldset id="historyConf">
+  <ul>
+      <li>
+        <label><span class="property">{'conf_history_guest'|@translate}</span><input type="checkbox" name="history_guest" {if ($history.history_guest)}checked="checked"{/if} /></label>
+      </li>
+
+      <li>
+        <label><span class="property">{'conf_history_user'|@translate}</span><input type="checkbox" name="log" {if ($history.log)}checked="checked"{/if} /></label>
+      </li>
+
+      <li>
+        <label><span class="property">{'conf_history_admin'|@translate}</span><input type="checkbox" name="history_admin" {if ($history.history_admin)}checked="checked"{/if} /></label>
+      </li>
+  </ul>
+</fieldset>
+{/if}
+
+
+{if isset($comments)}
+<fieldset id="commentsConf">
+  <ul>
+    <li>
+      <label>
+        <span class="property">{'Comments for all'|@translate}</span>
+        <input type="checkbox" name="comments_forall" {if ($comments.comments_forall)}checked="checked"{/if} />
+      </label>
+    </li>
+
+    <li>
+      <span class="property">
+        <label for="nb_comment_page">{'Number of comments per page'|@translate}</label>
+      </span>
+      <input type="text" size="3" maxlength="4" name="nb_comment_page" id="nb_comment_page" value="{$comments.NB_COMMENTS_PAGE}" />
+    </li>
+
+    <li>
+      <label>
+        <span class="property">{'Validation'|@translate}</span>
+        <input type="checkbox" name="comments_validation" {if ($comments.comments_validation)}checked="checked"{/if} />
+      </label>
+    </li>
+
+
+    <li>
+      <label>
+        <span class="property">{'Email administrators when a valid comment is entered'|@translate}</span>
+        <input type="checkbox" name="email_admin_on_comment" {if ($comments.email_admin_on_comment)}checked="checked"{/if} />
+      </label>
+    </li>
+
+    <li>
+      <label>
+        <span class="property">{'Email administrators when a comment requires validation'|@translate}</span>
+        <input type="checkbox" name="email_admin_on_comment_validation" {if ($comments.email_admin_on_comment_validation)}checked="checked"{/if} />
+      </label>
+    </li>
+
+  </ul>
+</fieldset>
+{/if}
+
+{if isset($upload)}
+<fieldset id="uploadConf">
+  <ul>
+    <li>
+      <label><span class="property">{'Show upload link every time'|@translate}</span>
+      <input type="checkbox" name="upload_link_everytime" {if ($upload.upload_link_everytime)}checked="checked"{/if} /></label>
+    </li>
+    <li>
+      <label><span class="property">{'User access level to upload'|@translate}</span>
+      {html_options name="upload_user_access" options=$upload.upload_user_access_options selected=$upload.upload_user_access_options_selected}
+    </li>
+    <li>
+      <label>
+        <span class="property">{'Email administrators when a picture is uploaded'|@translate}</span>
+        <input type="checkbox" name="email_admin_on_picture_uploaded" {if ($upload.email_admin_on_picture_uploaded)}checked="checked"{/if} />
+      </label>
+    </li>
+  </ul>
+</fieldset>
+{/if}
+
+{if isset($default)}
+{$PROFILE_CONTENT}
+{/if}
+
+{if !isset($default)}
+  <p>
+    <input class="submit" type="submit" name="submit" value="{'Submit'|@translate}" {$TAG_INPUT_ENABLED}>
+    <input class="submit" type="reset" name="reset" value="{'Reset'|@translate}">
+  </p>
+{/if}
+</form>
Index: /tags/2.0.2/admin/template/goto/content.css
===================================================================
--- /tags/2.0.2/admin/template/goto/content.css	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/content.css	(revision 3278)
@@ -0,0 +1,27 @@
+/* $Id$ */
+/* .Content  is on every pages so it is common and it will no longer be a specific css */
+.content { margin-right: 1em; margin-bottom: 1em; }
+.content h2 { margin-bottom: 3px;}
+.content .navigationBar { margin: 10px 0; text-align: center; }
+.content form { text-align: left; }
+.content dt { margin-bottom: 5px; font-style: italic;
+  font-size: 110%; }
+.content ul.categoryActions a img, ul.categoryActions a { 
+border:0; margin-bottom:-5px; }  
+ul.categoryActions { margin: 0 2px; width: auto; list-style-position:outside;
+  padding: 0; text-indent: 0; list-style: none; text-align: center; }
+.content div.titrePage ul.categoryActions { float: right; }
+.content div.titrePage { padding: 0 0 3px; }
+.content ul.categoryActions li { display: inline; }
+.content div.comment { margin: 0 0 0.5em 0; padding: 0; 
+  overflow: hidden; width: 100%;	/* don't ask why. It's a very usefull trick  */ }
+.content div.comment a.illustration {
+  display: block; float: left; margin: 0.5em 0 0 0.5em; }
+.content div.comment p.commentHeader {
+  text-align: right; margin: 0.5em 0.5em 0 0; }
+.content div.comment ul.actions { text-align: center; margin: 0.2em; }
+.content div.comment blockquote {
+  margin-right: 0.5em; overflow: visible; /*avoid a very strange margin behaviour (all browsers) */ }
+
+  /* not used but should be */
+body#thePopuphelpPage .content { margin: 1em; }
Index: /tags/2.0.2/admin/template/goto/default-colors.css
===================================================================
--- /tags/2.0.2/admin/template/goto/default-colors.css	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/default-colors.css	(revision 3278)
@@ -0,0 +1,86 @@
+/* $Id$ */
+
+
+/* So that non-links are slightly greyed out */
+.content .navigationBar {
+	color: #999;
+}
+
+/* Tables & forms */
+
+INPUT.text, INPUT.password, INPUT.button,
+INPUT.submit, INPUT.reset, INPUT.file,
+SELECT, TEXTAREA {
+  color:#999;
+  background-color: #666;	
+}
+
+INPUT:focus, SELECT:focus, TEXTAREA:focus, INPUT.focus, FORM .focus {
+  background-color: #444;	/* whitesmoke */
+}
+
+/* some theme set a border on INPUT  which is not pretty for radio/checkbox */
+INPUT[type="radio"], INPUT[type="checkbox"] {
+  border: none;	/* <= Opera needs this */
+}
+
+INPUT.radio, INPUT.checkbox {
+  border: none;	/* <= IE6 needs this */
+}
+
+.errors { /* Errors display */
+  color: #f33;
+  background-color: transparent;
+  font-weight: bold;
+  text-align: left;
+  margin: 5px;
+  border: 1px solid #666;
+  background-image: url(icon/errors.png);
+  background-repeat: no-repeat;
+  background-position: top right;
+  padding: 10px 50px 10px 10px;
+}
+
+/**
+ * Informations box in administration
+ */
+.infos {
+  text-align: left;
+  color: #f70;
+  background-color: transparent; 
+  background-image: url(icon/infos.png);
+  background-repeat: no-repeat;
+  background-position: top right;
+  margin: 5px;
+  padding: 10px 50px 10px 10px;
+}
+
+/**
+ * Header message like upgrade or adviser mode
+ */
+.header_msgs {
+  text-align:center;
+  font-weight: bold;
+  color:#333;
+  background-color: transparent;
+  margin: 1px;
+  padding: 1px;
+}
+
+/**
+ * Header notes box in public/administration
+ */
+.header_notes {
+  border: 1px solid #666; 
+  text-align: center;
+  background-image: url(icon/note.png);
+  background-repeat: no-repeat;
+  background-position: top left;
+  font-weight: bold;
+  margin: 14px;
+  padding: 5px 00px 0px 0px;
+}
+
+LEGEND {
+  font-style: italic;
+}
Index: /tags/2.0.2/admin/template/goto/default-layout.css
===================================================================
--- /tags/2.0.2/admin/template/goto/default-layout.css	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/default-layout.css	(revision 3278)
@@ -0,0 +1,458 @@
+/* $Id$ */
+
+/* History tables */
+TABLE.table2 {
+	border: 1px solid #111;
+	margin: 1em auto;
+	padding: 0;
+}
+
+TABLE.table2 TD, TABLE.table2 TH {
+	padding: 0 5px;
+}
+
+TABLE.table2 TR {
+	text-align: left;
+}
+
+TABLE.table2 THEAD TD { padding:7px 10px 3px 10px; }
+TABLE.table2 TR.throw { text-align: center; }
+TABLE.table2 { margin:0pt auto; }
+.sort { display:block; padding:8px 5px 0px 1px; clear: right; text-align:left; }
+
+
+.hour {
+	white-space: pre;
+}
+
+.number {
+	text-align: right;
+}
+
+TABLE#dailyStats {
+	width: 60%;
+}
+
+TABLE#detailedStats {
+	width: 99%;
+}
+
+/* Plugins tables */
+TABLE.plugins { min-width: 400px; }
+TABLE.plugins A { border: 0; }
+TABLE.plugins TR TD { padding: 4px 10px; }
+TABLE.plugins TR TD.pluginState { padding: 4px 16px; }
+
+TABLE.plugins TR TD.active {
+	background: url(icon/plugin_active.gif) no-repeat center left;
+	background-color: inherit; /* IE need it */
+}
+
+TABLE.plugins TR TD.inactive {
+	background: url(icon/plugin_inactive.gif) no-repeat center left;
+	background-color: inherit; /* IE need it */
+}
+
+TABLE.plugins ul.pluginsActions {
+	float: left;
+	padding: 0;
+	margin: 0;
+	width: 60px;
+	list-style: none;
+	text-align: center;
+}
+
+TABLE.plugins ul.pluginsActions li { display: inline; }
+
+/* categoryOrdering */
+SELECT.categoryList {
+	width: 100%;
+}
+ 
+FORM#categoryOrdering {
+	padding-left: 1em; /* same as FIELDSET margin (there is no fieldset in this form) */
+	padding-right: 1em; /* same as FIELDSET margin (there is no fieldset in this form) */
+}
+FORM#categoryOrdering p {
+	text-align: left;
+	margin-top: 1em;
+	margin-bottom: 1em;
+}
+UL.categoryUl {
+	list-style: none;
+	padding: 0;
+	margin: 0;
+}
+
+LI.categoryLi {
+	width: 100%;
+	border: 1px solid #666;
+	padding: 0px 5px;
+	margin-bottom: 5px;
+}
+
+FORM#categoryOrdering UL.categoryActions {
+	float: right;
+	margin-top: 5px;
+}
+/* */
+
+FORM#catModify TABLE { width: auto; }
+
+FIELDSET.elementEdit A {
+	display: block;
+	float: right;
+}
+
+TABLE.doubleSelect {
+	text-align: center;
+	margin: 0 auto;
+	width: 100%;
+}
+
+TABLE.doubleSelect TD {
+	padding: 0 3px;
+	width: 50%;
+}
+
+TABLE.doubleSelect SELECT.categoryList {
+	width: 100%; max-width: 100%; overflow-x: auto;
+}
+
+FORM#categoryPermissions LI {
+	display:inline;
+	white-space: nowrap;
+}
+
+FIELDSET#mainConfCheck SPAN.property,
+FIELDSET#historyConf SPAN.property,
+FIELDSET#commentsConf SPAN.property,
+FIELDSET#uploadConf SPAN.property {
+	float: right;
+	text-align: left;
+}
+FIELDSET#mainConfCheck INPUT,
+FIELDSET#historyConf INPUT,
+FIELDSET#commentsConf INPUT,
+FIELDSET#uploadConf INPUT {
+	float: none;
+}
+
+FIELDSET#mainConf SPAN.property {
+	width: 25%;
+}
+FIELDSET#mainConf TEXTAREA.description {
+	width: 70%;
+}
+
+FIELDSET#mainConfCheck SPAN.property,
+FIELDSET#historyConf SPAN.property {
+	width: 90%;
+}
+FIELDSET#mainConfCheck INPUT,
+FIELDSET#historyConf INPUT,
+FIELDSET#commentsConf INPUT {
+	margin-left: 5%;
+}
+FIELDSET#uploadConf SELECT {
+	float: right;
+	margin: 2px 10px 0px;
+}
+FIELDSET#uploadConf INPUT {
+	float: right;
+	margin: 5px 10px 0px;
+}
+FIELDSET#uploadConf SPAN.property {
+	width: 65%;
+}
+FIELDSET#commentsConf SPAN.property {
+	width: 85%;
+}
+
+.statBar {
+	height: 10px;
+	background-color: #ff7700;
+	border: 1px solid #666;
+}
+
+.over{
+position: relative;
+z-index: 0;
+}
+
+.over:hover{
+background-color: transparent;
+z-index: 50;
+}
+
+.over SPAN{ /*CSS for enlarged image*/
+position: absolute;
+background-color: #222;
+padding: 5px;
+left: -1000px;
+border: 1px solid #ff3363;
+visibility: hidden;
+color: black;
+text-decoration: none;
+}
+
+.over SPAN IMG{ /*CSS for enlarged image*/
+border-width: 0;
+padding: 2px;
+}
+
+.over:hover SPAN{ /*CSS for enlarged image on hover*/
+visibility: visible;
+top: 0;
+left: 60px; /*position where enlarged image should offset horizontally */
+}
+
+BODY {
+	margin: 5px;
+	padding: 0;
+	font-size: 0.8em;
+	font-family: Univers, Helvetica, Optima, "Bitstream Vera Sans", sans-serif;
+	text-align: center; /* be nice to IE5 */
+}
+
+H1 {
+	text-align: center;
+	font-size: 150%;
+	font-weight: bold;
+	padding: 0;
+	margin: 0.5em 0 1em 0;
+}
+
+H2 {
+	margin: 0;
+	padding: 5px 0.5em 5px 0.5em;
+	text-align: left;
+	font-size: 120%;
+}
+
+A {
+	text-decoration:none;
+	border-bottom: 0;
+}
+A:hover {
+	border-bottom: 1px solid #FF3363;
+}
+A.button, A.button:hover { 
+	border: 0; 
+}
+IMG {
+	border: none;
+}
+
+HR.separation {
+	visibility: hidden;
+	clear: both;
+}
+
+#copyright {
+	clear: both;
+	font-size: 83%;
+	text-align: center;
+	margin: 0 0 10px 0;
+}
+
+/** General defaults **/
+INPUT, SELECT {
+	margin: 0;
+	font-size: 1em;	/* <= some browsers don't set it correctly */
+}
+UL, DL, OL { text-align: left;}
+TABLE { /* horizontaly centered */
+	margin-left: auto;
+	margin-right: auto;
+}
+/* for debugging purpose */
+PRE { text-align:left; }
+
+/** forms **/
+
+FORM { padding: 0em; }
+
+FORM P {
+	text-align: center;
+	margin-top: 2em;
+	margin-bottom: 2em;
+}
+
+FORM FIELDSET P {
+	margin-top: 1em;
+	margin-bottom: 0;
+}
+
+.small {
+	font-size: 80%;
+}
+
+TEXTAREA.description {
+	height: 6em;
+	width: 40em;
+	overflow: auto;
+}
+
+SELECT.categoryList {
+	height: 20em;
+	width: auto;
+}
+
+DIV.comment BLOCKQUOTE {
+	padding: 0.5em;
+	overflow: auto;	/* no solution for IE6 */
+	min-height: 2.75em;	/* fix a Gecko bug whith scrollbar and 1 line only */
+}
+
+
+/**
+ * Filter forms are displayed label by label with the input (or select...)
+ * below the label. Use an UL to make a group (radiobox for instance).
+ * Use a SPAN to group objects in line
+ */
+FIELDSET {
+	padding: 1em;
+	margin: 1em;
+	overflow: hidden; /* <- makes Opera happy */
+}
+
+FORM.filter FIELDSET UL {
+	margin: 0;
+}
+FORM.filter FIELDSET UL,
+FORM.filter FIELDSET LABEL {
+	display: block;
+	float: left;
+	margin-right: 1em;
+	padding: 0;
+}
+
+FORM.filter FIELDSET LI {
+	list-style: none;
+	margin-bottom: 0.5em;
+}
+
+FORM.filter FIELDSET LI LABEL {
+	display: inline;
+	float: none;
+}
+
+FORM.filter FIELDSET UL.tagSelection LABEL {
+	display: inline;
+	float: none;
+	margin-right:0.5em;/*reduce from above*/
+}
+
+/* cannot use FIELDSET>LABEL because of IE<=6 */
+FORM.filter FIELDSET LABEL INPUT,
+FORM.filter FIELDSET LABEL SELECT,
+FORM.filter FIELDSET LABEL SPAN,
+FORM.filter FIELDSET LABEL TEXTAREA {
+	display: block;
+	margin: 0.5em 0;
+}
+FORM.filter FIELDSET * LABEL INPUT,
+FORM.filter FIELDSET * LABEL SELECT,
+FORM.filter FIELDSET * LABEL TEXTAREA,
+FORM.filter FIELDSET LABEL SPAN INPUT,
+FORM.filter FIELDSET LABEL SPAN SELECT,
+FORM.filter FIELDSET LABEL SPAN TEXTAREA {
+	display: inline;
+	vertical-align: top;
+	margin: 0 0.5em 0 0;
+}
+
+FORM.filter FIELDSET UL.tagSelection LI LABEL INPUT {
+	margin-right:0;
+}
+
+/* following declaration is important to avoid strange FF behaviour */
+FORM.filter FIELDSET LABEL SPAN SELECT {
+	margin: 0;
+}
+
+FORM.filter FIELDSET P
+{
+	clear: left;
+	display: block;
+}
+
+FORM.filter INPUT[type="submit"] {
+	margin-top: 1.8em;
+}
+
+FORM.properties UL, FORM#update UL {
+	list-style-type: none;
+	margin: 0;
+	padding: 0;
+}
+
+FORM.properties LI, FORM#update UL {
+	margin-bottom: 0.5em;
+	padding: 0;
+	line-height: 1.8em;
+	clear: left;
+}
+
+FORM.properties SPAN.property {
+	font-weight: bold;
+	float: left;
+	width: 50%;
+	text-align: right;
+	margin: 0;
+	padding: 0 0.5em 0 0;
+}
+
+#theHeader H1 {
+	margin-bottom: 0.5em;
+}
+
+/* button tools */
+UL.actions {
+	text-indent: 0;
+	list-style: none;
+}
+UL.actions LI {
+	display: inline;
+}
+UL.actions A {
+	border: none;
+}
+
+UL.tagSelection {
+	width: 99%;
+	margin: 1em 0 1em 0;
+	padding: 0;
+}
+
+UL.tagSelection LI {
+	display: inline;
+	white-space: nowrap;
+}
+
+
+/* jQuery tooltips */
+.cluetip-default #cluetip-outer {
+	position: relative;
+	border: 1px solid #111111;
+	color: #dddddd;
+	background-color: #222222;
+	text-align: left;
+}
+.cluetip-default h3#cluetip-title {
+	margin: 0 0 5px;
+	padding: 8px;
+	color: #666666;
+	background-color: #d3d3d3;
+	font-size: 1.1em;
+	font-weight: bold;
+}
+.cluetip-default #cluetip-inner {
+	padding: 10px;
+}
+
+/* jQuery datepicker */
+img.ui-datepicker-trigger {
+	cursor : pointer;
+}
Index: /tags/2.0.2/admin/template/goto/double_select.tpl
===================================================================
--- /tags/2.0.2/admin/template/goto/double_select.tpl	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/double_select.tpl	(revision 3278)
@@ -0,0 +1,23 @@
+{* $Id$ *}
+
+{include file='include/dbselect.inc.tpl'}
+
+<table class="doubleSelect">
+  <tr>
+    <td>
+      <h3>{$L_CAT_OPTIONS_TRUE}</h3>
+      <select class="categoryList" name="cat_true[]" multiple="multiple" size="30">
+        {html_options options=$category_option_true selected=$category_option_true_selected}
+      </select>
+      <p><input class="submit" type="submit" value="&raquo;" name="falsify" style="font-size:15px;" {$TAG_INPUT_ENABLED}/></p>
+    </td>
+
+    <td>
+      <h3>{$L_CAT_OPTIONS_FALSE}</h3>
+      <select class="categoryList" name="cat_false[]" multiple="multiple" size="30">
+        {html_options options=$category_option_false selected=$category_option_false_selected}
+      </select>
+      <p><input class="submit" type="submit" value="&laquo;" name="trueify" style="font-size:15px;" {$TAG_INPUT_ENABLED}/></p>
+    </td>
+  </tr>
+</table>
Index: /tags/2.0.2/admin/template/goto/element_set_global.tpl
===================================================================
--- /tags/2.0.2/admin/template/goto/element_set_global.tpl	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/element_set_global.tpl	(revision 3278)
@@ -0,0 +1,212 @@
+{* $Id$ *}
+
+{include file='include/datepicker.inc.tpl'}
+
+{literal}
+<script type="text/javascript">
+  pwg_initialization_datepicker("#date_creation_day", "#date_creation_month", "#date_creation_year", "#date_creation_linked_date", "#date_creation_action_set");
+</script>
+{/literal}
+
+<h2>{'Batch management'|@translate}</h2>
+
+<h3>{$CATEGORIES_NAV}</h3>
+
+{if !empty($thumbnails)}
+  <p style="text-align:center;">
+    {'global mode'|@translate}
+    | <a href="{$U_UNIT_MODE}">{'unit mode'|@translate}</a>
+  </p>
+
+  <fieldset>
+
+    <legend>{'Display options'|@translate}</legend>
+
+    <p>{'elements per page'|@translate}:
+        <a href="{$U_DISPLAY}&amp;display=20">20</a>
+      | <a href="{$U_DISPLAY}&amp;display=50">50</a>
+      | <a href="{$U_DISPLAY}&amp;display=100">100</a>
+      | <a href="{$U_DISPLAY}&amp;display=all">{'all'|@translate}</a>
+    </p>
+
+  </fieldset>
+
+  <form action="{$F_ACTION}" method="post">
+
+  <fieldset>
+
+    <legend>{'Elements'|@translate}</legend>
+
+    {if !empty($NAV_BAR)}<div class="navigationBar">{$NAV_BAR}</div>{/if}
+
+  {if !empty($thumbnails)}
+    <ul class="thumbnails">
+      {foreach from=$thumbnails item=thumbnail}
+      <li><span class="wrap1">
+          <label>
+            <span class="wrap2">
+        {if $thumbnail.LEVEL > 0}
+        <em class="levelIndicatorB">{$thumbnail.LEVEL}</em>
+        <em class="levelIndicatorF" title="{$pwg->l10n($pwg->sprintf('Level %d',$thumbnail.LEVEL))}">{$thumbnail.LEVEL}</em>
+        {/if}
+            <span>
+              <img src="{$thumbnail.TN_SRC}"
+                 alt="{$thumbnail.FILE}"
+                 title="{$thumbnail.TITLE}"
+                 class="thumbnail" />
+            </span></span>
+            <input type="checkbox" name="selection[]" value="{$thumbnail.ID}" />
+          </label>
+          </span>
+      </li>
+      {/foreach}
+    </ul>
+  {/if}
+
+  </fieldset>
+
+  {if $show_delete_form}
+  <fieldset>
+    <legend>{'Deletions'|@translate}</legend>
+    <p style="font-style:italic">{'Note: Only deletes photos added with pLoader'|@translate}</p>
+    <p>
+      {'target'|@translate}
+      <label><input type="radio" name="target_deletion" value="all" /> {'all'|@translate}</label>
+      <label><input type="radio" name="target_deletion" value="selection" checked="checked" /> {'selection'|@translate}</label>
+    </p>
+    <p>
+    <label><input type="checkbox" name="confirm_deletion" value="1" /> {'confirm'|@translate}</label>
+    <input class="submit" type="submit" value="{'Delete selected photos'|@translate}" name="delete" {$TAG_INPUT_ENABLED}/>
+    </p>
+  </fieldset>
+  {/if}
+
+  <fieldset>
+
+    <legend>{'Form'|@translate}</legend>
+
+    <table>
+
+      <tr>
+        <td>{'associate to category'|@translate}</td>
+        <td>
+          <select style="width:400px" name="associate" size="1">
+            <option value="0">------------</option>
+            {html_options options=$associate_options }
+         </select>
+        </td>
+      </tr>
+
+      <tr>
+        <td>{'dissociate from category'|@translate}</td>
+        <td>
+          <select style="width:400px" name="dissociate" size="1">
+            <option value="0">------------</option>
+            {if !empty($dissociate_options)}{html_options options=$dissociate_options }{/if}
+          </select>
+        </td>
+      </tr>
+
+      <tr>
+        <td>{'add tags'|@translate}</td>
+        <td>{if !empty($ADD_TAG_SELECTION)}{$ADD_TAG_SELECTION}{else}<p>{'No tag defined. Use Administration>Pictures>Tags'|@translate}</p>{/if}</td>
+      </tr>
+
+      {if !empty($DEL_TAG_SELECTION)}
+      <tr>
+        <td>{'remove tags'|@translate}</td>
+        <td>{$DEL_TAG_SELECTION}</td>
+      </tr>
+      {/if}
+
+      <tr>
+        <td>{'Author'|@translate}</td>
+        <td>
+          <label><input type="radio" name="author_action" value="leave" checked="checked" /> {'leave'|@translate}</label>
+          <label><input type="radio" name="author_action" value="unset" /> {'unset'|@translate}</label>
+          <label><input type="radio" name="author_action" value="set" id="author_action_set" /> {'set to'|@translate}</label>
+          <input onchange="document.getElementById('author_action_set').checked = true;" type="text" class="large" name="author" value="" />
+        </td>
+      </tr>
+
+      <tr>
+        <td>{'title'|@translate}</td>
+        <td>
+          <label><input type="radio" name="name_action" value="leave" checked="checked" /> {'leave'|@translate}</label>
+          <label><input type="radio" name="name_action" value="unset" /> {'unset'|@translate}</label>
+          <label><input type="radio" name="name_action" value="set" id="name_action_set" /> {'set to'|@translate}</label>
+          <input onchange="document.getElementById('name_action_set').checked = true;" type="text" class="large" name="name" value="" />
+        </td>
+      </tr>
+
+      <tr>
+        <td>{'Creation date'|@translate}</td>
+        <td>
+          <label><input type="radio" name="date_creation_action" value="leave" checked="checked" /> {'leave'|@translate}</label>
+          <label><input type="radio" name="date_creation_action" value="unset" /> {'unset'|@translate}</label>
+          <label><input type="radio" name="date_creation_action" value="set" id="date_creation_action_set" /> {'set to'|@translate}</label>
+          <select id="date_creation_day" name="date_creation_day">
+             <option value="0">--</option>
+            {section name=day start=1 loop=32}
+              <option value="{$smarty.section.day.index}" {if $smarty.section.day.index==$DATE_CREATION_DAY}selected="selected"{/if}>{$smarty.section.day.index}</option>
+            {/section}
+          </select>
+          <select id="date_creation_month" name="date_creation_month">
+            {html_options options=$month_list selected=$DATE_CREATION_MONTH}
+          </select>
+          <input id="date_creation_year"
+                 name="date_creation_year"
+                 type="text"
+                 size="4"
+                 maxlength="4"
+                 value="{$DATE_CREATION_YEAR}" />
+          <input id="date_creation_linked_date" name="date_creation_linked_date" type="hidden" size="10" disabled="disabled"/>
+        </td>
+      </tr>
+
+    <tr>
+      <td>{'Minimum privacy level'|@translate}</td>
+      <td>
+        <label><input type="radio" name="level_action" value="leave" checked="checked" />{'leave'|@translate}</label>
+        <label><input type="radio" name="level_action" value="set" id="level_action_set" />{'set to'|@translate}</label>
+        <select onchange="document.getElementById('level_action_set').checked = true;" name="level" size="1">
+          {html_options options=$level_options}
+        </select>
+      </td>
+    </tr>
+
+    </table>
+
+    <p>
+      {'target'|@translate}
+      <label><input type="radio" name="target" value="all" /> {'all'|@translate}</label>
+      <label><input type="radio" name="target" value="selection" checked="checked" /> {'selection'|@translate}</label>
+    </p>
+
+
+    <p><input class="submit" type="submit" value="{'Submit'|@translate}" name="submit" {$TAG_INPUT_ENABLED}/></p>
+
+  </fieldset>
+
+  <fieldset>
+
+    <legend>{'Caddie management'|@translate}</legend>
+
+    <ul style="list-style-type:none;">
+      {if ($IN_CADDIE)}
+      <li><label><input type="radio" name="caddie_action" value="empty_all" /> {'Empty caddie'|@translate}</label></li>
+      <li><label><input type="radio" name="caddie_action" value="empty_selected" /> {'Take selected elements out of caddie'|@translate}</label></li>
+      {else}
+      <li><label><input type="radio" name="caddie_action" value="add_selected" /> {'Add selected elements to caddie'|@translate}</label></li>
+      {/if}
+    </ul>
+
+    <p><input class="submit" type="submit" value="{'Submit'|@translate}" name="submit_caddie" /></p>
+
+  </fieldset>
+
+  </form>
+
+{else}
+  <div class="infos"><p>{'Caddie is currently empty'|@translate}</p></div>
+{/if}
Index: /tags/2.0.2/admin/template/goto/element_set_ranks.tpl
===================================================================
--- /tags/2.0.2/admin/template/goto/element_set_ranks.tpl	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/element_set_ranks.tpl	(revision 3278)
@@ -0,0 +1,41 @@
+<h2>{'Manage image ranks'|@translate}</h2>
+
+<h3>{$CATEGORIES_NAV}</h3>
+
+{if !empty($thumbnails)}
+  <form action="{$F_ACTION}" method="post">
+
+  <fieldset>
+
+    <legend>{'Edit ranks'|@translate}</legend>
+
+  {if !empty($thumbnails)}
+    <ul class="thumbnails">
+      {foreach from=$thumbnails item=thumbnail}
+      <li><span class="wrap1">
+          <label>
+            <span class="wrap2">
+        {if $thumbnail.LEVEL > 0}
+        <em class="levelIndicatorB">{$thumbnail.LEVEL}</em>
+        <em class="levelIndicatorF" title="{$pwg->l10n($pwg->sprintf('Level %d',$thumbnail.LEVEL))}">{$thumbnail.LEVEL}</em>
+        {/if}
+            <span>
+              <img src="{$thumbnail.TN_SRC}" class="thumbnail" />
+            </span></span>
+            <input style="height:12px; width:50px;" type="text" name="rank_of_image[{$thumbnail.ID}]" value="{$thumbnail.RANK}" />
+          </label>
+          </span>
+      </li>
+      {/foreach}
+    </ul>
+  {/if}
+
+    <p><input class="submit" type="submit" value="{'Submit'|@translate}" name="submit" {$TAG_INPUT_ENABLED}/></p>
+
+  </fieldset>
+
+  </form>
+
+{else}
+  <div class="infos"><p>{'No element in this category'|@translate}</p></div>
+{/if}
Index: /tags/2.0.2/admin/template/goto/element_set_unit.tpl
===================================================================
--- /tags/2.0.2/admin/template/goto/element_set_unit.tpl	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/element_set_unit.tpl	(revision 3278)
@@ -0,0 +1,112 @@
+{* $Id$ *}
+
+{include file='include/autosize.inc.tpl'}
+{include file='include/datepicker.inc.tpl'}
+
+<h2>{'Batch management'|@translate}</h2>
+
+<h3>{$CATEGORIES_NAV}</h3>
+
+<p style="text-align:center;">
+  <a href="{$U_GLOBAL_MODE}">{'global mode'|@translate}</a>
+  | {'unit mode'|@translate}
+</p>
+
+<form action="{$F_ACTION}" method="POST">
+<fieldset>
+  <legend>{'Display options'|@translate}</legend>
+  <p>{'elements per page'|@translate} :
+      <a href="{$U_ELEMENTS_PAGE}&amp;display=5">5</a>
+    | <a href="{$U_ELEMENTS_PAGE}&amp;display=10">10</a>
+    | <a href="{$U_ELEMENTS_PAGE}&amp;display=50">50</a>
+    | <a href="{$U_ELEMENTS_PAGE}&amp;display=all">{'all'|@translate}</a>
+  </p>
+
+</fieldset>
+
+{if !empty($NAV_BAR) }
+<div class="navigationBar">{$NAV_BAR}</div>
+{/if}
+
+{if !empty($elements) }
+<input type="hidden" name="element_ids" value="{$ELEMENT_IDS}" />
+{foreach from=$elements item=element}
+<fieldset class="elementEdit">
+  <legend>{$element.LEGEND}</legend>
+
+  <a href="{$element.U_EDIT}"><img src="{$element.TN_SRC}" alt="" title="{'Edit all picture informations'|@translate}" /></a>
+
+  <table>
+
+    <tr>
+      <td><strong>{'Name'|@translate}</strong></td>
+      <td><input type="text" class="large" name="name-{$element.ID}" value="{$element.NAME}" /></td>
+    </tr>
+
+    <tr>
+      <td><strong>{'Author'|@translate}</strong></td>
+      <td><input type="text" class="large" name="author-{$element.ID}" value="{$element.AUTHOR}" /></td>
+    </tr>
+
+    <tr>
+      <td><strong>{'Creation date'|@translate}</strong></td>
+      <td>
+        <label><input type="radio" name="date_creation_action-{$element.ID}" value="unset" /> {'unset'|@translate}</label>
+        <label><input type="radio" name="date_creation_action-{$element.ID}" value="set" id="date_creation_action_set-{$element.ID}" /> {'set to'|@translate}</label>
+
+        <select id="date_creation_day-{$element.ID}" name="date_creation_day-{$element.ID}">
+         	<option value="0">--</option>
+           {section name=day start=1 loop=32}
+             <option value="{$smarty.section.day.index}" {if $smarty.section.day.index==$element.DATE_CREATION_DAY}selected="selected"{/if}>{$smarty.section.day.index}</option>
+           {/section}
+        </select>
+        <select id="date_creation_month-{$element.ID}" name="date_creation_month-{$element.ID}">
+          {html_options options=$month_list selected=$element.DATE_CREATION_MONTH}
+        </select>
+        <input id="date_creation_year-{$element.ID}"
+               name="date_creation_year-{$element.ID}"
+               type="text"
+               size="4"
+               maxlength="4"
+               value="{$element.DATE_CREATION_YEAR}" />
+        <input id="date_creation_linked_date-{$element.ID}" name="date_creation_linked_date-{$element.ID}" type="hidden" size="10" disabled="disabled"/>
+        <script type="text/javascript">
+          pwg_initialization_datepicker("#date_creation_day-{$element.ID}", "#date_creation_month-{$element.ID}", "#date_creation_year-{$element.ID}", "#date_creation_linked_date-{$element.ID}", "#date_creation_action_set-{$element.ID}");
+        </script>
+      </td>
+    </tr>
+
+    <tr>
+      <td><strong>{'Tags'|@translate}</strong></td>
+      <td>{$element.TAG_SELECTION}</td>
+    </tr>
+
+    <tr>
+      <td><strong>{'Description'|@translate}</strong></td>
+      <td><textarea name="description-{$element.ID}" id="description-{$element.ID}" class="description">{$element.DESCRIPTION}</textarea></td>
+    </tr>
+
+  </table>
+
+</fieldset>
+{/foreach}
+
+<p>
+  <input class="submit" type="submit" value="{'Submit'|@translate}" name="submit" {$TAG_INPUT_ENABLED}/>
+  <input class="submit" type="reset" value="{'Reset'|@translate}" />
+</p>
+{/if}
+
+</form>
+
+<script type="text/javascript">// <![CDATA[
+{literal}$(document).ready(function() {
+	$(".elementEdit img").fadeTo("slow", 0.6); // Opacity on page load
+	$(".elementEdit img").hover(function(){
+		$(this).fadeTo("slow", 1.0); // Opacity on hover
+	},function(){
+   		$(this).fadeTo("slow", 0.6); // Opacity on mouseout
+	});
+});{/literal}
+// ]]>
+</script>
Index: /tags/2.0.2/admin/template/goto/extend_for_templates.tpl
===================================================================
--- /tags/2.0.2/admin/template/goto/extend_for_templates.tpl	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/extend_for_templates.tpl	(revision 3278)
@@ -0,0 +1,38 @@
+{* $Id$ *}
+<div class="titrePage"><h2>{'extend_for_templates'|@translate}</h2>
+</div>
+{if isset($extents)}
+<h4>{'Replacement of original templates'|@translate}</h4>
+<form method="post" name="extend_for_templates" id="extend_for_templates" action="">
+  <table class="table2">
+    <tr class="throw">
+      <th>{'Replacers'|@translate}</th>
+      <th>{'Original templates'|@translate}</th>
+      <th>{'Optional URL keyword'|@translate}</th>
+      <th>{'Bound template'|@translate}</th>
+    </tr>
+    {foreach from=$extents item=tpl name=extent_loop}
+    <tr class="{if $smarty.foreach.extent_loop.index is odd}row1{else}row2{/if}">
+      <td>
+        <input type="hidden" name=reptpl[] value="{$tpl.replacer}" />
+        {$tpl.replacer}
+      </td>
+      <td>
+        {html_options name=original[] output=$tpl.original_tpl values=$tpl.original_tpl selected=$tpl.selected_tpl}
+      </td>
+      <td>
+        {html_options name=url[] output=$tpl.url_parameter values=$tpl.url_parameter selected=$tpl.selected_url}
+      </td>
+      <td>
+        {html_options name=bound[] output=$tpl.bound_tpl values=$tpl.bound_tpl selected=$tpl.selected_bound}
+      </td>
+    </tr>
+    {/foreach}
+  </table>
+  {if !is_adviser()}
+  <p>
+    <input class="submit" type="submit" value="{'Submit'|@translate}" name="submit" />
+  </p>
+  {/if}
+</form>
+{/if}
Index: /tags/2.0.2/admin/template/goto/fix-ie5-ie6.css
===================================================================
--- /tags/2.0.2/admin/template/goto/fix-ie5-ie6.css	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/fix-ie5-ie6.css	(revision 3278)
@@ -0,0 +1,36 @@
+/* $Id$ */
+/* Issues in IE from 5 to 6 only not to be used with IE7                      */
+
+
+/* to avoid vanishing objects in IE6 */
+H1, #theHeader {
+  width: 100%;	/* <- useless but seems to make IE6 happy */
+}
+.content {
+  height: 1em;	/* for IE6 it's like min-height */
+}
+
+/* fix quickconnect layout */
+FORM#quickconnect FIELDSET {
+  width: 99%;	/* correct an ugly 1 or 2 px misalignement with IE */
+}
+
+/* fix IE with another layout for thumbnails */
+.content UL.thumbnails SPAN.wrap2 {
+  display: block;
+  position: relative;
+  text-align: left;
+}
+
+.content UL.thumbnails IMG.thumbnail {
+  position: relative;
+  top: -50%;  /* Is this following hacking technic required ? */
+  /*\*//*/
+    margin-top: -40%;
+  /**/
+}
+.content UL.thumbnails INPUT {
+  position: absolute;
+  left: 2px;
+  top: 2px;  /* same as other browsers but not so pretty */
+}
Index: /tags/2.0.2/admin/template/goto/footer.tpl
===================================================================
--- /tags/2.0.2/admin/template/goto/footer.tpl	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/footer.tpl	(revision 3278)
@@ -0,0 +1,40 @@
+{* $Id$ *}
+{* 
+          Warning : This is the admin pages footer only 
+          don't be confusing with the public page footer
+*}
+<div id="copyright">
+ <a name="EoP"></a> <!-- End of ADMIN Page -->
+ {if isset($debug.TIME) }
+ {'generation_time'|@translate} {$debug.TIME} ({$debug.NB_QUERIES} {'sql_queries_in'|@translate} {$debug.SQL_TIME}) -
+ {/if}
+
+ {* Please, do not remove this copyright. If you really want to,
+      contact us on http://piwigo.org to find a solution on how
+      to show the origin of the script...
+  *}
+
+  {'powered_by'|@translate}
+  <a href="{$PHPWG_URL}" class="Piwigo">
+  <span class="Piwigo">Piwigo</span></a>
+  {$VERSION}
+  {if isset($CONTACT_MAIL)}
+  - {'send_mail'|@translate}
+  <a href="mailto:{$CONTACT_MAIL}?subject={'title_send_mail'|@translate|@escape:url}">{'Webmaster'|@translate}</a>
+  {/if}
+
+</div> <!-- copyright -->
+{if isset($footer_elements)}
+{foreach from=$footer_elements item=v}
+{$v}
+{/foreach}
+{/if}
+{if isset($debug.QUERIES_LIST)}
+<div id="debug">
+{$debug.QUERIES_LIST}
+</div>
+{/if}
+</div> <!-- the_page -->
+
+</body>
+</html>
Index: /tags/2.0.2/admin/template/goto/group_list.tpl
===================================================================
--- /tags/2.0.2/admin/template/goto/group_list.tpl	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/group_list.tpl	(revision 3278)
@@ -0,0 +1,43 @@
+{* $Id$ *}
+<div class="titrePage">
+  <h2>{'title_groups'|@translate}</h2>
+</div>
+
+<form method="post" name="add_user" action="{$F_ADD_ACTION}" class="properties">
+  <fieldset>
+    <legend>{'Add group'|@translate}</legend>
+
+    <span class="property">
+      <label for="groupname">{'Group name'|@translate}</label>
+    </span>
+    <input type="text" id="groupname" name="groupname" maxlength="50" size="20" />
+
+    <p>
+      <input class="submit" type="submit" name="submit_add" value="{'Add'|@translate}" {$TAG_INPUT_ENABLED}/>
+    </p>
+  </fieldset>
+</form>
+
+<table class="table2">
+  <tr class="throw">
+    <th>{'Group name'|@translate}</th>
+    <th>{'Members'|@translate}</th>
+    <th>{'Actions'|@translate}</th>
+  </tr>
+  {if not empty($groups)}
+  {foreach from=$groups item=group name=group_loop}
+  <tr class="{if $smarty.foreach.group_loop.index is odd}row1{else}row2{/if}">
+    <td>{$group.NAME}<i><small>{$group.IS_DEFAULT}</small></i></td>
+    <td><a href="{$group.U_MEMBERS}">{$group.MEMBERS}</a></td>
+    <td style="text-align:center;">
+      <a href="{$group.U_PERM}">
+        <img src="{$ROOT_URL}{$themeconf.admin_icon_dir}/permissions.png" class="button" style="border:none" id="btn_permissions" alt="{'permissions'|@translate}" title="{'permissions'|@translate}" /></a>
+      <a href="{$group.U_DELETE}" onclick="return confirm( document.getElementById('btn_delete').title + '\n\n' + '{'Are you sure?'|@translate|@escape:'javascript'}');">
+        <img src="{$ROOT_URL}{$themeconf.admin_icon_dir}/delete.png" class="button" style="border:none" id="btn_delete" alt="{'delete'|@translate}" title="{'delete'|@translate}" {$TAG_INPUT_ENABLED}/></a>
+      <a href="{$group.U_ISDEFAULT}" onclick="return confirm( document.getElementById('btn_toggle_is_default_group').title + '\n\n' + '{'Are you sure?'|@translate|@escape:'javascript'}');">
+        <img src="{$ROOT_URL}{$themeconf.admin_icon_dir}/toggle_is_default_group.png" class="button" style="border:none" id="btn_toggle_is_default_group" alt="{'toggle_is_default_group'|@translate}" title="{'toggle_is_default_group'|@translate}" {$TAG_INPUT_ENABLED}/></a>
+    </td>
+  </tr>
+  {/foreach}
+  {/if}
+</table>
Index: /tags/2.0.2/admin/template/goto/group_perm.tpl
===================================================================
--- /tags/2.0.2/admin/template/goto/group_perm.tpl	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/group_perm.tpl	(revision 3278)
@@ -0,0 +1,8 @@
+{* $Id *}
+<h2>{$TITLE}</h2>
+
+<form method="post" action="{$F_ACTION}">
+  {$DOUBLE_SELECT}
+</form>
+
+<p>{'Only private categories are listed'|@translate}</p>
Index: /tags/2.0.2/admin/template/goto/header.tpl
===================================================================
--- /tags/2.0.2/admin/template/goto/header.tpl	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/header.tpl	(revision 3278)
@@ -0,0 +1,65 @@
+{* $Id$ *}
+{* 
+
+          Warning : This is the admin pages header only 
+          don't confuse with the public page header
+
+*}
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+"http://www.w3.org/TR/html4/strict.dtd">
+<html lang="{$lang_info.code}" dir="{$lang_info.direction}">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset={$CONTENT_ENCODING}">
+<meta name="generator" content="Piwigo (aka PWG), see piwigo.org">
+<title>{$GALLERY_TITLE} :: {$PAGE_TITLE}</title>
+<link rel="shortcut icon" type="image/x-icon" href="{$ROOT_URL}template-common/favicon.ico">
+
+<link rel="stylesheet" type="text/css" href="{$ROOT_URL}admin/template/{$themeconf.template}/layout.css">
+<!--[if lt IE 7]>
+  <link rel="stylesheet" type="text/css" href="{$ROOT_URL}admin/template/{$themeconf.template}/fix-ie5-ie6.css">
+<![endif]-->
+<link rel="stylesheet" type="text/css" href="{$ROOT_URL}admin/template/{$themeconf.template}/default-colors.css">
+<link rel="stylesheet" type="text/css" href="{$ROOT_URL}admin/template/{$themeconf.template}/theme/{$themeconf.theme}/theme.css">
+{known_script id="jquery" src=$ROOT_URL|@cat:"template-common/lib/jquery.packed.js" now=1} {*jQuery is always available by default*}
+{$themeconf.local_head}
+<script type="text/javascript" src="{$ROOT_URL}template-common/scripts.js"></script>
+<!--[if lt IE 7]>
+<style>
+  {* only because we need {$ROOT_URL} otherwise use fix-ie5-ie6.css *}
+  BODY {ldelim} behavior:url("{$ROOT_URL}template-common/csshover.htc"); }
+  A IMG, .button, .icon {ldelim}
+    behavior:url("{$ROOT_URL}template-common/tooltipfix.htc");
+  }
+  FORM {ldelim} behavior: url("{$ROOT_URL}template-common/inputfix.htc"); }
+</style>
+<script type="text/javascript" src="{$ROOT_URL}template-common/pngfix.js"></script>
+<![endif]-->
+
+{if not empty($head_elements)}
+{foreach from=$head_elements item=elt}
+{$elt}
+{/foreach}
+{/if}
+
+</head>
+
+<body id="{$BODY_ID}">
+<div id="headbranch"></div> {* Dummy block for double background management *}
+<div id="the_page">
+
+{if not empty($header_msgs)}
+<div class="header_msgs">
+  {foreach from=$header_msgs item=elt}
+  {$elt}
+  {/foreach}
+</div>
+{/if}
+
+<div id="theHeader">{*$PAGE_BANNER*}</div>
+{if not empty($header_notes)}
+<div class="header_notes">
+  {foreach from=$header_notes item=elt}
+  {$elt}
+  {/foreach}
+</div>
+{/if}
Index: /tags/2.0.2/admin/template/goto/history.tpl
===================================================================
--- /tags/2.0.2/admin/template/goto/history.tpl	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/history.tpl	(revision 3278)
@@ -0,0 +1,147 @@
+{* $Id$ *}
+
+{include file='include/datepicker.inc.tpl'}
+
+{literal}
+<script type="text/javascript">
+  pwg_initialization_datepicker("#start_day", "#start_month", "#start_year", "#start_linked_date", null, null, "#end_linked_date");
+  pwg_initialization_datepicker("#end_day", "#end_month", "#end_year", "#end_linked_date", null, "#start_linked_date", null);
+</script>
+{/literal}
+
+<div class="titrePage">
+  <h2>{'History'|@translate} {$TABSHEET_TITLE}</h2>
+</div>
+
+<form class="filter" method="post" name="filter" action="{$F_ACTION}">
+<fieldset>
+  <legend>{'Filter'|@translate}</legend>
+  <ul>
+    <li><label>{'search_date_from'|@translate}</label></li>
+    <li>
+      <select id="start_day" name="start_day">
+        <option value="0">--</option>
+        {section name=day start=1 loop=32}
+        <option value="{$smarty.section.day.index}" {if $smarty.section.day.index==$START_DAY_SELECTED}selected="selected"{/if}>{$smarty.section.day.index}</option>
+        {/section}
+      </select>
+      <select id="start_month" name="start_month">
+      {html_options options=$month_list selected=$START_MONTH_SELECTED}
+      </select>
+      <input id="start_year" name="start_year" value="{$START_YEAR}" type="text" size="4" maxlength="4" >
+      <input id="start_linked_date" name="start_linked_date" type="hidden" size="10" disabled="disabled"/>
+    </li>
+  </ul>
+  <ul>
+    <li><label>{'search_date_to'|@translate}</label></li>
+    <li>
+      <select id="end_day" name="end_day">
+        <option value="0">--</option>
+        {section name=day start=1 loop=32}
+        <option value="{$smarty.section.day.index}" {if $smarty.section.day.index==$END_DAY_SELECTED}selected="selected"{/if}>{$smarty.section.day.index}</option>
+        {/section}
+      </select>
+      <select id="end_month" name="end_month">
+      {html_options options=$month_list selected=$END_MONTH_SELECTED}
+      </select>
+      <input id="end_year" name="end_year" value="{$END_YEAR}" type="text" size="4" maxlength="4" >
+      <input id="end_linked_date" name="end_linked_date" type="hidden" size="10" disabled="disabled"/>
+    </li>
+  </ul>
+
+  <label>
+    {'Element type'|@translate}
+    <select name="types[]" multiple="multiple" size="4">
+      {html_options values=$type_option_values output=$type_option_values|translate selected=$type_option_selected}
+    </select>
+  </label>
+
+  <label>
+    {'User'|@translate}
+    <select name="user">
+      <option value="-1">------------</option>
+      {html_options options=$user_options selected=$user_options_selected}
+    </select>
+  </label>
+
+  <label>
+    {'Image id'|@translate}
+    <input name="image_id" value="{$IMAGE_ID}" type="text" size="5">
+  </label>
+
+  <label>
+    {'File name'|@translate}
+    <input name="filename" value="{$FILENAME}" type="text">
+  </label>
+
+  <label>
+    {'Thumbnails'|@translate}
+    <select name="display_thumbnail">
+      {html_options values=$display_thumbnail_values output=$display_thumbnail_values|translate selected=$display_thumbnail_selected}
+    </select>
+  </label>
+
+  <input class="submit" type="submit" name="submit" value="{'Submit'|@translate}" />
+</fieldset>
+</form>
+
+{if isset($search_summary)}
+<fieldset>
+  <legend>{'Summary'|@translate}</legend>
+
+  <ul>
+    <li>{$search_summary.NB_LINES}, {$search_summary.FILESIZE}</li>
+    <li>
+      {$search_summary.USERS}
+      <ul>
+        <li>{$search_summary.MEMBERS}</li>
+        <li>{$search_summary.GUESTS}</li>
+      </ul>
+    </li>
+  </ul>
+</fieldset>
+{/if}
+
+
+{if !empty($NAV_BAR)}
+<div class="navigationBar">
+  {$NAV_BAR}
+</div>
+{/if}
+
+
+<table class="table2" id="detailedStats">
+<tr class="throw">
+  <th>{'Date'|@translate}</th>
+  <th>{'time'|@translate}</th>
+  <th>{'user'|@translate}</th>
+  <th>{'IP'|@translate}</th>
+  <th>{'image'|@translate}</th>
+  <th>{'Element type'|@translate}</th>
+  <th>{'section'|@translate}</th>
+  <th>{'category'|@translate}</th>
+  <th>{'tags'|@translate}</th>
+</tr>
+{if !empty($search_results) }
+{foreach from=$search_results item=detail name=res_loop}
+<tr class="{if $smarty.foreach.res_loop.index is odd}row1{else}row2{/if}">
+  <td class="hour">{$detail.DATE}</td>
+  <td class="hour">{$detail.TIME}</td>
+  <td>{$detail.USER}</td>
+  <td>{$detail.IP}</td>
+  <td>{$detail.IMAGE}</td>
+  <td>{$detail.TYPE}</td>
+  <td>{$detail.SECTION}</td>
+  <td>{$detail.CATEGORY}</td>
+  <td>{$detail.TAGS}</td>
+</tr>
+{/foreach}
+{/if}
+</table>
+
+
+{if !empty($NAV_BAR)}
+<div class="navigationBar">
+  {$NAV_BAR}
+</div>
+{/if}
Index: /tags/2.0.2/admin/template/goto/icon/index.php
===================================================================
--- /tags/2.0.2/admin/template/goto/icon/index.php	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/icon/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/admin/template/goto/include/autosize.inc.tpl
===================================================================
--- /tags/2.0.2/admin/template/goto/include/autosize.inc.tpl	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/include/autosize.inc.tpl	(revision 3278)
@@ -0,0 +1,14 @@
+{* $Id$ *}
+{known_script id="jquery" src=$ROOT_URL|@cat:"template-common/lib/jquery.packed.js"}
+{known_script id="jquery.autogrow" src=$ROOT_URL|@cat:"template-common/lib/plugins/jquery.autogrow-textarea.js"}
+
+{* Auto size and auto grow textarea *}
+{literal}
+<script type="text/javascript">
+  jQuery().ready(function(){
+    jQuery('textarea').css('overflow-y', 'hidden');
+    // Auto size and auto grow for all text area
+    jQuery('textarea').autogrow();
+  });
+</script>
+{/literal}
Index: /tags/2.0.2/admin/template/goto/include/datepicker.inc.tpl
===================================================================
--- /tags/2.0.2/admin/template/goto/include/datepicker.inc.tpl	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/include/datepicker.inc.tpl	(revision 3278)
@@ -0,0 +1,25 @@
+{* $Id$ *}
+
+{known_script id="jquery" src=$ROOT_URL|@cat:"template-common/lib/jquery.packed.js"}
+{known_script id="jquery.ui" src=$ROOT_URL|@cat:"template-common/lib/ui/ui.core.packed.js"}
+{known_script id="jquery.ui.datepicker" src=$ROOT_URL|@cat:"template-common/lib/ui/ui.datepicker.packed.js"}
+{known_script id="datepicker.js" src=$ROOT_URL|@cat:"template-common/datepicker.js"}
+
+{assign var="datepicker_language" value="template-common/lib/ui/i18n/ui.datepicker-"|@cat:$lang_info.code|@cat:".js"}
+
+{if "PHPWG_ROOT_PATH"|@constant|@cat:$datepicker_language|@file_exists}
+{known_script id="jquery.ui.datepicker-$lang_info.code" src=$ROOT_URL|@cat:$datepicker_language}
+{/if}
+
+{html_head}
+<link rel="stylesheet" type="text/css" href="{$ROOT_URL}template-common/lib/ui/ui.datepicker.css">
+{/html_head}
+
+<script type="text/javascript">
+function pwg_initialization_datepicker(day, month, year, linked_date, checked_on_change, min_linked_date, max_linked_date)
+{ldelim}
+  return pwg_common_initialization_datepicker(
+    "{$ROOT_URL}admin/template/{$themeconf.template}/icon/datepicker.png",
+    day, month, year, linked_date, checked_on_change, min_linked_date, max_linked_date);
+}
+</script>
Index: /tags/2.0.2/admin/template/goto/include/dbselect.inc.tpl
===================================================================
--- /tags/2.0.2/admin/template/goto/include/dbselect.inc.tpl	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/include/dbselect.inc.tpl	(revision 3278)
@@ -0,0 +1,23 @@
+{* $Id$ *}
+{known_script id="jquery" src=$ROOT_URL|@cat:"template-common/lib/jquery.packed.js"}
+{known_script id="jquery.ui" src=$ROOT_URL|@cat:"template-common/lib/ui/ui.core.packed.js"}
+{known_script id="jquery.ui.resizable" src=$ROOT_URL|@cat:"template-common/lib/ui/ui.resizable.packed.js"}
+
+{* Resize possible *}
+{literal}
+<script type="text/javascript">
+  jQuery().ready(function(){
+    // Resize possible for double select list
+    jQuery(".doubleSelect select.categoryList").resizable({
+      handles: "w,e",
+      animate: true,
+      animateDuration: "slow",
+      animateEasing: "swing",
+      preventDefault: true,
+      preserveCursor: true,
+      autoHide: true,
+      ghost: true
+    });
+  });
+</script>
+{/literal}
Index: /tags/2.0.2/admin/template/goto/include/resize.inc.tpl
===================================================================
--- /tags/2.0.2/admin/template/goto/include/resize.inc.tpl	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/include/resize.inc.tpl	(revision 3278)
@@ -0,0 +1,23 @@
+{* $Id$ *}
+{known_script id="jquery" src=$ROOT_URL|@cat:"template-common/lib/jquery.packed.js"}
+{known_script id="jquery.ui" src=$ROOT_URL|@cat:"template-common/lib/ui/ui.core.packed.js"}
+{known_script id="jquery.ui.resizable" src=$ROOT_URL|@cat:"template-common/lib/ui/ui.resizable.packed.js"}
+
+{* Resize possible *}
+{literal}
+<script type="text/javascript">
+  jQuery().ready(function(){
+    // Resize possible for list
+    jQuery(".categoryList").resizable({
+      handles: "all",
+      animate: true,
+      animateDuration: "slow",
+      animateEasing: "swing",
+      preventDefault: true,
+      preserveCursor: true,
+      autoHide: true,
+      ghost: true
+    });
+  });
+</script>
+{/literal}
Index: /tags/2.0.2/admin/template/goto/index.php
===================================================================
--- /tags/2.0.2/admin/template/goto/index.php	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/admin/template/goto/install.tpl
===================================================================
--- /tags/2.0.2/admin/template/goto/install.tpl	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/install.tpl	(revision 3278)
@@ -0,0 +1,160 @@
+{* $Id$ *}
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+"http://www.w3.org/TR/html4/strict.dtd">
+<html lang="{$lang_info.code}" dir="{$lang_info.direction}">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset={$T_CONTENT_ENCODING}">
+<meta http-equiv="Content-script-type" content="text/javascript">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<link rel="shortcut icon" type="image/x-icon" href="{$ROOT_URL}template-common/favicon.ico">
+<link rel="stylesheet" type="text/css" href="{$ROOT_URL}admin/template/{$themeconf.template}/layout.css">
+<link rel="stylesheet" type="text/css" href="{$ROOT_URL}admin/template/{$themeconf.template}/default-colors.css">
+<link rel="stylesheet" type="text/css" href="{$ROOT_URL}admin/template/{$themeconf.template}/theme/{$themeconf.theme}/theme.css">
+{literal}
+<style type="text/css">
+.content {
+ width: 800px;
+ margin: auto;
+ text-align: center;
+}
+
+.table2 {
+  width: 100%;
+  margin-bottom: 1em !important;
+}
+
+TD {
+  text-align: left;
+  padding: 0.1em 0.5em;
+  height: 2.5em;
+}
+
+.sql_content, .infos a {
+  color: #ff3363;
+}
+</style>
+{/literal}
+<title>Piwigo {$RELEASE} - {'Installation'|@translate}</title>
+</head>
+
+<body>
+<div id="headbranch"></div> {* Dummy block for double background management *}
+<div id="the_page">
+<div id="theHeader"></div>
+<div id="content" class="content">
+
+<h2>Piwigo {$RELEASE} - {'Installation'|@translate}</h2>
+
+{if isset($errors)}
+<div class="errors">
+  <ul>
+    {foreach from=$errors item=error}
+    <li>{$error}</li>
+    {/foreach}
+  </ul>
+</div>
+{/if}
+
+{if isset($infos)}
+<div class="infos">
+  <ul>
+    {foreach from=$infos item=info}
+    <li>{$info}</li>
+    {/foreach}
+  </ul>
+</div>
+{/if}
+
+{if isset($install)}
+<form method="POST" action="{$F_ACTION}" name="install_form">
+
+  <table class="table2">
+    <tr class="throw">
+      <th colspan="2">{'Initial_config'|@translate}</th>
+    </tr>
+    <tr>
+      <td style="width: 30%">{'Default_lang'|@translate}</td>
+      <td>
+    <select name="language" onchange="document.location = 'install.php?language='+this.options[this.selectedIndex].value;">
+    {html_options options=$language_options selected=$language_selection}
+    </select>
+      </td>
+    </tr>
+  </table>
+  <table class="table2">
+    <tr class="throw">
+      <th colspan="3">{'step1_title'|@translate}</th>
+    </tr>
+    <tr>
+      <td style="width: 30%;">{'step1_host'|@translate}</td>
+      <td align=center><input type="text" name="dbhost" value="{$F_DB_HOST}" /></td>
+      <td>{'step1_host_info'|@translate}</td>
+    </tr>
+    <tr>
+      <td>{'step1_user'|@translate}</td>
+      <td align=center><input type="text" name="dbuser" value="{$F_DB_USER}" /></td>
+      <td>{'step1_user_info'|@translate}</td>
+    </tr>
+    <tr>
+      <td>{'step1_pass'|@translate}</td>
+      <td align=center><input type="password" name="dbpasswd" value="" /></td>
+      <td>{'step1_pass_info'|@translate}</td>
+    </tr>
+    <tr>
+      <td>{'step1_database'|@translate}</td>
+      <td align=center><input type="text" name="dbname" value="{$F_DB_NAME}" /></td>
+      <td>{'step1_database_info'|@translate}</td>
+    </tr>
+    <tr>
+      <td>{'step1_prefix'|@translate}</td>
+      <td align=center><input type="text" name="prefix" value="{$F_DB_PREFIX}" /></td>
+      <td>{'step1_prefix_info'|@translate}</td>
+    </tr>
+  </table>
+
+  <table class="table2">
+    <tr class="throw">
+      <th colspan="3">{'step2_title'|@translate}</th>
+    </tr>
+    <tr>
+      <td style="width: 30%;">{'install_webmaster'|@translate}</td>
+      <td align="center"><input type="text" name="admin_name" value="{$F_ADMIN}" /></td>
+      <td>{'install_webmaster_info'|@translate}</td>
+    </tr>
+    <tr>
+      <td>{'step2_pwd'|@translate}</td>
+      <td align="center"><input type="password" name="admin_pass1" value="" /></td>
+      <td>{'step2_pwd_info'|@translate}</td>
+    </tr>
+    <tr>
+      <td>{'step2_pwd_conf'|@translate}</td>
+      <td align="center"><input type="password" name="admin_pass2" value="" /></td>
+      <td>{'step2_pwd_conf_info'|@translate}</td>
+    </tr>
+    <tr>
+      <td>{'conf_mail_webmaster'|@translate}</td>
+      <td align="center"><input type="text" name="admin_mail" value="{$F_ADMIN_EMAIL}" /></td>
+      <td>{'conf_mail_webmaster_info'|@translate}</td>
+    </tr>
+  </table>
+
+  <table>
+    <tr>
+      <td style="text-align: center;">
+        <input class="submit" type="submit" name="install" value="{'Start_Install'|@translate}" />
+      </td>
+    </tr>
+  </table>
+</form>
+{else}
+<p>
+  <br />
+  <input type="button" name="index" value="{'home'|@translate}" onClick="document.location = 'index.php';"/>
+  <input type="button" name="identification" value="{'Identification'|@translate}" onClick="document.location = 'identification.php';"/>
+</p>
+{/if}
+</div> {* content *}
+<div style="text-align: center">{$L_INSTALL_HELP}</div>
+</div> {* the_page *}
+</body>
+</html>
Index: /tags/2.0.2/admin/template/goto/intro.tpl
===================================================================
--- /tags/2.0.2/admin/template/goto/intro.tpl	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/intro.tpl	(revision 3278)
@@ -0,0 +1,65 @@
+{* $Id$ *}
+<h2>{'title_default'|@translate}</h2>
+<dl style="padding-top: 30px;">
+  <dt>{'Piwigo version'|@translate}</dt>
+  <dd>
+    <ul>
+      <li><a href="{$PHPWG_URL}"  onclick="window.open(this.href, ''); 
+          return false;">Piwigo</a> {$PWG_VERSION}</li>
+      <li><a href="{$U_CHECK_UPGRADE}">{'Check for upgrade'|@translate}</a></li>
+    </ul>
+  </dd>
+
+  <dt>{'Environment'|@translate}</dt>
+  <dd>
+    <ul>
+      <li>{'Operating system'|@translate}: {$OS}</li>
+      <li>PHP: {$PHP_VERSION} (<a href="{$U_PHPINFO}" onclick="window.open(this.href, ''); 
+          return false;">{'Show info'|@translate}</a>)  [{$PHP_DATATIME}]</li>
+      <li>MySQL: {$MYSQL_VERSION} [{$DB_DATATIME}]</li>
+    </ul>
+  </dd>
+
+  <dt>{'Database'|@translate}</dt>
+  <dd>
+    <ul>
+      <li>
+        {$DB_ELEMENTS}
+        {if isset($waiting)}
+        (<a href="{$waiting.URL}">{$waiting.INFO}</a>)
+        {/if}
+
+        {if isset($first_added)}
+        ({$first_added.DB_DATE})
+        {/if}
+      </li>
+      <li>{$DB_CATEGORIES} ({$DB_IMAGE_CATEGORY})</li>
+      <li>{$DB_TAGS} ({$DB_IMAGE_TAG})</li>
+      <li>{$DB_USERS}</li>
+      <li>{$DB_GROUPS}</li>
+      <li>
+        {$DB_COMMENTS}
+        {if isset($unvalidated)}
+        (<a href="{$unvalidated.URL}">{$unvalidated.INFO}</a>)
+        {/if}
+      </li>
+    </ul>
+  </dd>
+</dl>
+
+
+<form name="QuickSynchro" action="{$U_CAT_UPDATE}" method="post" id="QuickSynchro" style="display: block; text-align:right;">
+<div>
+<input type="hidden" name="sync" value="files" checked="checked" />
+<input type="hidden" name="display_info" value="1" checked="checked" />
+<input type="hidden" name="add_to_caddie" value="1" checked="checked" />
+<input type="hidden" name="privacy_level" value="0" checked="checked" />
+<input type="hidden" name="sync_meta" checked="checked"/>
+<input type="hidden" name="simulate" value="0" />
+<input type="hidden" name="subcats-included" value="1" checked="checked"/>
+</div>
+<div class="bigbutton">
+<span class="bigtext">{'Quick Local Synchronization'|@translate}</span>
+<input type="submit" value="" name="submit">
+</div>
+</form>
Index: /tags/2.0.2/admin/template/goto/layout.css
===================================================================
--- /tags/2.0.2/admin/template/goto/layout.css	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/layout.css	(revision 3278)
@@ -0,0 +1,12 @@
+
+/* template css */
+/*@import "menubar.css";*/
+@import "content.css";
+@import "thumbnails.css";
+@import "default-layout.css";
+/* Override properties with import local file */
+@import "local-layout.css";
+/* common css */
+@import "../../../template-common/default-layout.css";
+/* Override properties with import local file */
+@import "../../../template-common/local-layout.css";
Index: /tags/2.0.2/admin/template/goto/local-layout.css
===================================================================
--- /tags/2.0.2/admin/template/goto/local-layout.css	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/local-layout.css	(revision 3278)
@@ -0,0 +1,1 @@
+/* You can modify this file */
Index: /tags/2.0.2/admin/template/goto/maintenance.tpl
===================================================================
--- /tags/2.0.2/admin/template/goto/maintenance.tpl	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/maintenance.tpl	(revision 3278)
@@ -0,0 +1,22 @@
+{* $Id$ *}
+<div class="titrePage">
+  <h2>{'Maintenance'|@translate}</h2>
+</div>
+
+<ul>
+  <li><a href="{$U_MAINT_CATEGORIES}" {$TAG_INPUT_ENABLED}>{'update categories informations'|@translate}</a></li>
+  <li><a href="{$U_MAINT_IMAGES}" {$TAG_INPUT_ENABLED}>{'update images informations'|@translate}</a></li>
+  <li><a href="{$U_MAINT_DATABASE}" {$TAG_INPUT_ENABLED}>{'repair and optimize database'|@translate}</a></li>
+</ul>
+
+<ul>
+  <li><a href="{$U_MAINT_HISTORY_DETAIL}" onclick="return confirm('{'Are you sure?'|@translate}');" {$TAG_INPUT_ENABLED}>{'purge history detail'|@translate}</a></li>
+  <li><a href="{$U_MAINT_HISTORY_SUMMARY}" onclick="return confirm('{'Are you sure?'|@translate}');" {$TAG_INPUT_ENABLED}>{'purge history summary'|@translate}</a></li>
+  <li><a href="{$U_MAINT_SESSIONS}" {$TAG_INPUT_ENABLED}>{'purge sessions'|@translate}</a></li>
+  <li><a href="{$U_MAINT_FEEDS}" {$TAG_INPUT_ENABLED}>{'purge never used notification feeds'|@translate}</a></li>
+  <li><a href="{$U_MAINT_COMPILED_TEMPLATES}" {$TAG_INPUT_ENABLED}>{'Purge compiled templates'|@translate}</a></li>
+</ul>
+
+<ul>
+  <li><a href="{$U_MAINT_C13Y}" {$TAG_INPUT_ENABLED}>{'c13y_maintenance'|@translate}</a></li>
+</ul>
Index: /tags/2.0.2/admin/template/goto/menubar.css
===================================================================
--- /tags/2.0.2/admin/template/goto/menubar.css	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/menubar.css	(revision 3278)
@@ -0,0 +1,1 @@
+/* menubar.css is no longer used in admin because menubar is always active in admin so it is layout */
Index: /tags/2.0.2/admin/template/goto/menubar.tpl
===================================================================
--- /tags/2.0.2/admin/template/goto/menubar.tpl	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/menubar.tpl	(revision 3278)
@@ -0,0 +1,30 @@
+{* $Id$ *}
+
+<div class="titrePage">
+	<h2>Menubar</h2>
+</div>
+
+<form method="post" class="properties">
+<table class="table2">
+	<tr class="throw">
+		<td>Id</td>
+		<td>{'Author'|@translate}</td>
+		<td>{'Name'|@translate}</td>
+		<td>{'Position'|@translate}</td>
+		<td>Hide</td>
+	</tr>
+	{foreach from=$blocks item=block name="block_loop"}
+	<tr class="{if $smarty.foreach.block_loop.index is odd}row1{else}row2{/if}">
+		<td>{$block.reg->get_id()}</td>
+		<td>{$block.reg->get_owner()}</td>
+		<td>{$block.reg->get_name()|@translate}</td>
+		<td><input type="input" name="pos_{$block.reg->get_id()}" value={math equation="abs(pos)" pos=$block.pos} size="2"></td>
+		<td><input type="checkbox" name="hide_{$block.reg->get_id()}" {if $block.pos<0}checked="checked"{/if} ></td>
+	</tr>
+	{/foreach}
+</table>
+<p>
+	<input type="submit" name="submit" value="{'Submit'|@translate}" {$TAG_INPUT_ENABLED}/>
+	<input type="submit" name="reset" value="{'Reset'|@translate}" {$TAG_INPUT_ENABLED}/>
+</p>
+</form>
Index: /tags/2.0.2/admin/template/goto/notification_by_mail.tpl
===================================================================
--- /tags/2.0.2/admin/template/goto/notification_by_mail.tpl	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/notification_by_mail.tpl	(revision 3278)
@@ -0,0 +1,122 @@
+{* $Id$ *}
+
+{include file='include/autosize.inc.tpl'}
+
+<div class="titrePage">
+  <h2>{'nbm_send_mail_to_users'|@translate} {$TABSHEET_TITLE}</h2>
+</div>
+
+<form method="post" name="notification_by_mail" id="notification_by_mail" action="{$F_ACTION}">
+  {if isset($REPOST_SUBMIT_NAME)}
+  <fieldset>
+    <div class="infos">
+      <input class="submit" type="submit" value="{'nbm_repost_submit'|@translate}" name="{$REPOST_SUBMIT_NAME}" {$TAG_INPUT_ENABLED}/>
+    </div>
+  </fieldset>
+  {/if}
+
+  {if isset($param)}
+  <fieldset>
+    <legend>{'nbm_title_param'|@translate}</legend>
+    <table>
+      <tr>
+        <td><label>{'nbm_send_html_mail'|@translate}</label></td>
+        <td>
+          <label><input type="radio" name="nbm_send_html_mail" value="true"  {if $param.SEND_HTML_MAIL}checked="checked"{/if}/>{'Yes'|@translate}</label>
+          <label><input type="radio" name="nbm_send_html_mail" value="false" {if not $param.SEND_HTML_MAIL}checked="checked"{/if}/>{'No'|@translate}</label>
+        </td>
+      </tr>
+      <tr>
+        <td>
+          <label for="send_mail_as">{'nbm_send_mail_as'|@translate}</label>
+          <br/><i><small>{'nbm_info_send_mail_as'|@translate}</small></i>
+        </td>
+        <td><input type="text" maxlength="35" size="35" name="nbm_send_mail_as" id="send_mail_as" value="{$param.SEND_MAIL_AS}"/></td>
+      </tr>
+      <tr>
+        <td><label>{'nbm_send_detailed_content'|@translate}</label></td>
+        <td>
+          <label><input type="radio" name="nbm_send_detailed_content" value="true"  {if $param.SEND_DETAILED_CONTENT}checked="checked"{/if}/>{'Yes'|@translate}</label>
+          <label><input type="radio" name="nbm_send_detailed_content" value="false" {if not $param.SEND_DETAILED_CONTENT}checked="checked"{/if}/>{'No'|@translate}</label>
+        </td>
+      </tr>
+     <tr>
+        <td><label for="complementary_mail_content">{'nbm_complementary_mail_content'|@translate}</label></td>
+        <td><textarea cols="50" rows="5" name="nbm_complementary_mail_content" id="complementary_mail_content">{$param.COMPLEMENTARY_MAIL_CONTENT}</textarea></td>
+      </tr>
+      <tr>
+        <td>
+          <label>{'nbm_send_recent_post_dates'|@translate}</label>
+          <br/><i><small>{'nbm_info_send_recent_post_dates'|@translate}</small></i>
+        </td>
+        <td>
+          <label><input type="radio" name="nbm_send_recent_post_dates" value="true" {if $param.SEND_RECENT_POST_DATES}checked="checked"{/if}/>{'Yes'|@translate}</label>
+          <label><input type="radio" name="nbm_send_recent_post_dates" value="false" {if not $param.SEND_RECENT_POST_DATES}checked="checked"{/if}/>{'No'|@translate}</label>
+        </td>
+      </tr>
+    </table>
+  </fieldset>
+
+  <p>
+    <input class="submit" type="submit" value="{'Submit'|@translate}" name="param_submit" {$TAG_INPUT_ENABLED}/>
+    <input class="submit" type="reset" value="{'Reset'|@translate}" name="param_reset"/>
+  </p>
+  {/if}{* isset $param*}
+
+  {if isset($subscribe)}
+  <fieldset>
+    <legend>{'nbm_title_subscribe'|@translate}</legend>
+    <p><i>{'nbm_warning_subscribe_unsubscribe'|@translate}</i></p>
+    {$DOUBLE_SELECT}
+  </fieldset>
+  {/if}{* isset $subscribe*}
+
+  {if isset($send)}
+    {if empty($send.users)}
+    <p>{'nbm_no_user_available_to_send_L1'|@translate}</p>
+    <p>
+    {'nbm_no_user_available_to_send_L2'|@translate}<br>
+    {'nbm_no_user_available_to_send_L3'|@translate}
+    </p>
+    {else}
+    <fieldset>
+      <legend>{'nbm_title_send'|@translate}</legend>
+      <table class="table2">
+        <tr class="throw">
+          <th>{'nbm_col_user'|@translate}</th>
+          <th>{'nbm_col_mail'|@translate}</th>
+          <th>{'nbm_col_last_send'|@translate}</th>
+          <th>{'nbm_col_check_user_send_mail'|@translate}</th>
+        </tr>
+        {foreach from=$send.users item=u name=user_loop}
+        <tr class="{if $smarty.foreach.user_loop.index is odd}row1{else}row2{/if}">
+          <td><label for="send_selection-{$u.ID}">{$u.USERNAME}</label></td>
+          <td><label for="send_selection-{$u.ID}">{$u.EMAIL}</label></td>
+          <td><label for="send_selection-{$u.ID}">{$u.LAST_SEND}</label></td>
+          <td><input type="checkbox" name="send_selection[]" value="{$u.ID}" {$u.CHECKED} id="send_selection-{$u.ID}"/></td>
+        </tr>
+        {/foreach}
+      </table>
+      <p>
+          <a href="#" onclick="SelectAll(document.getElementById('notification_by_mail')); return false;">{'Check all'|@translate}</a>
+        / <a href="#" onclick="DeselectAll(document.getElementById('notification_by_mail')); return false;">{'Uncheck all'|@translate}</a>
+      </p>
+    </fieldset>
+
+    <fieldset>
+      <legend>{'nbm_send_options'|@translate}</legend>
+      <table>
+       <tr>
+          <td><label for="send_customize_mail_content">{'nbm_send_complementary_mail_content'|@translate}</label></td>
+          <td><textarea cols="50" rows="5" name="send_customize_mail_content" id="send_customize_mail_content">{$send.CUSTOMIZE_MAIL_CONTENT}</textarea></td>
+        </tr>
+      </table>
+    </fieldset>
+
+    <p>
+      <input class="submit" type="submit" value="{'nbm_send_submit'|@translate}" name="send_submit" {$TAG_INPUT_ENABLED}/>
+    </p>
+    {/if}
+  {/if}{* isset $send*}
+
+</form>
Index: /tags/2.0.2/admin/template/goto/permalinks.tpl
===================================================================
--- /tags/2.0.2/admin/template/goto/permalinks.tpl	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/permalinks.tpl	(revision 3278)
@@ -0,0 +1,67 @@
+{* $Id$ *}
+<div class="titrePage">
+  <h2>{'Permalinks'|@translate}</h2>
+</div>
+
+<form method="post" action="">
+<fieldset><legend>{'Add/delete a permalink'|@translate}</legend>
+  <label>{'Category'|@translate}:
+    <select name="cat_id">
+      <option value="0">------</option>
+      {html_options options=$categories selected=$categories_selected}
+    </select>
+  </label>
+
+  <label>{'Permalink'|@translate}:
+    <input name="permalink" />
+  </label>
+
+  <label>{'Save to permalink history'|@translate}:
+    <input type="checkbox" name="save" checked="checked" />
+  </label>
+
+  <p>
+    <input type="submit" class="submit" name="set_permalink" value="{'Submit'|@translate}" {$TAG_INPUT_ENABLED}/>
+  </p>
+  </fieldset>
+</form>
+
+<h3>{'Permalinks'|@translate}</h3>
+<table class="table2">
+	<tr class="throw">
+		<td>Id {$SORT_ID}</td>
+		<td>{'Category'|@translate} {$SORT_NAME}</td>
+		<td>{'Permalink'|@translate} {$SORT_PERMALINK}</td>
+	</tr>
+{foreach from=$permalinks item=permalink name="permalink_loop"}
+	<tr class="{if $smarty.foreach.permalink_loop.index is odd}row1{else}row2{/if}" style="line-height:1.5em;">
+		<td style="text-align:center;">{$permalink.id}</td>
+		<td>{$permalink.name}</td>
+		<td>{$permalink.permalink}</td>
+	</tr>
+{/foreach}
+</table>
+
+<h3>{'Permalink history'|@translate} <a name="old_permalinks"></a></h3>
+<table class="table2">
+	<tr class="throw">
+		<td>Id {$SORT_OLD_CAT_ID}</td>
+		<td>{'Category'|@translate}</td>
+		<td>{'Permalink'|@translate} {$SORT_OLD_PERMALINK}</td>
+		<td>Deleted on {$SORT_OLD_DATE_DELETED}</td>
+		<td>Last hit {$SORT_OLD_LAST_HIT}</td>
+		<td style="width:20px;">Hit {$SORT_OLD_HIT}</td>
+		<td style="width:5px;"></td>
+	</tr>
+{foreach from=$deleted_permalinks item=permalink}
+	<tr style="line-height:1.5em;">
+		<td style="text-align:center;">{$permalink.cat_id}</td>
+		<td>{$permalink.name}</td>
+		<td>{$permalink.permalink}</td>
+		<td>{$permalink.date_deleted}</td>
+		<td>{$permalink.last_hit}</td>
+		<td>{$permalink.hit}</td>
+		<td><a href="{$permalink.U_DELETE}" {$TAG_INPUT_ENABLED}><img src="{$ROOT_URL}{$themeconf.admin_icon_dir}/delete.png" alt="[{'delete'|@translate}]" class="button"></a></td>
+	</tr>
+{/foreach}
+</table>
Index: /tags/2.0.2/admin/template/goto/picture.css
===================================================================
--- /tags/2.0.2/admin/template/goto/picture.css	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/picture.css	(revision 3278)
@@ -0,0 +1,123 @@
+/* $Id$ */
+
+/* Maybe some cleanup has to be done there  TODO */
+#imageHeaderBar {
+  padding-top: 2px;
+  padding-bottom: 2px;
+  margin-top: 4px;
+  overflow: hidden;
+  width: 100%;
+}
+
+#imageHeaderBar .browsePath {
+  float: left;
+  margin-left: 10px;
+}
+
+#imageHeaderBar .imageNumber {
+  float: right;
+  margin-right: 10px;
+}
+
+#imageHeaderBar H2 {
+  text-align: center;
+  padding: 0;
+  clear: both;
+}
+
+#imageToolBar {
+  text-align: center;
+  position: relative;
+  clear: both;
+  margin-bottom: 4px;
+  padding: 0;
+}
+
+#imageToolBar {
+    height: 28px;
+}
+#imageToolBar A, #imageToolBar IMG {
+    display: block;
+    border: none;
+    margin: 0; padding: 0;
+}
+#imageToolBar A { width: 48px; }
+#imageToolBar IMG { margin: 2px auto; }
+#imageToolBar .randomButtons A { float: left; }
+#imageToolBar .navButtons    A { float: right; }
+
+#theImage {
+    clear: left;
+}
+
+#theImage>IMG {
+    display: block;
+    margin: 0 auto;
+}
+
+#theImage IMG {
+  border-width: 3px;
+  border-style: solid;
+}
+
+.navThumb {
+    margin-top: 2px;
+}
+#thumbPrev {
+    float: left;
+}
+
+#thumbNext {
+    float: right;
+}
+
+#linkPrev {
+    margin-right: 10px;
+    margin-left: 5px;
+}
+
+#linkNext {
+    margin-right: 5px;
+    margin-left: 10px;
+}
+
+TABLE.infoTable .value {
+    text-align: left;
+}
+
+TABLE.infoTable .label {
+    font-weight: bold;
+    text-align: right;
+    padding-right: 0.5em;
+}
+
+TABLE.infoTable TD.value UL {
+  margin: 0;
+  padding: 0 0 0 1.5em;
+  list-style-type: square;
+}
+
+#comments {
+  text-align: left;
+}
+
+#comments .comment {
+  margin: 1em 0;
+}
+
+#comments P {
+  margin: 0 0.5em 0 1em;
+}
+
+#comments .author {
+  font-weight: bold;
+}
+
+#thePicturePage #comments BLOCKQUOTE {
+  margin: 0.5em 1em 1em 4em;
+}
+
+#comments P.userCommentDelete {
+  float: right;
+  margin: 0 0.5em 0 0;
+}
Index: /tags/2.0.2/admin/template/goto/picture_modify.tpl
===================================================================
--- /tags/2.0.2/admin/template/goto/picture_modify.tpl	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/picture_modify.tpl	(revision 3278)
@@ -0,0 +1,204 @@
+{* $Id$ *}
+
+{include file='include/autosize.inc.tpl'}
+{include file='include/dbselect.inc.tpl'}
+{include file='include/datepicker.inc.tpl'}
+
+{literal}
+<script type="text/javascript">
+  pwg_initialization_datepicker("#date_creation_day", "#date_creation_month", "#date_creation_year", "#date_creation_linked_date", "#date_creation_action_set");
+</script>
+{/literal}
+
+<h2>{'title_picmod'|@translate}</h2>
+
+<img src="{$TN_SRC}" alt="{'thumbnail'|@translate}" class="thumbnail" />
+
+<ul class="categoryActions">
+  {if isset($U_JUMPTO) }
+  <li><a href="{$U_JUMPTO}" title="{'jump to image'|@translate}"><img src="{$themeconf.admin_icon_dir}/category_jump-to.png" class="button" alt="{'jump to image'|@translate}" /></a></li>
+  {/if}
+  {if !url_is_remote($path)}
+  <li><a href="{$U_SYNC}" title="{'synchronize metadata'|@translate}" {$TAG_INPUT_ENABLED}><img src="{$themeconf.admin_icon_dir}/sync_metadata.png" class="button" alt="{'synchronize'|@translate}" /></a></li>
+  {/if}
+</ul>
+
+<form action="{$F_ACTION}" method="post" id="properties">
+
+  <fieldset>
+    <legend>{'Informations'|@translate}</legend>
+
+    <table>
+
+      <tr>
+        <td><strong>{'Path'|@translate}</strong></td>
+        <td>{$PATH}</td>
+      </tr>
+
+      <tr>
+        <td><strong>{'Post date'|@translate}</strong></td>
+        <td>{$REGISTRATION_DATE}</td>
+      </tr>
+
+      <tr>
+        <td><strong>{'Dimensions'|@translate}</strong></td>
+        <td>{$DIMENSIONS}</td>
+      </tr>
+
+      <tr>
+        <td><strong>{'Filesize'|@translate}</strong></td>
+        <td>{$FILESIZE}</td>
+      </tr>
+
+{if isset($HIGH_FILESIZE) }
+      <tr>
+        <td><strong>{'High filesize'|@translate}</strong></td>
+        <td>{$HIGH_FILESIZE}</td>
+      </tr>
+{/if}
+
+      <tr>
+        <td><strong>{'Storage category'|@translate}</strong></td>
+        <td>{$STORAGE_CATEGORY}</td>
+      </tr>
+
+      {if isset($related_categories) }
+      <tr>
+        <td><strong>{'Linked categories'|@translate}</strong></td>
+        <td>
+          <ul>
+            {foreach from=$related_categories item=name}
+            <li>{$name}</li>
+            {/foreach}
+          </ul>
+        </td>
+      </tr>
+      {/if}
+
+    </table>
+
+  </fieldset>
+
+  <fieldset>
+    <legend>{'Properties'|@translate}</legend>
+
+    <table>
+
+      <tr>
+        <td><strong>{'Name'|@translate}</strong></td>
+        <td><input type="text" class="large" name="name" value="{$NAME}" /></td>
+      </tr>
+
+      <tr>
+        <td><strong>{'Author'|@translate}</strong></td>
+        <td><input type="text" class="large" name="author" value="{$AUTHOR}" /></td>
+      </tr>
+
+      <tr>
+        <td><strong>{'Creation date'|@translate}</strong></td>
+        <td>
+          <label><input type="radio" name="date_creation_action" value="unset" /> {'unset'|@translate}</label>
+          <input type="radio" name="date_creation_action" value="set" id="date_creation_action_set" /> {'set to'|@translate}
+          <select id="date_creation_day" name="date_creation_day">
+            <option value="0">--</option>
+            {section name=day start=1 loop=32}
+              <option value="{$smarty.section.day.index}" {if $smarty.section.day.index==$DATE_CREATION_DAY_VALUE}selected="selected"{/if}>{$smarty.section.day.index}</option>
+            {/section}
+          </select>
+          <select id="date_creation_month" name="date_creation_month">
+            {html_options options=$month_list selected=$DATE_CREATION_MONTH_VALUE}
+          </select>
+          <input id="date_creation_year"
+                 name="date_creation_year"
+                 type="text"
+                 size="4"
+                 maxlength="4"
+                 value="{$DATE_CREATION_YEAR_VALUE}" />
+          <input id="date_creation_linked_date" name="date_creation_linked_date" type="hidden" size="10" disabled="disabled"/>
+        </td>
+      </tr>
+
+      <tr>
+        <td><strong>{'Tags'|@translate}</strong></td>
+        <td>{$TAG_SELECTION}</td>
+      </tr>
+
+
+      <tr>
+        <td><strong>{'Description'|@translate}</strong></td>
+        <td><textarea name="description" id="description" class="description">{$DESCRIPTION}</textarea></td>
+      </tr>
+
+  <tr>
+    <td><strong>{'Minimum privacy level'|@translate}</strong></td>
+    <td>
+      <select name="level" size="1">
+        {html_options options=$level_options selected=$level_options_selected}
+      </select>
+    </td>
+  </tr>
+
+    </table>
+
+    <p style="text-align:center;">
+      <input class="submit" type="submit" value="{'Submit'|@translate}" name="submit" {$TAG_INPUT_ENABLED}/>
+      <input class="submit" type="reset" value="{'Reset'|@translate}" name="reset" />
+    </p>
+
+  </fieldset>
+
+</form>
+
+<form id="associations" method="post" action="{$F_ACTION}#associations">
+  <fieldset>
+    <legend>{'Association to categories'|@translate}</legend>
+
+    <table class="doubleSelect">
+      <tr>
+        <td>
+          <h3>{'Associated'|@translate}</h3>
+          <select class="categoryList" name="cat_associated[]" multiple="multiple" size="30">
+            {html_options options=$associated_options}
+          </select>
+          <p><input class="submit" type="submit" value="&raquo;" name="dissociate" style="font-size:15px;" {$TAG_INPUT_ENABLED}/></p>
+        </td>
+
+        <td>
+          <h3>{'Dissociated'|@translate}</h3>
+          <select class="categoryList" name="cat_dissociated[]" multiple="multiple" size="30">
+            {html_options options=$dissociated_options}
+          </select>
+          <p><input class="submit" type="submit" value="&laquo;" name="associate" style="font-size:15px;" {$TAG_INPUT_ENABLED}/></p>
+        </td>
+      </tr>
+    </table>
+
+  </fieldset>
+</form>
+
+<form id="representation" method="post" action="{$F_ACTION}#representation">
+  <fieldset>
+    <legend>{'Representation of categories'|@translate}</legend>
+
+    <table class="doubleSelect">
+      <tr>
+        <td>
+          <h3>{'Represents'|@translate}</h3>
+          <select class="categoryList" name="cat_elected[]" multiple="multiple" size="30">
+            {html_options options=$elected_options}
+          </select>
+          <p><input class="submit" type="submit" value="&raquo;" name="dismiss" style="font-size:15px;" {$TAG_INPUT_ENABLED}/></p>
+        </td>
+
+        <td>
+          <h3>{'Does not represent'|@translate}</h3>
+          <select class="categoryList" name="cat_dismissed[]" multiple="multiple" size="30">
+            {html_options options=$dismissed_options}
+          </select>
+          <p><input class="submit" type="submit" value="&laquo;" name="elect" style="font-size:15px;" {$TAG_INPUT_ENABLED}/></p>
+        </td>
+      </tr>
+    </table>
+
+  </fieldset>
+</form>
Index: /tags/2.0.2/admin/template/goto/plugins_list.tpl
===================================================================
--- /tags/2.0.2/admin/template/goto/plugins_list.tpl	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/plugins_list.tpl	(revision 3278)
@@ -0,0 +1,88 @@
+<div class="titrePage">
+<span class="sort">
+{'Sort order'|@translate} : 
+  <select onchange="document.location = this.options[this.selectedIndex].value;" style="width:200px">
+        {html_options options=$order_options selected=$order_selected}
+  </select>
+</span>
+  <h2>{'Plugins'|@translate}</h2>
+</div>
+
+
+{if isset($plugins)}
+<table class="table2 plugins">
+<thead>
+  <tr class="throw">
+    <td>{'Name'|@translate}</td>
+    <td>{'Actions'|@translate}</td>
+    <td>{'Version'|@translate}</td>
+    <td>{'Description'|@translate}</td>
+  </tr>
+</thead>
+
+{foreach from=$plugins item=plugin name=plugins_loop}
+  <tr class="{if $smarty.foreach.plugins_loop.index is odd}row1{else}row2{/if}">
+  <td class="pluginState{if $plugin.STATE != 'uninstalled'} {$plugin.STATE}{/if}">
+    {$plugin.NAME}
+  </td>
+  <td>
+    <ul class="pluginsActions">
+    {if $plugin.STATE == 'active'}
+      <li>
+        <a href="{$plugin.U_ACTION}&amp;action=deactivate">
+          <img src="{$themeconf.admin_icon_dir}/plug_deactivate.png" alt="{'Deactivate'|@translate}" title="{'Deactivate'|@translate}" />
+        </a>
+      </li>
+      <li>
+          <img src="{$themeconf.admin_icon_dir}/plug_uninstall_grey.png" alt="{'Uninstall'|@translate}" title="{'Uninstall'|@translate}" />
+      </li>
+    {/if}
+    {if $plugin.STATE == 'inactive'}
+      <li>
+        <a href="{$plugin.U_ACTION}&amp;action=activate">
+          <img src="{$themeconf.admin_icon_dir}/plug_activate.png" alt="{'Activate'|@translate}" title="{'Activate'|@translate}" />
+        </a>
+      </li>
+      <li>
+        <a href="{$plugin.U_ACTION}&amp;action=uninstall" onclick="return confirm('{'Are you sure?'|@translate|@escape:'javascript'}');">
+          <img src="{$themeconf.admin_icon_dir}/plug_uninstall.png" alt="{'Uninstall'|@translate}" title="{'Uninstall'|@translate}" />
+        </a>
+      </li>
+    {/if}
+    {if $plugin.STATE == 'missing'}
+      <li>
+          <img src="{$themeconf.admin_icon_dir}/plug_deactivate_grey.png" alt="{'Deactivate'|@translate}" title="{'Deactivate'|@translate}" />
+      </li>
+      <li>
+        <a href="{$plugin.U_ACTION}&amp;action=uninstall" onclick="return confirm('{'Are you sure?'|@translate|@escape:'javascript'}');">
+          <img src="{$themeconf.admin_icon_dir}/plug_uninstall.png" alt="{'Uninstall'|@translate}" title="{'Uninstall'|@translate}" />
+        </a>
+      </li>
+    {/if}
+    {if $plugin.STATE == 'uninstalled'}
+      <li>
+          <img src="{$themeconf.admin_icon_dir}/plug_activate_grey.png" alt="{'Activate'|@translate}" title="{'Activate'|@translate}" />
+      </li>
+      <li>
+        <a href="{$plugin.U_ACTION}&amp;action=install" onclick="return confirm('{'Are you sure?'|@translate|@escape:'javascript'}');">
+          <img src="{$themeconf.admin_icon_dir}/plug_install.png" alt="{'Install'|@translate}" title="{'Install'|@translate}"/>
+        </a>
+      </li>
+      <li>
+        <a href="{$plugin.U_ACTION}&amp;action=delete" onclick="return confirm('{'plugins_confirm_delete'|@translate|@escape:'javascript'}');">
+          <img src="{$themeconf.admin_icon_dir}/plug_delete.png" alt="{'plugins_delete'|@translate}" title="{'plugins_delete'|@translate}">
+        </a>
+      </li>
+    {else}
+      <li>
+        <img src="{$themeconf.admin_icon_dir}/plug_delete_grey.png" alt="{'plugins_delete'|@translate}" title="{'plugins_delete'|@translate}" />
+      </li>
+    {/if}
+    </ul>
+  </td>
+  <td style="text-align:center;">{$plugin.VERSION}</td>
+  <td>{$plugin.DESCRIPTION}</td>
+  </tr>
+{/foreach}
+</table>
+{/if}
Index: /tags/2.0.2/admin/template/goto/plugins_new.tpl
===================================================================
--- /tags/2.0.2/admin/template/goto/plugins_new.tpl	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/plugins_new.tpl	(revision 3278)
@@ -0,0 +1,49 @@
+{* $Id$ *}
+{known_script id="jquery" src=$ROOT_URL|@cat:"template-common/lib/jquery.packed.js"}
+{known_script id="jquery.dimensions" src=$ROOT_URL|@cat:"template-common/lib/plugins/jquery.dimensions.packed.js"}
+{known_script id="jquery.cluetip" src=$ROOT_URL|@cat:"template-common/lib/plugins/jquery.cluetip.packed.js"}
+
+<script type="text/javascript">
+jQuery().ready(function(){ldelim}
+  jQuery('.cluetip').cluetip({ldelim}
+    width: 300,
+    splitTitle: '|'
+  });
+});
+</script>
+
+<div class="titrePage">
+<span class="sort">
+{'Sort order'|@translate} : 
+  <select onchange="document.location = this.options[this.selectedIndex].value;">
+        {html_options options=$order_options selected=$order_selected}
+  </select>
+</span>
+  <h2>{'Plugins'|@translate}</h2>
+</div>
+
+{if isset($plugins)}
+<br>
+<table class="table2 plugins">
+<thead>
+  <tr class="throw">
+    <td>{'Name'|@translate}</td>
+    <td>{'Version'|@translate}</td>
+    <td>{'Date'|@translate}</td>
+    <td>{'Author'|@translate}</td>
+    <td>{'Actions'|@translate}</td>
+  </tr>
+</thead>
+{foreach from=$plugins item=plugin name=plugins_loop}
+  <tr class="{if $smarty.foreach.plugins_loop.index is odd}row1{else}row2{/if}">
+    <td><a href="{$plugin.EXT_URL}" onclick="window.open(this.href); return false;" class="cluetip" title="{$plugin.EXT_NAME}|{$plugin.EXT_DESC|htmlspecialchars|nl2br}">{$plugin.EXT_NAME}</a></td>
+    <td style="text-align:center;"><a href="{$plugin.EXT_URL}" onclick="window.open(this.href); return false;" class="cluetip" title="{$plugin.EXT_NAME}|{$plugin.VER_DESC|htmlspecialchars|nl2br}">{$plugin.VERSION}</a></td>
+    <td>{$plugin.DATE}</td>
+    <td>{$plugin.AUTHOR}</td>
+    <td style="text-align:center;"><a href="{$plugin.URL_INSTALL}" onclick="return confirm('{'plugins_confirm_install'|@translate|@escape:javascript}');">{'plugins_auto_install'|@translate}</a>
+      / <a href="{$plugin.URL_DOWNLOAD}">{'plugins_download'|@translate}</a>
+    </td>
+  </tr>
+{/foreach}
+</table>
+{/if}
Index: /tags/2.0.2/admin/template/goto/plugins_update.tpl
===================================================================
--- /tags/2.0.2/admin/template/goto/plugins_update.tpl	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/plugins_update.tpl	(revision 3278)
@@ -0,0 +1,81 @@
+{* $Id$ *}
+{known_script id="jquery" src=$ROOT_URL|@cat:"template-common/lib/jquery.packed.js"}
+{known_script id="jquery.dimensions" src=$ROOT_URL|@cat:"template-common/lib/plugins/jquery.dimensions.packed.js"}
+{known_script id="jquery.cluetip" src=$ROOT_URL|@cat:"template-common/lib/plugins/jquery.cluetip.packed.js"}
+
+<script type="text/javascript">
+jQuery().ready(function(){ldelim}
+  jQuery('.cluetip').cluetip({ldelim}
+    width: 300,
+    splitTitle: '|'
+  });
+});
+</script>
+
+<div class="titrePage">
+  <h2>{'Plugins'|@translate}</h2>
+</div>
+
+{if isset($plugins_not_uptodate)}
+<br>
+<b>{'plugins_need_update'|@translate}</b>
+<table class="table2 plugins">
+<thead>
+  <tr class="throw">
+    <td>{'Name'|@translate}</td>
+    <td>{'plugins_actual_version'|@translate}</td>
+    <td>{'plugins_new_version'|@translate}</td>
+    <td>{'Actions'|@translate}</td>
+  </tr>
+</thead>
+{foreach from=$plugins_not_uptodate item=plugin name=plugins_loop}
+  <tr class="{if $smarty.foreach.plugins_loop.index is odd}row1{else}row2{/if}">
+    <td><a href="{$plugin.EXT_URL}" onclick="window.open(this.href); return false;" class="cluetip" title="{$plugin.EXT_NAME}|{$plugin.EXT_DESC|htmlspecialchars|nl2br}">{$plugin.EXT_NAME}</a></td>
+    <td style="text-align:center;">{$plugin.VERSION}</td>
+    <td style="text-align:center;"><a href="{$plugin.EXT_URL}" onclick="window.open(this.href); return false;" class="cluetip" title="{$plugin.EXT_NAME}|{$plugin.NEW_VER_DESC|htmlspecialchars|nl2br}">{$plugin.NEW_VERSION}</a></td>
+    <td style="text-align:center;"><a href="{$plugin.URL_UPDATE}" onclick="return confirm('{'plugins_confirm_upgrade'|@translate|@escape:javascript}');">{'plugins_auto_update'|@translate}</a>
+      / <a href="{$plugin.URL_DOWNLOAD}">{'plugins_download'|@translate}</a></td>
+  </tr>
+{/foreach}
+</table>
+{/if}
+
+
+{if isset($plugins_uptodate)}
+<br>
+<b>{'plugins_dontneed_update'|@translate}</b>
+<table class="table2 plugins">
+<thead>
+  <tr class="throw">
+    <td>{'Name'|@translate}</td>
+    <td>{'Version'|@translate}</td>
+  </tr>
+</thead>
+{foreach from=$plugins_uptodate item=plugin name=plugins_loop}
+  <tr class="{if $smarty.foreach.plugins_loop.index is odd}row1{else}row2{/if}">
+    <td><a href="{$plugin.URL}" onclick="window.open(this.href); return false;" class="cluetip" title="{$plugin.NAME}|{$plugin.EXT_DESC|htmlspecialchars|nl2br}">{$plugin.NAME}</a></td>
+    <td style="text-align:center;"><a href="{$plugin.URL}" onclick="window.open(this.href); return false;" class="cluetip" title="{$plugin.NAME}|{$plugin.VER_DESC|htmlspecialchars|nl2br}">{$plugin.VERSION}</a></td>
+  </tr>
+{/foreach}
+</table>
+{/if}
+
+
+{if isset($plugins_cant_check)}
+<br>
+<b>{'plugins_cant_check'|@translate}</b>
+<table class="table2 plugins">
+<thead>
+  <tr class="throw">
+    <td>{'Name'|@translate}</td>
+    <td>{'Version'|@translate}</td>
+  </tr>
+</thead>
+{foreach from=$plugins_cant_check item=plugin name=plugins_loop}
+  <tr class="{if $smarty.foreach.plugins_loop.index is odd}row1{else}row2{/if}">
+    <td>{$plugin.NAME}</td>
+    <td style="text-align:center;">{$plugin.VERSION}</td>
+  </tr>
+{/foreach}
+</table>
+{/if}
Index: /tags/2.0.2/admin/template/goto/print.css
===================================================================
--- /tags/2.0.2/admin/template/goto/print.css	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/print.css	(revision 3278)
@@ -0,0 +1,14 @@
+#menubar, .content .navigationBar, UL.categoryActions, 
+#imageToolBar, .navThumb, #addComment {
+    display: none;
+}
+
+BODY {
+    margin: 0;
+    color: #000000;
+    background: #ffffff;
+}
+
+.content {
+    margin: 0;
+}
Index: /tags/2.0.2/admin/template/goto/profile.tpl
===================================================================
--- /tags/2.0.2/admin/template/goto/profile.tpl	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/profile.tpl	(revision 3278)
@@ -0,0 +1,6 @@
+{* $Id$ *}
+<div class="titrePage">
+  <h2>{'Profile'|@translate}</h2>
+</div>
+
+{$PROFILE_CONTENT}
Index: /tags/2.0.2/admin/template/goto/profile_content.tpl
===================================================================
--- /tags/2.0.2/admin/template/goto/profile_content.tpl	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/profile_content.tpl	(revision 3278)
@@ -0,0 +1,109 @@
+{* $Id$ *}
+<form method="post" name="profile" action="{$F_ACTION}" id="profile" class="properties">
+
+  <fieldset>
+    <legend>{'Registration'|@translate}</legend>
+    <input type="hidden" name="redirect" value="{$REDIRECT}" />
+    <ul>
+      <li>
+        <span class="property">{'Username'|@translate}</span>
+        {$USERNAME}
+      </li>
+{if not $SPECIAL_USER} {* can modify password + email*}
+      <li>
+        <span class="property">
+          <label for="mail_address">{'Email address'|@translate}</label>
+        </span>
+        <input type="text" name="mail_address" id="mail_address" value="{$EMAIL}">
+      </li>
+{if not $IN_ADMIN} {* admins do not need old password*}
+      <li>
+        <span class="property">
+          <label for="password">{'Password'|@translate}</label>
+        </span>
+        <input type="password" name="password" id="password" value="">
+      </li>
+{/if}
+      <li>
+        <span class="property">
+          <label for="use_new_pwd">{'new_password'|@translate}</label>
+        </span>
+        <input type="password" name="use_new_pwd" id="use_new_pwd" value="">
+      </li>
+      <li>
+        <span class="property">
+          <label for="passwordConf">{'Confirm Password'|@translate}</label>
+        </span>
+        <input type="password" name="passwordConf" id="passwordConf" value="">
+      </li>
+    </ul>
+{/if}
+  </fieldset>
+
+  <fieldset>
+    <legend>{'preferences'|@translate}</legend>
+
+    <ul>
+      <li>
+        <span class="property">
+          <label for="nb_image_line">{'nb_image_per_row'|@translate}</label>
+        </span>
+        <input type="text" size="3" maxlength="2" name="nb_image_line" id="nb_image_line" value="{$NB_IMAGE_LINE}">
+      </li>
+      <li>
+        <span class="property">
+          <label for="nb_line_page">{'nb_row_per_page'|@translate}</label>
+        </span>
+        <input type="text" size="3" maxlength="2" name="nb_line_page" id="nb_line_page" value="{$NB_ROW_PAGE}" >
+      </li>
+      <li>
+        <span class="property">
+          <label for="template">{'theme'|@translate}</label>
+        </span>
+        {html_options name=template options=$template_options selected=$template_selection}
+      </li>
+      <li>
+        <span class="property">
+          <label for="language">{'language'|@translate}</label>
+        </span>
+        {html_options name=language options=$language_options selected=$language_selection}
+      </li>
+      <li>
+        <span class="property">
+          <label for="recent_period">{'recent_period'|@translate}</label>
+        </span>
+        <input type="text" size="3" maxlength="2" name="recent_period" id="recent_period" value="{$RECENT_PERIOD}">
+      </li>
+      <li>
+        <span class="property">{'auto_expand'|@translate}</span>
+        {html_radios name='expand' options=$radio_options selected=$EXPAND}
+      </li>
+      <li>
+        <span class="property">{'show_nb_comments'|@translate}</span>
+        {html_radios name='show_nb_comments' options=$radio_options selected=$NB_COMMENTS}
+      </li>
+      <li>
+        <span class="property">{'show_nb_hits'|@translate}</span>
+        {html_radios name='show_nb_hits' options=$radio_options selected=$NB_HITS}
+      </li>
+      <li>
+        <span class="property">
+          <label for="maxwidth">{'maxwidth'|@translate}</label>
+        </span>
+        <input type="text" size="4" maxlength="4" name="maxwidth" id="maxwidth" value="{$MAXWIDTH}">
+      </li>
+      <li>
+        <span class="property">
+          <label for="maxheight">{'maxheight'|@translate}</label>
+        </span>
+        <input type="text" size="4" maxlength="4" name="maxheight" id="maxheight" value="{$MAXHEIGHT}">
+      </li>
+    </ul>
+  </fieldset>
+
+  <p class="bottomButtons">
+    <input class="submit" type="submit" name="validate" value="{'Submit'|@translate}">
+    <input class="submit" type="reset" name="reset" value="{'Reset'|@translate}">
+  </p>
+
+</form>
Index: /tags/2.0.2/admin/template/goto/rating.tpl
===================================================================
--- /tags/2.0.2/admin/template/goto/rating.tpl	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/rating.tpl	(revision 3278)
@@ -0,0 +1,67 @@
+{* $Id$ *}
+<h2>{'Rating'|@translate} [{$NB_ELEMENTS} {'elements'|@translate}]</h2>
+
+<form action="{$F_ACTION}" method="GET" id="update" class="filter">
+  <fieldset>
+    <legend>{'Filter'|@translate}</legend>
+
+    <label>
+      {'Sort by'|@translate}
+      <select name="order_by">
+        {html_options options=$order_by_options selected=$order_by_options_selected}
+      </select>
+    </label>
+
+    <label>
+      {'Users'|@translate}
+      <select name="users">
+        {html_options options=$user_options selected=$user_options_selected}
+      </select>
+    </label>
+
+    <label>
+      {'Number of items'|@translate}
+      <input type="text" name="display" size="2" value="{$DISPLAY}">
+    </label>
+
+    <label>
+      &nbsp;
+    <input class="submit" type="submit" name="submit_filter" value="{'Submit'|@translate}" />
+    </label>
+    <input type="hidden" name="page" value="rating" />
+  </fieldset>
+</form>
+
+<div class="navigationBar">{$NAVBAR}</div>
+<table width="99%">
+<tr class="throw">
+  <td>{'File'|@translate}</td>
+  <td>{'Number of rates'|@translate}</td>
+  <td>{'Average rate'|@translate}</td>
+  <td>{'Controversy'|@translate}</td>
+  <td>{'Sum of rates'|@translate}</td>
+  <td>{'Rate'|@translate}</td>
+  <td>{'Username'|@translate}</td>
+  <td>{'Rate date'|@translate}</td>
+  <td></td>
+</tr>
+{foreach from=$images item=image name=image}
+<tr valign="top" class="{if $smarty.foreach.image.index is odd}row1{else}row2{/if}">
+  <td rowspan="{$image.NB_RATES_TOTAL+1}"><a href="{$image.U_URL}"><img src="{$image.U_THUMB}" alt="{$image.FILE}" title="{$image.FILE}"></a></td>
+  <td rowspan="{$image.NB_RATES_TOTAL+1}"><strong>{$image.NB_RATES}/{$image.NB_RATES_TOTAL}</strong></td>
+  <td rowspan="{$image.NB_RATES_TOTAL+1}"><strong>{$image.AVG_RATE}</strong></td>
+  <td rowspan="{$image.NB_RATES_TOTAL+1}"><strong>{$image.STD_RATE}</strong></td>
+  <td rowspan="{$image.NB_RATES_TOTAL+1}" style="border-right: 1px solid;" ><strong>{$image.SUM_RATE}</strong></td>
+</tr>
+{foreach from=$image.rates item=rate name=rate}
+<tr class="{if ($smarty.foreach.image.index+$smarty.foreach.rate.index) is odd}row1{else}row2{/if}">
+    <td>{$rate.RATE}</td>
+    <td><b>{$rate.USER}</b></td>
+    <td><span class="date">{$rate.DATE}</span></td>
+    <td><a href="{$rate.U_DELETE}" {$TAG_INPUT_ENABLED}><img src="{$themeconf.admin_icon_dir}/delete.png" class="button" style="border:none;vertical-align:middle; margin-left:5px;" alt="[{'delete'|@translate}]"/></a></td>
+</tr>
+{/foreach} {*rates*}
+{/foreach} {*images*}
+</table>
+
+<div class="navigationBar">{$NAVBAR}</div>
Index: /tags/2.0.2/admin/template/goto/site_manager.tpl
===================================================================
--- /tags/2.0.2/admin/template/goto/site_manager.tpl	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/site_manager.tpl	(revision 3278)
@@ -0,0 +1,74 @@
+{* $Id$ *}
+<div class="titrePage">
+  <h2>{'Site manager'|@translate}</h2>
+</div>
+
+{if not empty($remote_output)}
+<div class="remoteOutput">
+  <ul>
+    {foreach from=$remote_output item=remote_line}
+    <li class="{$remote_line.CLASS}">{$remote_line.CONTENT}</li>
+    {/foreach}
+  </ul>
+</div>
+{/if}
+
+{if isset($local_listing)}
+{'remote_site_local_found'|@translate} {$local_listing.URL}
+{if isset($local_listing.CREATE)}
+<form action="{$F_ACTION}" method="post">
+  <p>
+    {'remote_site_local_create'|@translate}:
+    <input type="hidden" name="no_check" value="1"/>
+    <input type="hidden" name="galleries_url" value="{$local_listing.URL}" />
+    <input type="submit" name="submit" value="{'Submit'|@translate}" {$TAG_INPUT_ENABLED} />
+  </p>
+</form>
+{/if}
+{if isset($local_listing.U_SYNCHRONIZE)}
+&nbsp;<a href="{$local_listing.U_SYNCHRONIZE}" title="{'remote_site_local_update'|@translate}">{'site_synchronize'|@translate}</a>
+<br/><br/>
+{/if}
+{/if}
+
+{if not empty($sites)}
+<table class="table2">
+	<tr class="throw">
+		<td>{'site_local'|@translate} / {'site_remote'|@translate}</td>
+		<td>{'Actions'|@translate}</td>
+	</tr>
+  {foreach from=$sites item=site name=site}
+  <tr style="text-align:left" class="{if $smarty.foreach.site.index is odd}row1{else}row2{/if}"><td>
+    <a href="{$site.NAME}">{$site.NAME}</a><br/>({$site.TYPE}, {$site.CATEGORIES} {'Categories'|@translate}, {$pwg->l10n_dec('%d element','%d elements',$site.IMAGES)})
+  </td><td>
+    [<a href="{$site.U_SYNCHRONIZE}" title="{'site_synchronize_hint'|@translate}">{'site_synchronize'|@translate}</a>]
+    {if isset($site.U_DELETE)}
+      [<a href="{$site.U_DELETE}" onclick="return confirm('{'Are you sure?'|@translate|escape:'javascript'}');"
+                title="{'site_delete_hint'|@translate}" {$TAG_INPUT_ENABLED}>{'site_delete'|@translate}</a>]
+    {/if}
+    {if isset($site.remote)}
+      <br/>
+      [<a href="{$site.remote.U_TEST}" title="{'remote_site_test_hint'|@translate}" {$TAG_INPUT_ENABLED}>{'remote_site_test'|@translate}</a>]
+      [<a href="{$site.remote.U_GENERATE}" title="{'remote_site_generate_hint'|@translate}" {$TAG_INPUT_ENABLED}>{'remote_site_generate'|@translate}</a>]
+      [<a href="{$site.remote.U_CLEAN}" title="{'remote_site_clean_hint'|@translate}" {$TAG_INPUT_ENABLED}>{'remote_site_clean'|@translate}</a>]
+    {/if}
+    {if not empty($site.plugin_links)}
+        <br>
+      {foreach from=$site.plugin_links item=plugin_link}
+        [<a href="{$plugin_link.U_HREF}" title='{$plugin_link.U_HINT}' {$TAG_INPUT_ENABLED}>{$plugin_link.U_CAPTION}</a>]
+      {/foreach}
+    {/if}
+  </td></tr>
+  {/foreach}
+</table>
+{/if}
+
+<form action="{$F_ACTION}" method="post">
+  <p>
+    <label for="galleries_url" >{'site_create'|@translate}</label>
+    <input type="text" name="galleries_url" id="galleries_url" />
+  </p>
+  <p>
+    <input class="submit" type="submit" name="submit" value="{'Submit'|@translate}" {$TAG_INPUT_ENABLED} />
+  </p>
+</form>
Index: /tags/2.0.2/admin/template/goto/site_update.tpl
===================================================================
--- /tags/2.0.2/admin/template/goto/site_update.tpl	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/site_update.tpl	(revision 3278)
@@ -0,0 +1,117 @@
+{* $Id$ *}
+
+{include file='include/resize.inc.tpl'}
+
+<div class="titrePage">
+  <h2>{'title_update'|@translate}: <a href="{$SITE_URL}">{$SITE_URL}</a></h2>
+</div>
+
+{if isset($update_result)}
+<h3>{$L_RESULT_UPDATE}</h3>
+<ul>
+  <li class="update_summary_new">{$update_result.NB_NEW_CATEGORIES} {'update_nb_new_categories'|@translate}</li>
+  <li class="update_summary_new">{$update_result.NB_NEW_ELEMENTS} {'update_nb_new_elements'|@translate}</li>
+  <li class="update_summary_del">{$update_result.NB_DEL_CATEGORIES} {'update_nb_del_categories'|@translate}</li>
+  <li class="update_summary_del">{$update_result.NB_DEL_ELEMENTS} {'update_nb_del_elements'|@translate}</li>
+  <li>{$update_result.NB_UPD_ELEMENTS} {'update_nb_upd_elements'|@translate}</li>
+  <li class="update_summary_err">{$update_result.NB_ERRORS} {'update_nb_errors'|@translate}</li>
+</ul>
+{/if}
+
+{if isset($metadata_result)}
+<h3>{$L_RESULT_METADATA}</h3>
+<ul>
+  <li>{$metadata_result.NB_ELEMENTS_DONE} {'update_nb_elements_metadata_sync'|@translate}</li>
+  <li>{$metadata_result.NB_ELEMENTS_CANDIDATES} {'update_nb_elements_metadata_available'|@translate}</li>
+  <li>{'update_used_metadata'|@translate} : {$METADATA_LIST}</li>
+</ul>
+{/if}
+
+
+{if not empty($sync_errors)}
+<h3>{'update_error_list_title'|@translate}</h3>
+<div class="errors">
+<ul>
+  {foreach from=$sync_errors item=error}
+  <li>[{$error.ELEMENT}] {$error.LABEL}</li>
+  {/foreach}
+</ul>
+</div>
+<h3>{'update_errors_caption'|@translate}</h3>
+<ul>
+  {foreach from=$sync_error_captions item=caption}
+  <li><strong>{$caption.TYPE}</strong>: {$caption.LABEL}</li>
+  {/foreach}
+</ul>
+{/if}
+
+{if not empty($sync_infos)}
+<h3>{'update_infos_title'|@translate}</h3>
+<div class="infos">
+<ul>
+  {foreach from=$sync_infos item=info}
+  <li>[{$info.ELEMENT}] {$info.LABEL}</li>
+  {/foreach}
+</ul>
+</div>
+{/if}
+
+{if isset($introduction)}
+<h4>{'update_default_title'|@translate}</h4>
+<form action="" method="post" id="update">
+
+	<fieldset id="syncFiles">
+		<legend>{'update_sync_files'|@translate}</legend>
+		<ul>
+			<li><label><input type="radio" name="sync" value="" {if empty($introduction.sync)}checked="checked"{/if}/> {'nothing'|@translate}</label></li>
+			<li><label><input type="radio" name="sync" value="dirs" {if 'dirs'==$introduction.sync}checked="checked"{/if}/> {'update_sync_dirs'|@translate}</label></li>
+
+			<li><label><input type="radio" name="sync" value="files" {if 'files'==$introduction.sync}checked="checked"{/if}/> {'update_sync_all'|@translate}</label>
+				<ul style="padding-left:3em">
+					<li><label><input type="checkbox" name="display_info" value="1" {if $introduction.display_info}checked="checked"{/if}/> {'update_display_info'|@translate}</label></li>
+					<li><label><input type="checkbox" name="add_to_caddie" value="1" {if $introduction.add_to_caddie}checked="checked"{/if}/> {'add new elements to caddie'|@translate}</label></li>
+					<li><label>{'Minimum privacy level'|@translate} <select name="privacy_level">{html_options options=$introduction.privacy_level_options selected=$introduction.privacy_level_selected}</select></label></li>
+				</ul>
+			</li>
+		</ul>
+	</fieldset>
+
+	<fieldset id="syncMetadata">
+		<legend>{'update_sync_metadata'|@translate}</legend>
+		<label><input type="checkbox" name="sync_meta" {if $introduction.sync_meta}checked="checked"{/if}/> {'synchronize metadata'|@translate} ({$METADATA_LIST})</label></li>
+		<ul style="padding-left:3em">
+	  		<li>
+	  			<label><input type="checkbox" name="meta_all" {if $introduction.meta_all}checked="checked"{/if}/> {'update_sync_metadata_all'|@translate}</label>
+	  		</li>
+	  		<li>
+	  			<label><input type="checkbox" name="meta_empty_overrides" {if $introduction.meta_empty_overrides}checked="checked"{/if}/> {'overrides existing values with empty ones'|@translate}</label>
+	  		</li>
+		</ul>
+	</fieldset>
+
+  <fieldset id="syncSimulate">
+    <legend></legend>
+    <ul><li><label><input type="checkbox" name="simulate" value="1" checked="checked" {$TAG_INPUT_ENABLED} /> {'update_simulate'|@translate}</label></li></ul>
+  </fieldset>
+
+  <fieldset id="catSubset">
+    <legend>{'update_cats_subset'|@translate}</legend>
+    <ul>
+    <li>
+    <select class="categoryList" name="cat" size="10">
+      {html_options options=$category_options selected=$category_options_selected}
+    </select>
+    </li>
+
+    <li><label><input type="checkbox" name="subcats-included" value="1" {if $introduction.subcats_included}checked="checked"{/if}/> {'search_subcats_included'|@translate}</label></li>
+    </ul>
+  </fieldset>
+
+  <p class="bottomButtons">
+    <input class="submit" type="submit" value="{'Submit'|@translate}" name="submit" />
+    <input class="submit" type="reset"  value="{'Reset'|@translate}"  name="reset"  />
+  </p>
+</form>
+{/if}{*isset $introduction*}
+
+<p><a href="{$U_SITE_MANAGER}">{'Site manager'|@translate}</a></p>
Index: /tags/2.0.2/admin/template/goto/stats.tpl
===================================================================
--- /tags/2.0.2/admin/template/goto/stats.tpl	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/stats.tpl	(revision 3278)
@@ -0,0 +1,26 @@
+{* $Id$ *}
+
+<div class="titrePage">
+  <h2>{'History'|@translate} {$TABSHEET_TITLE}</h2>
+</div>
+
+<h3>{$L_STAT_TITLE}</h3>
+
+<table class="table2" id="dailyStats">
+	<tr class="throw">
+		<th>{$PERIOD_LABEL}</th>
+		<th>{'Pages seen'|@translate}</th>
+		<th></th>
+	</tr>
+
+{if not empty($statrows)}
+{foreach from=$statrows item=row}
+	<tr>
+		<td style="white-space: nowrap">{$row.VALUE}</td>
+		<td class="number">{$row.PAGES}</td>
+		<td><div class="statBar" style="width:{$row.WIDTH}px"></div></td>
+	</tr>
+{/foreach}
+{/if}
+
+</table>
Index: /tags/2.0.2/admin/template/goto/tabsheet.tpl
===================================================================
--- /tags/2.0.2/admin/template/goto/tabsheet.tpl	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/tabsheet.tpl	(revision 3278)
@@ -0,0 +1,10 @@
+{* $Id$ *}
+{if isset($tabsheet) and count($tabsheet)}
+<ul class="tabsheet">
+{foreach from=$tabsheet key=name item=sheet}
+  <li class="{if ($name == $tabsheet_selected)}selected_tab{else}normal_tab{/if}">
+    <a href="{$sheet.url}"><span>{$sheet.caption}</span></a>
+  </li>
+{/foreach}
+</ul>
+{/if}
Index: /tags/2.0.2/admin/template/goto/tags.tpl
===================================================================
--- /tags/2.0.2/admin/template/goto/tags.tpl	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/tags.tpl	(revision 3278)
@@ -0,0 +1,54 @@
+{* $Id$ *}
+<div class="titrePage">
+  <h2>{'Manage tags'|@translate}</h2>
+</div>
+
+<form action="{$F_ACTION}" method="post">
+
+  {if isset($EDIT_TAGS_LIST)}
+  <fieldset>
+    <legend>{'Edit tags'|@translate}</legend>
+    <input type="hidden" name="edit_list" value="{$EDIT_TAGS_LIST}" />
+    <table class="table2">
+      <tr class="throw">
+        <th>{'Current name'|@translate}</th>
+        <th>{'New name'|@translate}</th>
+      </tr>
+      {foreach from=$tags item=tag}
+      <tr>
+        <td>{$tag.NAME}</td>
+        <td><input type="text" name="tag_name-{$tag.ID}" value="{$tag.NAME}" /></td>
+      </tr>
+      {/foreach}
+    </table>
+
+    <p>
+      <input class="submit" type="submit" name="submit" value="{'Submit'|@translate}" {$TAG_INPUT_ENABLED} />
+      <input class="submit" type="reset" value="{'Reset'|@translate}" />
+    </p>
+  </fieldset>
+  {/if}
+
+  <fieldset>
+    <legend>{'Add a tag'|@translate}</legend>
+
+    <label>
+      {'New tag'|@translate}
+      <input type="text" name="add_tag" />
+    </label>
+    
+    <p><input class="submit" type="submit" name="add" value="{'Submit'|@translate}" {$TAG_INPUT_ENABLED}/></p>
+  </fieldset>
+
+  <fieldset>
+    <legend>{'Tag selection'|@translate}</legend>
+    
+    {$TAG_SELECTION}
+
+    <p>
+      <input class="submit" type="submit" name="edit" value="{'Edit selected tags'|@translate}"/>
+      <input class="submit" type="submit" name="delete" value="{'Delete selected tags'|@translate}" onclick="return confirm('{'Are you sure?'|@translate}');" {$TAG_INPUT_ENABLED}/>
+    </p>
+  </fieldset>
+
+</form>
Index: /tags/2.0.2/admin/template/goto/theme/roma/index.php
===================================================================
--- /tags/2.0.2/admin/template/goto/theme/roma/index.php	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/theme/roma/index.php	(revision 3278)
@@ -0,0 +1,54 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+// +-----------------------------------------------------------------------+
+// | PhpWebGallery - a PHP based picture gallery                           |
+// | Copyright (C) 2002-2003 Pierrick LE GALL - pierrick@phpwebgallery.net |
+// | Copyright (C) 2003-2007 PhpWebGallery Team - http://phpwebgallery.net |
+// +-----------------------------------------------------------------------+
+// | file          : $Id$
+// | last update   : $Date$
+// | last modifier : $Author$
+// | revision      : $Revision$
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/admin/template/goto/theme/roma/mail-css.tpl
===================================================================
--- /tags/2.0.2/admin/template/goto/theme/roma/mail-css.tpl	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/theme/roma/mail-css.tpl	(revision 3278)
@@ -0,0 +1,19 @@
+{* $Id$ *}
+/* Theme wipi mail css */
+
+body {ldelim} background-color:#111; color:#69c;}
+#the_page {ldelim} background: #111 url({$ROOT_URL}template/{$themeconf.template}/mail/text/html/images/mailbody-bg.png) repeat-y scroll left top;}
+#content {ldelim} background: transparent url({$ROOT_URL}template/{$themeconf.template}/mail/text/html/images/header-bg.png) no-repeat scroll left top;}
+#copyright {ldelim} background: transparent url({$ROOT_URL}template/{$themeconf.template}/mail/text/html/images/footer-bg.png) no-repeat scroll left bottom;
+color: #69c;}
+h2 {ldelim} background-color: #222;color:#eee;background-image: url({$ROOT_URL}template/{$themeconf.template}/theme/{$themeconf.theme}/images/tableh1_bg.png);}
+img {ldelim} margin: 16px; padding:15px;border:1px solid #eee; -moz-border-radius: 4px; border-radius: 4px 4px; }
+img:hover {ldelim} border:1px solid #69c; -moz-border-radius: 4px; border-radius: 4px 4px; }
+a {ldelim} color: #69c; background: transparent; }
+a:hover {ldelim} color: #f92; }
+a.PWG {ldelim} border: 0px; }
+a.PWG .P {ldelim} color : #f92; }
+a.PWG .W {ldelim} color : #aaa; }
+a.PWG .G {ldelim} color : #69c; }
+a.PWG:hover .P {ldelim} color : #69c; }
+a.PWG:hover .G {ldelim} color : #f92; }
Index: /tags/2.0.2/admin/template/goto/theme/roma/theme.css
===================================================================
--- /tags/2.0.2/admin/template/goto/theme/roma/theme.css	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/theme/roma/theme.css	(revision 3278)
@@ -0,0 +1,214 @@
+/* $Id$ */
+/* text color */
+body, h3, dt, h2, .throw, .content, label,
+input.rateButtonSelected /* <= why IE doesn't inherit this ? */ { color:#666; }
+INPUT, select, textarea { color:#999; background-color: #444; }  
+input[type="radio"], input[type="checkbox"] { background-color: transparent; }  
+/* INPUT[type="checkbox"], INPUT[type="radio"]
+{ color:#999; background-color: #eee; }  */
+INPUT[type="submit"], INPUT[type="reset"]  { color:#999; border: 1px solid #666; background-color: #444; padding: 1px 15px; }
+input.rateButton, legend, h3 { color: #666; }
+#theAdminPage h2 { color: #333; }
+.content .infos { color: #f70; border:0; background-color: transparent;
+padding:5px 60px 0pt 10pt; min-height: 48px; text-align:left; background-position:left top;}
+.content .infos .submit {margin-left:30px;}
+.content .infos li, .content .errors li { list-style-type:none; }
+.content .errors { color: #f33; border:0; background-color: transparent;
+padding:5px 60px 0pt 10pt; min-height: 48px; text-align:left; font-weight:bold; background-position:left top;  }
+#copyright { color:#666; margin:60px auto 0px 240px; text-align:center; 
+padding-bottom: 15px; }
+.header_notes { background: transparent url(../../icon/note.png) no-repeat right top;
+border:0; font-weight:bold; min-height: 48px;
+padding:15px 60px 0 0; position:absolute; right:0;
+text-align:right; top:90px; width:550px;  }
+html, body { min-height: 100%; }
+body { margin: 0; padding: 0;
+background:#111111 url(images/bottom-left-bg.jpg) no-repeat fixed left bottom; }
+#the_page { margin: 0; padding: 0; z-index: 1; top:0px;
+padding-top: 0; min-height: 100%; width:100%; position:absolute; left:0px; }
+#headbranch { width: 233px; height: 240px; margin: 0; padding: 0;
+position:absolute; left:0px; top:0px; z-index: 0; 
+background:transparent url(images/top-left-bg.jpg) no-repeat scroll left top; }
+#theHeader { min-height:105px; margin: 0; padding: 0;
+background:transparent url(images/piwigo_logo_sombre_214x100.png) no-repeat scroll 245px top; }
+h3, #imageToolBar a:hover, .row2, .content { background-color: #222; }
+.throw, .row1 { background-color:#111; }
+.throw em { font-style: normal; color: #ff3363; }
+#content { background: #222 url(images/fillet.png) repeat-x top left; min-height: 466px; margin-top: 9px; }
+.content { padding:5px 5px 5px 5px; margin: 0 10px 0 248px; z-index:99; }
+.content h3 { font-size:20px; letter-spacing:-0.4px; margin:0 20px 12px 0;
+ text-align:center; background:none; border: 0; }
+.content h3 ~ h3{ margin-top: 40px; }
+.content h4 { font-size:14px; text-align:left; padding:3px; margin: 2px;}
+/*.content h2:before, .content h2:after, */ 
+.content h2 { 
+letter-spacing:2px; margin-right:30px; text-align:right; color: #666; 
+text-transform:none; font-weight:bold; padding-left:20px; width:54%; }
+.content h2:lang(en) { text-transform:capitalize; }
+
+.content dl, dd { margin:5px; }
+.content div.titrePage { height:55px; }
+
+.instructions { text-align:left; padding-top:5px;}
+.instructions LI { margin-bottom:5px; }
+.instructionBlock {border: 1px solid #666; margin: 5px; overflow: hidden;}
+.instructionBlockHeaderCollapsed, .instructionBlockHeaderExpanded {background-color:#111; background-position:15px center;
+background-repeat:no-repeat; color:#ff3363; cursor:pointer; font-size:110%; overflow:hidden; padding:8px 41px;}
+.instructionBlockHeaderCollapsed span, .instructionBlockHeaderExpanded span {border-bottom: none; }
+ 
+.instructionBlockHeaderCollapsed { background-image: url(../../icon/expand.gif);}
+.instructionBlockHeaderExpanded { background-image: url(../../icon/collapse.gif);}
+.instructionBlockContent { padding:0 15px 15px;}
+SPAN.pwgScreen { font-style:italic; border-bottom:1px dotted #666}
+
+.content ul.thumbnails span.wrap2:hover { background-color:#111; border:1px solid #FF3363; color:#666; }
+.content ul.thumbnails span.wrap2 { border:1px solid #666; padding: 4px; }
+.content ul.thumbnails span.wrap2 { -moz-border-radius-bottomleft:4px; -moz-border-radius-bottomright:4px; -moz-border-radius-topleft:4px; -moz-border-radius-topright:4px; }
+.content ul.thumbnails span.wrap1 { margin:0 12px 5px; }
+/* .throw, */ td h3 {
+ background-image: url(images/fillet.png); background-repeat: repeat-x; }
+/* borders */ 
+fieldset { border: 1px solid #666; }
+INPUT, SELECT, TEXTAREA { border: 1px solid #666; }
+input:focus, select:focus, textarea:focus, input.focus, form .focus { background-color:#444;color: #999; }
+TEXTAREA { cursor:text; font-size: 13px; }
+.content UL.thumbnails SPAN.wrap2 {
+  border: 1px solid #aaaaaa;	/* thumbnails border color and style */
+  border-radius: 4px 4px;	/* round corners with CSS3 compliant browsers */
+}
+.tagSelection label { padding-right:12px; }
+.content ul.categoryActions a img { margin-left: 10px; }
+ul.thumbnails input { border:3px double #999; color:#999; font-size:10px; margin:0; background-color:#444; text-align: center;}
+INPUT[type="submit"]:hover , INPUT[type="reset"]:hover  { cursor: pointer; }
+INPUT.bigbutton:hover { background-color: #222;  color:#f33; border: 0; }
+.throw  { font-size: 120%; line-height: 26px; padding-top: 10px; font-weight: bold; color: #ff3363; }
+label { cursor:pointer }
+.categoryLi { background: #222 }
+.virtual_cat { background: #333 !important; }
+a.Piwigo {
+  font-family: verdana, arial, helvetica, sans-serif !important;
+  font-size: 11px; font-weight: normal; letter-spacing: 0;
+  color : #F33; text-decoration: none; border: 0; }
+a.Piwigo:hover  span.Piwigo  { 
+  border-bottom: 1px solid #FF3363; 
+}
+
+*, *:focus, *:active, input:active, a:active, input:focus, a:focus { outline: none; -moz-outline-width: 0px; }
+a { color:#f70; border-width: 0; }
+a:hover, a:active { color: #f33; border-bottom: 1px solid #FF3363; cursor: pointer; }
+.content .navigationBar {color:#666;}
+ul.actions, .content form#waiting  {text-align:center;}
+h2 { display:block; font-size:28px; letter-spacing:-1px; 
+margin:0 20px; height:104px; overflow:hidden; padding:0; position:absolute; 
+right:0; text-align:right; top:0; width:770px; }
+.header_msgs { background:transparent url(images/header_msgs-bg.gif) repeat scroll right top;
+border:0; color:#333; font-size:24px; height:30px; left:0; margin:0; padding:10px 0 0; position:absolute;
+text-align:center; top:0; width:100%; z-index:99; }
+.HelpActions a { border:0; margin:-14px 14px 0 0; position:absolute; right:0; }
+.HelpActions li {list-style-image:none; list-style-position:outside; 
+list-style-type:none; text-align:center; text-indent:0pt; }
+#content.content div.comment a.illustration{ margin-right: 30px;}
+/* tabsheets are often used in admin  pages => No specific css files */
+.tabsheet { 
+background-color:transparent; border:0; display:table; float:right; 
+font-family:verdana,arial,helvetica,sans-serif; font-size:8px; line-height:14px; 
+list-style-image:none; padding: 0; position:relative; text-decoration:none;
+top:-2px; white-space:nowrap; margin: 0 28px 0 0;}
+.tabsheet li { background:transparent url(images/inactive_tab.png) no-repeat scroll left 0;
+float:left; margin:0 2px 0 0; overflow:hidden; text-align:right; }
+.tabsheet a { 
+background:transparent url(images/inactive_tab2.png) no-repeat scroll right 0px;
+color:#666; display:block; font-size:11px; border:0;
+font-weight:bold; height:18px; overflow:hidden; padding:8px 7px 5px 18px; line-height: 18px;
+text-align:right; text-decoration:none; margin: 0; }
+.tabsheet a:first-letter { text-transform:capitalize; }
+.tabsheet li:hover, .tabsheet li.selected_tab  { 
+background:transparent url(images/active_tab.png) no-repeat scroll left 0px; }
+.tabsheet a:hover, .tabsheet li.selected_tab  a { color: #F36;
+background:transparent url(images/active_tab2.png) no-repeat scroll right 0px; }
+.tabsheet a span { display:block; font-size:10px; margin-right:2px; padding:0 3px 0 1px; }
+.tabsheet .selected_tab a span { background:transparent url(images/active_tab3.png) repeat-x scroll left top; }
+.tabsheet .normal_tab a span { background:transparent url(images/inactive_tab3.png) repeat-x scroll left top; }
+.tabsheet .normal_tab:hover a span { background:transparent url(images/active_tab3.png) repeat-x scroll left top; }
+#debug { margin-left:248px; font-size:12px; }
+/* menubar is on all admin pages => No specific css file */
+#menubar {
+background:transparent url(images/menuBoxBottom_new.png) no-repeat scroll left bottom;
+border:0; display:inline; float:left; left:0; margin: 0 0 0 35px; min-height:475px; height:475px; /* should be 477 */
+padding:0; width:207px; z-index:99; text-align: left; }
+#menubar ul.scroll { height:163px; margin-right:10px; overflow-y:auto; 
+ /* Only IE family supports colored scrollbar */
+ scrollbar-face-color: #222; scrollbar-shadow-color: #444; scrollbar-highlight-color: #000;
+ scrollbar-3dlight-color: #292929; scrollbar-darkshadow-color: #333; scrollbar-track-color: #111;
+ scrollbar-arrow-color: #ff3333; }
+
+#menubar dd { 
+background: transparent url(images/menubar-detail.png) repeat-y top left; 
+margin: 10px 0 0 0; padding: 0; height:232px; }
+#menubar dl {
+background:transparent url(images/menuBoxTop_new.png) no-repeat scroll left top; 
+width: 207px; border:0; margin: 0; padding: 0; display: block; min-height:35px; }
+#menubar dl.first { 
+background:transparent url(images/menubar-top.png) no-repeat scroll left 1px; }
+#menubar dt { margin: 0; display: block; background: none; left:10px; font-weight:bold;
+position:relative; padding: 5px 1px 4px 5px; top:-10px; font-size: 13px; color: #666; }
+#menubar dt  span { background-color: #111; cursor:pointer; }
+#menubar li { margin: 0 0 0 6px; }
+#menubar li.external { list-style-image:url(images/external_inactive.png); padding:10px 0px 0pt 10px; }
+#menubar li.external:hover { list-style-image:url(images/external_active.png); }
+a.external { color:#FF3363; border:0; text-decoration: none; }
+a.external:hover { color:#FF7700; border:0; }
+#menubar ul { color: #333; margin:0 0 0 9px; line-height: 16px;
+  list-style-type: square; list-style-position: inside; padding: 0; }
+/* jQuery tooltips */
+.cluetip-default #cluetip-outer { border-color: #666; color: #666; background-color: #222; }
+.cluetip-default h3#cluetip-title { color: #ff3363; background-color: #111; }
+/* jQuery ui resizable */
+.ui-resizable { position: relative; }
+.ui-wrapper { border: 0; }
+.ui-wrapper input, .ui-wrapper textarea { border: 0; }
+
+/* Global handle styles */
+.ui-resizable-handle { position: absolute; display: none; font-size: 0.1px; }
+.ui-resizable .ui-resizable-handle { display: block; }
+body .ui-resizable-disabled .ui-resizable-handle { display: none; } /* use 'body' to make it more specific (css order) */
+body .ui-resizable-autohide .ui-resizable-handle { display: none; } /* use 'body' to make it more specific (css order) */
+.ui-resizable-n { cursor: n-resize; height: 6px; width: 100%; top: 0px; left: 0px; background: transparent url(images/resizable-n.gif) no-repeat scroll center top; }
+.ui-resizable-s { cursor: s-resize; height: 6px; width: 100%; bottom: 0px; left: 0px; background: transparent url(images/resizable-s.gif) no-repeat scroll center top; }
+.ui-resizable-e { cursor: e-resize; width: 6px; right: 0px; top: 0px; height: 100%; background: transparent url(images/resizable-e.gif) no-repeat scroll right center; }
+.ui-resizable-w { cursor: w-resize; width: 6px; left: 0px; top: 0px; height: 100%; background: transparent url(images/resizable-w.gif) no-repeat scroll right center; }
+.ui-resizable-se { cursor: se-resize; width: 9px; height: 9px; right: 0px; bottom: 0px; background: transparent url(images/resizable-se.gif); }
+.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: 0px; bottom: 0px; background: transparent url(images/resizable-sw.gif); }
+.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: 0px; top: 0px; background: transparent url(images/resizable-nw.gif); }
+.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: 0px; top: 0px; background: transparent url(images/resizable-ne.gif); }
+#ui-datepicker-div .ui-datepicker-control, #ui-datepicker-div  a { background-color: #111; color: #f70 !important;}
+#ui-datepicker-div .ui-datepicker-days-row { background-color: #444;}
+#ui-datepicker-div .ui-datepicker-week-end-cell, #ui-datepicker-div .ui-datepicker-week-end-cell  a { background-color: #222; color: #f33; border-color: #444; border-top-color: #222; border-left-color: #222;}
+#ui-datepicker-div .ui-datepicker-title-row { background-color: #111;}
+#ui-datepicker-div .ui-datepicker-title-row .ui-datepicker-week-end-cell a { color: #f33;}
+#ui-datepicker-div  a:hover { color: #ff3333 !important; border: 0; background-color: #111 !important;}
+#ui-datepicker-div .ui-datepicker-header select { background-color:#444; color:#999; font-weight:normal;}
+#ui-datepicker-div .ui-datepicker-links { background-color:#222;}
+#ui-datepicker-div .ui-datepicker-header { background-color:#444;}
+#ui-datepicker-div .ui-datepicker-current-day { background-color: #111 !important; border-color: #444; border-top-color: #111; border-left-color: #111;}
+#ui-datepicker-div .ui-datepicker-days-cell { background-color:#444; border:1px solid #222; border-top-color: #444; border-left-color: #444;}
+td img.ui-datepicker-trigger { margin:-3px 5px 2px; }
+INPUT[type="text"].large  { width: 317px; }
+input[type="button"], input[type="submit"], input[type="reset"] {
+color:#ff3363; background-color:#222; border-color: #ff3363; }
+input[type="button"]:hover, input[type="submit"]:hover, input[type="reset"]:hover {
+color:#999; border-color: #666; }
+.bigbutton { background:transparent url(images/quickLocalSync_inactiv.png) no-repeat scroll left top; display: block;
+color:#111; font-size:28px; height:161px; margin: 0 20px 0 auto; padding:0 18px 0; text-align:center; width:625px; 
+position:relative;  z-index: 50;}
+.bigtext { display:block; font-weight:bold; left:225px; position:relative; top:35px; width:320px;  z-index: 55; cursor:pointer; }
+.bigbutton:hover { background:transparent url(images/quickLocalSync_hover.png) no-repeat scroll left top; color: #000; }
+.bigbutton input { background:transparent url(images/transparent.gif) repeat scroll left top; border:0;
+display:block; height:85px; left:225px; position:relative; top:-42px; width:313px; z-index:99; padding:0;}
+.bigbutton input:hover { cursor:pointer; background:transparent url(images/transparent.gif) repeat scroll left top; border:0; padding:0;}
+/* hacks */
+html>body #menubar {min-height:477px; height:477px;} /* IE 7 and modern browsers */
+* html[lang="en"] body .content h2 , *+html[lang="en"] body .content h2 { text-transform:capitalize; } /* IE */
+*+html  .bigtext { left: 70px; }
+*+html  .bigbutton input, * html  .bigbutton input  { left:0px; position:relative; top:-40px; }
+* html .bigtext { margin-right: 300px; }
Index: /tags/2.0.2/admin/template/goto/theme/roma/themeconf.inc.php
===================================================================
--- /tags/2.0.2/admin/template/goto/theme/roma/themeconf.inc.php	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/theme/roma/themeconf.inc.php	(revision 3278)
@@ -0,0 +1,15 @@
+<?php
+if (!function_exists('selected_admin_menu')) 
+{
+  include_once(PHPWG_ROOT_PATH.'admin/include/functions_themes.inc.php');
+}
+$themeconf = array(
+  'template' => 'goto', /* Goto Admin template */
+  'theme' => 'roma',    /* "roma" is the foundation theme of Piwigo */
+  'icon_dir' => 'template/yoga/icon',
+  'admin_icon_dir' => 'admin/template/goto/icon',
+  'mime_icon_dir' => 'template/yoga/icon/mimetypes/',
+  'selected_admin_menu' => selected_admin_menu(),
+  'local_head' => '',
+);
+?>
Index: /tags/2.0.2/admin/template/goto/thumbnail.tpl
===================================================================
--- /tags/2.0.2/admin/template/goto/thumbnail.tpl	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/thumbnail.tpl	(revision 3278)
@@ -0,0 +1,120 @@
+{* $Id$ *}
+<div class="titrePage">
+  <h2>{'title_thumbnails'|@translate}</h2>
+</div>
+
+{if isset($results) }
+<div class="admin">{'tn_results_title'|@translate}</div>
+<table style="width:100%;">
+  <tr class="throw">
+    <td>{'Path'|@translate}</td>
+    <td>{'thumbnail'|@translate}</td>
+    <td>{'tn_results_gen_time'|@translate}</td>
+    <td>{'filesize'|@translate}</td>
+    <td>{'Dimensions'|@translate}</td>
+  </tr>
+  {foreach from=$results.elements item=elt}
+  <tr>
+    <td>{$elt.PATH}</td>
+    <td><img src="{$elt.TN_FILE_IMG}" /></td>
+    <td style="text-align:right;">{$elt.GEN_TIME}</td>
+    <td style="text-align:right;">{$elt.TN_FILESIZE_IMG}</td>
+    <td style="text-align:right;">{$elt.TN_WIDTH_IMG} x {$elt.TN_HEIGHT_IMG}</td>
+  </tr>
+  {/foreach}
+</table>
+
+<table class="table2">
+  <tr class="throw">
+    <td colspan="2">{'tn_stats'|@translate}</td>
+  </tr>
+  <tr>
+    <td>{'tn_stats_nb'|@translate}</td>
+    <td style="text-align:center;">{$results.TN_NB}</td>
+  </tr>
+  <tr>
+    <td>{'tn_stats_total'|@translate}</td>
+    <td style="text-align:right;">{$results.TN_TOTAL}</td>
+  </tr>
+  <tr>
+    <td>{'tn_stats_max'|@translate}</td>
+    <td style="text-align:right;">{$results.TN_MAX}</td>
+  </tr>
+  <tr>
+    <td>{'tn_stats_min'|@translate}</td>
+    <td style="text-align:right;">{$results.TN_MIN}</td>
+  </tr>
+  <tr>
+    <td>{'tn_stats_mean'|@translate}</td>
+    <td style="text-align:right;">{$results.TN_AVERAGE}</td>
+  </tr>
+</table>
+<br />
+{/if}
+
+{if isset($params) }
+<form method="post" action="{$params.F_ACTION}" class="properties">
+
+  <fieldset>
+    <legend>{'tn_params_title'|@translate}</legend>
+
+    <ul>
+      <li>
+        <span class="property">{'tn_params_GD'|@translate}</span>
+	<label>
+          <input type="radio" name="gd" value="2" {if $params.GD_SELECTED==2}checked="checked"{/if} />2.x
+        </label>
+        <label>
+          <input type="radio" name="gd" value="1" {if $params.GD_SELECTED==1}checked="checked"{/if} />1.x
+        </label>
+      </li>
+
+      <li>
+        <span class="property">
+          <label for="width">{'maximum width'|@translate}</label>
+        </span>
+	<input type="text" id="width" name="width" value="{$params.WIDTH_TN}" />
+      </li>
+
+      <li>
+        <span class="property">
+          <label for="height">{'maximum height'|@translate}</label>
+        </span>
+	<input type="text" id="height" name="height" value="{$params.HEIGHT_TN}" />
+      </li>
+
+      <li>
+        <span class="property">{'Number of thumbnails to create'|@translate}</span>
+	<label><input type="radio" name="n" value="5"   {if $params.N_SELECTED==5}checked="checked"{/if} /> 5</label>
+	<label><input type="radio" name="n" value="10"  {if $params.N_SELECTED==10}checked="checked"{/if} /> 10</label>
+	<label><input type="radio" name="n" value="20"  {if $params.N_SELECTED==20}checked="checked"{/if} /> 20</label>
+	<label><input type="radio" name="n" value="all" {if $params.N_SELECTED=='all'}checked="checked"{/if} /> {'tn_all'|@translate}</label>
+      </li>
+    </ul>
+  </fieldset>
+
+  <p><input class="submit" type="submit" name="submit" value="{'Submit'|@translate}" {$TAG_INPUT_ENABLED}/></p>
+</form>
+{/if} {*isset params*}
+
+{if !empty($remainings) }
+<div class="admin">{$TOTAL_NB_REMAINING} {'tn_alone_title'|@translate}</div>
+<table style="width:100%;">
+  <tr class="throw">
+    <td>&nbsp;</td>
+    <td style="width:60%;">{'Path'|@translate}</td>
+    <td>{'filesize'|@translate}</td>
+    <td>{'Dimensions'|@translate}</td>
+  </tr>
+  {foreach from=$remainings item=elt name=remain_loop}
+  <tr class="{if $smarty.foreach.remain_loop.index is odd}row1{else}row2{/if}">
+    <td>{$smarty.foreach.remain_loop.iteration}</td>
+    <td><div style="margin-left:10px;">{$elt.PATH}</div></td>
+    <td><div style="margin-left:10px;">{$elt.FILESIZE_IMG}</div></td>
+    <td><div style="margin-left:10px;">{$elt.WIDTH_IMG} x {$elt.HEIGHT_IMG}</div></td>
+  </tr>
+  {/foreach}
+</table>
+{else}
+<div style="text-align:center;font-weight:bold;margin:10px;"> [ {'tn_no_missing'|@translate} ]</div>
+{/if}
Index: /tags/2.0.2/admin/template/goto/thumbnails.css
===================================================================
--- /tags/2.0.2/admin/template/goto/thumbnails.css	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/thumbnails.css	(revision 3278)
@@ -0,0 +1,37 @@
+/* $Id$ */
+.content UL.thumbnails {
+  margin: 0; padding: 0; list-style: none;
+  text-align: center;	/* to center the whole collection in .content */
+}
+.content UL.thumbnails LI { display: inline }
+.content UL.thumbnails SPAN.wrap1 {
+  margin: 0 5px 5px 5px;
+  display: table-cell; display: inline-table;
+  display: inline-block; /* Why 3 display option ??? */
+  vertical-align: top;		/* OK with Opera and IE6 not Geko */
+  text-align: center;		/* to center the thumbnail and legend in Geko/Opera */
+}
+.content UL.thumbnails SPAN.wrap2 {
+  margin: 0;			/* important reset the margins */
+  display: table-cell;		/* block prevents vertical-align here */
+  vertical-align: middle;	/* Ok with Opera and Geko not IE6 */
+}
+.content UL.thumbnails LABEL { display: block; border-bottom: none; }
+.content UL.thumbnails IMG {
+  margin-bottom: -4px;  /* why ??? something wrong with Geko and Opera ignored by IE6*/
+}
+.content UL.thumbnails LABEL { position: relative; }
+.content UL.thumbnails INPUT {
+  position: relative;	/* <= Opera can handle relative here */
+  top: -20px;
+}
+:root .content UL.thumbnails INPUT { /* hide from Opera */
+  position: absolute;	/* <= Opera hide 1 checkbox over 2 !!! */
+  left: 2px; top: 2px;
+}
+UL.thumbnails .levelIndicatorB {
+display:block; position:absolute; z-index:100;padding:0px 0 0 14px; color:black; font-weight:bold; font-size:120%;
+}
+UL.thumbnails .levelIndicatorF {
+display:block; position:absolute; z-index:101;padding:1px 0 0 15px; color:white; font-weight:bold; font-size:120%;
+}
Index: /tags/2.0.2/admin/template/goto/upgrade.tpl
===================================================================
--- /tags/2.0.2/admin/template/goto/upgrade.tpl	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/upgrade.tpl	(revision 3278)
@@ -0,0 +1,118 @@
+{* $Id$ *}
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+"http://www.w3.org/TR/html4/strict.dtd">
+<html lang="{$lang_info.code}" dir="{$lang_info.direction}">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<meta http-equiv="Content-script-type" content="text/javascript">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<link rel="shortcut icon" type="image/x-icon" href="{$ROOT_URL}template-common/favicon.ico">
+<link rel="stylesheet" type="text/css" href="{$ROOT_URL}admin/template/{$themeconf.template}/layout.css">
+<link rel="stylesheet" type="text/css" href="{$ROOT_URL}admin/template/{$themeconf.template}/default-colors.css">
+<link rel="stylesheet" type="text/css" href="{$ROOT_URL}admin/template/{$themeconf.template}/theme/{$themeconf.theme}/theme.css">
+{literal}
+<style type="text/css">
+.content {
+  width: 800px;
+  min-height: 0px !important;
+  margin: auto;
+  padding: 25px;
+  text-align: left;
+}
+
+table { margin: 0px; }
+td {  padding: 3px 10px; }
+textarea { margin-left: 20px; }
+</style>
+{/literal}
+<title>Piwigo {$RELEASE} - {'Upgrade'|@translate}</title>
+</head>
+
+<body>
+<div id="headbranch"></div> {* Dummy block for double background management *}
+<div id="the_page">
+<div id="theHeader"></div>
+<div id="content" class="content">
+
+{if isset($introduction)}
+<h2>Piwigo {$RELEASE} - {'Upgrade'|@translate}</h2>
+
+{if isset($errors)}
+<div class="errors">
+  <ul>
+    {foreach from=$errors item=error}
+    <li>{$error}</li>
+    {/foreach}
+  </ul>
+</div>
+{/if}
+
+<table>
+  <tr>
+    <td>{'language'|@translate}</td>
+    <td>
+      <select name="language" onchange="document.location = 'upgrade.php?language='+this.options[this.selectedIndex].value;">
+        {html_options options=$language_options selected=$language_selection}
+      </select>
+    </td>
+  </tr>
+</table>
+
+<p>{'introduction message'|@translate|@sprintf:$introduction.CURRENT_RELEASE}</p>
+{if isset($login)}
+<p>{'upgrade login message'|@translate}</p>
+{/if}
+
+<form method="POST" action="{$introduction.F_ACTION}" name="upgrade_form">
+{if isset($login)}
+<table>
+  <tr>
+    <td>{'Username'|@translate}</td>
+    <td><input type="text" name="username" id="username" size="25" maxlength="40" style="width: 150px;" /></td>
+  </tr>
+  <tr>
+    <td>{'Password'|@translate}</td>
+    <td><input type="password" name="password" id="password" size="25" maxlength="25" style="width: 150px;" /></td>
+  </tr>
+</table>
+{/if}
+
+<p style="text-align: center;">
+<input class="submit" type="submit" name="submit" value="{'Upgrade from %s to %s'|@translate|@sprintf:$introduction.CURRENT_RELEASE:$RELEASE}"/>
+</p>
+</form>
+<!--
+<p style="text-align: center;">
+<a href="{$introduction.RUN_UPGRADE_URL}">{'Upgrade from %s to %s'|@translate|@sprintf:$introduction.CURRENT_RELEASE:$RELEASE}</a>
+</p>
+-->
+
+{/if}
+
+{if isset($upgrade)}
+<h2>{'Upgrade from %s to %s'|@translate|@sprintf:$upgrade.VERSION:$RELEASE}</h2>
+
+<p><b>{'Statistics'|@translate}</b></p>
+<ul>
+  <li>{'total upgrade time'|@translate} : {$upgrade.TOTAL_TIME}</li>
+  <li>{'total SQL time'|@translate} : {$upgrade.SQL_TIME}</li>
+  <li>{'SQL queries'|@translate} : {$upgrade.NB_QUERIES}</li>
+</ul>
+
+<p><b>{'Upgrade informations'|@translate}</b></p>
+<ul>
+  {foreach from=$infos item=info}
+  <li>{$info}</li>
+  {/foreach}
+</ul>
+
+<form action="index.php" method="post">
+<p><input type="submit" name="submit" value="{'home'|@translate}"/></p>
+</form>
+{/if}
+
+</div> {* content *}
+<div>{$L_UPGRADE_HELP}</div>
+</div> {* the_page *}
+</body>
+</html>
Index: /tags/2.0.2/admin/template/goto/upload.tpl
===================================================================
--- /tags/2.0.2/admin/template/goto/upload.tpl	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/upload.tpl	(revision 3278)
@@ -0,0 +1,52 @@
+{* $Id$ *}
+<div class="titrePage">
+  <h2>{'waiting'|@translate} {$TABSHEET_TITLE}</h2>
+</div>
+
+<h3>{'title_upload'|@translate}</h3>
+
+<form action="{$F_ACTION}" method="post" id="waiting">
+  <table style="width:99%;" >
+    <tr class="throw">
+      <td style="width:20%;">{'category'|@translate}</td>
+      <td style="width:20%;">{'Date'|@translate}</td>
+      <td style="width:20%;">{'file'|@translate}</td>
+      <td style="width:20%;">{'thumbnail'|@translate}</td>
+      <td style="width:20%;">{'Author'|@translate}</td>
+      <td style="width:1px;">&nbsp;</td>
+    </tr>
+    
+    {if not empty($pictures) }
+    {foreach from=$pictures item=picture name=picture_loop}
+    <tr class="{if $smarty.foreach.picture_loop.index is odd}row1{else}row2{/if}">
+      <td style="white-space:nowrap;">{$picture.CATEGORY_IMG}</td>
+      <td style="white-space:nowrap;">{$picture.DATE_IMG}</td>
+      <td style="white-space:nowrap;">
+        <a href="{$picture.PREVIEW_URL_IMG}" title="{$picture.FILE_TITLE}">{$picture.FILE_IMG}</a>
+      </td>
+      <td style="white-space:nowrap;">
+        {if not empty($picture.thumbnail) }
+        <a href="{$picture.thumbnail.PREVIEW_URL_TN_IMG}" title="{$picture.thumbnail.FILE_TN_TITLE}">{$picture.thumbnail.FILE_TN_IMG}</a>
+        {/if}
+      </td>
+      <td style="white-space:nowrap;">
+        <a href="mailto:{$picture.UPLOAD_EMAIL}">{$picture.UPLOAD_USERNAME}</a>
+      </td>
+      <td style="white-space:nowrap;">
+        <label><input type="radio" name="action-{$picture.ID_IMG}" value="validate" /> {'Validate'|@translate}</label>
+        <label><input type="radio" name="action-{$picture.ID_IMG}" value="reject" /> {'Reject'|@translate}</label>
+      </td>
+    </tr>
+    {/foreach}
+    {/if}
+  </table>
+
+  <p class="bottomButtons">
+    <input type="hidden" name="list" value="{$LIST}" />
+    <input class="submit" type="submit" name="submit" value="{'Submit'|@translate}" {$TAG_INPUT_ENABLED}/>
+    <input class="submit" type="submit" name="validate-all" value="{'Validate All'|@translate}" {$TAG_INPUT_ENABLED}/>
+    <input class="submit" type="submit" name="reject-all" value="{'Reject All'|@translate}" {$TAG_INPUT_ENABLED}/>
+    <input class="submit" type="reset" value="{'Reset'|@translate}" />
+  </p>
+
+</form>
Index: /tags/2.0.2/admin/template/goto/user_list.tpl
===================================================================
--- /tags/2.0.2/admin/template/goto/user_list.tpl	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/user_list.tpl	(revision 3278)
@@ -0,0 +1,330 @@
+{* $Id$ *}
+<div class="titrePage">
+  <h2>{'title_liste_users'|@translate}</h2>
+</div>
+
+<form class="filter" method="post" name="add_user" action="{$F_ADD_ACTION}">
+  <fieldset>
+    <legend>{'Add a user'|@translate}</legend>
+    <label>{'Username'|@translate} <input type="text" name="login" maxlength="50" size="20" /></label>
+    <label>{'Password'|@translate} <input type="text" name="password" /></label>
+    <label>{'Email address'|@translate} <input type="text" name="email" /></label>
+    <label>&nbsp; <input class="submit" type="submit" name="submit_add" value="{'Submit'|@translate}" {$TAG_INPUT_ENABLED} /></label>
+  </fieldset>
+</form>
+
+<form class="filter" method="get" name="filter" action="{$F_FILTER_ACTION}">
+<fieldset>
+  <legend>{'Filter'|@translate}</legend>
+  <input type="hidden" name="page" value="user_list" />
+
+  <label>{'Username'|@translate} <input type="text" name="username" value="{$F_USERNAME}" /></label>
+
+  <label>
+  {'status'|@translate}
+  {html_options name=status options=$status_options selected=$status_selected}
+  </label>
+
+  <label>
+  {'group'|@translate}
+  {html_options name=group options=$group_options selected=$group_selected}
+  </label>
+
+  <label>
+  {'Sort by'|@translate}
+  {html_options name=order_by options=$order_options selected=$order_selected}
+  </label>
+
+  <label>
+  {'Sort order'|@translate}
+  {html_options name=direction options=$direction_options selected=$direction_selected}
+  </label>
+
+  <label>
+  &nbsp;
+  <input class="submit" type="submit" value="{'Submit'|@translate}" />
+  </label>
+
+</fieldset>
+
+</form>
+
+<form method="post" name="preferences" action="">
+
+<table class="table2" width="97%">
+  <thead>
+    <tr class="throw">
+      <td>&nbsp;</td>
+      <td>{'Username'|@translate}</td>
+      <td>{'user_status'|@translate}</td>
+      <td>{'Email address'|@translate}</td>
+      <td>{'Groups'|@translate}</td>
+      <td>{'properties'|@translate}</td>
+      {if not empty($plugin_user_list_column_titles)}
+      {foreach from=$plugin_user_list_column_titles item=title}
+      <td>{$title}</td>
+      {/foreach}
+      {/if}
+      <td>{'Actions'|@translate}</td>
+    </tr>
+  </thead>
+
+  {foreach from=$users item=user name=users_loop}
+  <tr class="{if $smarty.foreach.users_loop.index is odd}row1{else}row2{/if}">
+    <td><input type="checkbox" name="selection[]" value="{$user.ID}" {$user.CHECKED} id="selection-{$user.ID}" /></td>
+    <td><label for="selection-{$user.ID}">{$user.USERNAME}</label></td>
+    <td>{$user.STATUS}</td>
+    <td>{$user.EMAIL}</td>
+    <td>{$user.GROUPS}</td>
+    <td>{$user.PROPERTIES}</td>
+    {foreach from=$user.plugin_columns item=data}
+    <td>{$data}</td>
+    {/foreach}
+    <td style="text-align:center;">
+      <a href="{$user.U_PERM}"><img src="{$ROOT_URL}{$themeconf.admin_icon_dir}/permissions.png" class="button" style="border:none" alt="{'permissions'|@translate}" title="{'permissions'|@translate}" /></a>
+      <a href="{$user.U_PROFILE}"><img src="{$ROOT_URL}{$themeconf.admin_icon_dir}/edit_s.png" class="button" style="border:none" alt="{'Profile'|@translate}" title="{'Profile'|@translate}" /></a>
+      {foreach from=$user.plugin_actions item=data}
+      {$data}
+      {/foreach}
+      </td>
+  </tr>
+  {/foreach}
+</table>
+
+<div class="navigationBar">{$NAVBAR}</div>
+
+{* delete the selected users ? *}
+<fieldset>
+  <legend>{'Deletions'|@translate}</legend>
+  <label><input type="checkbox" name="confirm_deletion" value="1" /> {'confirm'|@translate}</label>
+  <input class="submit" type="submit" value="{'Delete selected users'|@translate}" name="delete" {$TAG_INPUT_ENABLED}/>
+</fieldset>
+
+<fieldset>
+  <legend>{'Status'|@translate}</legend>
+
+  <table>
+    <tr>
+      <td>{'Status'|@translate}</td>
+      <td>
+        <label><input type="radio" name="status_action" value="leave" checked="checked" /> {'leave'|@translate}</label>
+        <label><input type="radio" name="status_action" value="set" id="status_action_set" /> {'set to'|@translate}</label>
+        <select onchange="document.getElementById('status_action_set').checked = true;" name="status" size="1">
+          {html_options options=$pref_status_options selected=$pref_status_selected}
+        </select>
+      </td>
+    </tr>
+
+    {if isset($adviser)}
+    <tr>
+      <td>{'adviser'|@translate}</td>
+      <td>
+        <label><input type="radio" name="adviser" value="leave" checked="checked" /> {'leave'|@translate}</label>
+        / {'set to'|@translate}
+        <label><input type="radio" name="adviser" value="true"  />{'Yes'|@translate}</label>
+        <label><input type="radio" name="adviser" value="false" />{'No'|@translate}</label>
+      </td>
+    </tr>
+    {/if}
+
+  </table>
+</fieldset>
+
+{* form to set properties for many users at once *}
+<fieldset>
+  <legend>{'Groups'|@translate}</legend>
+
+<table>
+
+  <tr>
+    <td>{'associate to group'|@translate}</td>
+    <td>
+      {html_options name=associate options=$association_options selected=$associate_selected}
+    </td>
+  </tr>
+
+  <tr>
+    <td>{'dissociate from group'|@translate}</td>
+    <td>
+      {html_options name=dissociate options=$association_options selected=$dissociate_selected}
+    </td>
+  </tr>
+
+</table>
+
+</fieldset>
+
+{* Properties *}
+<fieldset>
+  <legend>{'properties'|@translate}</legend>
+
+  <table>
+
+    <tr>
+      <td>{'enabled_high'|@translate}</td>
+      <td>
+        <label><input type="radio" name="enabled_high" value="leave" checked="checked" /> {'leave'|@translate}</label>
+        / {'set to'|@translate}
+        <label><input type="radio" name="enabled_high" value="true"  />{'Yes'|@translate}</label>
+        <label><input type="radio" name="enabled_high" value="false" />{'No'|@translate}</label>
+      </td>
+    </tr>
+
+	<tr>
+		<td>{'Privacy level'|@translate}</td>
+		<td>
+			<label><input type="radio" name="level_action" value="leave" checked="checked" />{'leave'|@translate}</label>
+			<label><input type="radio" name="level_action" value="set" id="level_action_set" />{'set to'|@translate}</label>
+			<select onchange="document.getElementById('level_action_set').checked = true;" name="level" size="1">
+			  {html_options options=$level_options selected=$level_selected}
+			</select>
+	  </td>
+	</tr>
+
+  </table>
+
+</fieldset>
+
+{* preference *}
+<fieldset>
+  <legend>{'Preferences'|@translate}</legend>
+
+<table>
+
+  <tr>
+    <td>{'nb_image_per_row'|@translate}</td>
+    <td>
+      <label><input type="radio" name="nb_image_line_action" value="leave" checked="checked" /> {'leave'|@translate}</label>
+      <label><input type="radio" name="nb_image_line_action" value="set" id="nb_image_line_action_set"  /> {'set to'|@translate}</label>
+      <input onmousedown="document.getElementById('nb_image_line_action_set').checked = true;"
+             size="3" maxlength="2" type="text" name="nb_image_line" value="{$NB_IMAGE_LINE}" />
+    </td>
+  </tr>
+
+  <tr>
+    <td>{'nb_row_per_page'|@translate}</td>
+    <td>
+      <label><input type="radio" name="nb_line_page_action" value="leave" checked="checked" /> {'leave'|@translate}</label>
+      <label><input type="radio" name="nb_line_page_action" value="set" id="nb_line_page_action_set" /> {'set to'|@translate}</label>
+      <input onmousedown="document.getElementById('nb_line_page_action_set').checked = true;"
+             size="3" maxlength="2" type="text" name="nb_line_page" value="{$NB_LINE_PAGE}" />
+    <td>
+  </tr>
+
+  <tr>
+    <td>{'theme'|@translate}</td>
+    <td>
+      <label><input type="radio" name="template_action" value="leave" checked="checked" /> {'leave'|@translate}</label>
+      <label><input type="radio" name="template_action" value="set" id="template_action_set" /> {'set to'|@translate}</label>
+      <select onchange="document.getElementById('template_action_set').checked = true;" name="template" size="1">
+        {html_options values=$template_options output=$template_options selected=$template_selected}
+      </select>
+    </td>
+  </tr>
+
+  <tr>
+    <td>{'language'|@translate}</td>
+    <td>
+      <label><input type="radio" name="language_action" value="leave" checked="checked" /> {'leave'|@translate}</label>
+      <label><input type="radio" name="language_action" value="set" id="language_action_set" /> {'set to'|@translate}</label>
+      <select onchange="document.getElementById('language_action_set').checked = true;" name="language" size="1">
+        {html_options options=$language_options selected=$language_selected}
+      </select>
+    </td>
+  </tr>
+
+  <tr>
+    <td>{'recent_period'|@translate}</td>
+    <td>
+      <label><input type="radio" name="recent_period_action" value="leave" checked="checked" /> {'leave'|@translate}</label>
+      <label><input type="radio" name="recent_period_action" value="set" id="recent_period_action_set"  /> {'set to'|@translate}</label>
+      <input onmousedown="document.getElementById('recent_period_action_set').checked = true;"
+             type="text" size="3" maxlength="2" name="recent_period" value="{$RECENT_PERIOD}" />
+    </td>
+  </tr>
+
+  <tr>
+    <td>{'auto_expand'|@translate}</td>
+    <td>
+      <label><input type="radio" name="expand" value="leave" checked="checked" /> {'leave'|@translate}</label>
+      / {'set to'|@translate}
+      <label><input type="radio" name="expand" value="true"  />{'Yes'|@translate}</label>
+      <label><input type="radio" name="expand" value="false" />{'No'|@translate}</label>
+    </td>
+  </tr>
+
+  <tr>
+    <td>{'show_nb_comments'|@translate}</td>
+    <td>
+      <label><input type="radio" name="show_nb_comments" value="leave" checked="checked" /> {'leave'|@translate}</label>
+      / {'set to'|@translate}
+      <label><input type="radio" name="show_nb_comments" value="true" />{'Yes'|@translate}</label>
+      <label><input type="radio" name="show_nb_comments" value="false" />{'No'|@translate}</label>
+    </td>
+  </tr>
+
+  <tr>
+    <td>{'show_nb_hits'|@translate}</td>
+    <td>
+      <label><input type="radio" name="show_nb_hits" value="leave" checked="checked" /> {'leave'|@translate}</label>
+      / {'set to'|@translate}
+      <label><input type="radio" name="show_nb_hits" value="true" />{'Yes'|@translate}</label>
+      <label><input type="radio" name="show_nb_hits" value="false" />{'No'|@translate}</label>
+    </td>
+  </tr>
+
+  <tr>
+    <td>{'maxwidth'|@translate}</td>
+    <td>
+      <label><input type="radio" name="maxwidth_action" value="leave" checked="checked" /> {'leave'|@translate}</label>
+      <label><input type="radio" name="maxwidth_action" value="unset" /> {'unset'|@translate}</label>
+      <label><input type="radio" name="maxwidth_action" value="set" id="maxwidth_action_set" /> {'set to'|@translate}</label>
+      <input onmousedown="document.getElementById('maxwidth_action_set').checked = true;"
+             type="text" size="4" maxlength="4" name="maxwidth" value="{$MAXWIDTH}" />
+    </td>
+  </tr>
+
+
+  <tr>
+    <td>{'maxheight'|@translate}</td>
+    <td>
+      <label><input type="radio" name="maxheight_action" value="leave" checked="checked" /> {'leave'|@translate}</label>
+      <label><input type="radio" name="maxheight_action" value="unset" /> {'unset'|@translate}</label>
+      <label><input type="radio" name="maxheight_action" value="set" id="maxheight_action_set" /> {'set to'|@translate}</label>
+      <input onmousedown="document.getElementById('maxheight_action_set').checked = true;"
+             type="text" size="4" maxlength="4" name="maxheight" value="{$MAXHEIGHT}" />
+    </td>
+  </tr>
+
+
+</table>
+
+</fieldset>
+
+<p>
+  {'target'|@translate}
+  <label><input type="radio" name="target" value="all" /> {'all'|@translate}</label>
+  <label><input type="radio" name="target" value="selection" checked="checked" /> {'selection'|@translate}</label>
+</p>
+
+<p>
+  <input class="submit" type="submit" value="{'Submit'|@translate}" name="pref_submit" {$TAG_INPUT_ENABLED} />
+  <input class="submit" type="reset" value="{'Reset'|@translate}" name="pref_reset" />
+</p>
+
+</form>
+
+<script type="text/javascript">// <![CDATA[{literal}
+jQuery("form:last").submit( function() {
+	if ( jQuery("input[name=target][value=selection]:checked", this).length > 0 )
+	if ( jQuery("input[name='selection[]']:checked", this).length == 0)
+	{
+		alert( {/literal}"{'Select at least one user'|@translate|escape:javascript}"{literal} );
+		return false;
+	}
+	return true;
+}
+);{/literal}
+// ]]>
+</script>
+ 
Index: /tags/2.0.2/admin/template/goto/user_perm.tpl
===================================================================
--- /tags/2.0.2/admin/template/goto/user_perm.tpl	(revision 3278)
+++ /tags/2.0.2/admin/template/goto/user_perm.tpl	(revision 3278)
@@ -0,0 +1,23 @@
+{* $Id$ *}
+<h2>{$TITLE}</h2>
+
+{if isset($categories_because_of_groups) }
+<fieldset>
+  <legend>{'Categories authorized thanks to group associations'|@translate}</legend>
+
+  <ul>
+    {foreach from=$categories_because_of_groups item=cat }
+    <li>{$cat}</li>
+    {/foreach}
+  </ul>
+</fieldset>
+{/if}
+
+
+<fieldset>
+  <legend>{'Other private categories'|@translate}</legend>
+
+  <form method="post" action="{$F_ACTION}">
+    {$DOUBLE_SELECT}
+  </form>
+</fieldset>
Index: /tags/2.0.2/admin/thumbnail.php
===================================================================
--- /tags/2.0.2/admin/thumbnail.php	(revision 3278)
+++ /tags/2.0.2/admin/thumbnail.php	(revision 3278)
@@ -0,0 +1,358 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+
+// +-----------------------------------------------------------------------+
+// | Check Access and exit when user status is not ok                      |
+// +-----------------------------------------------------------------------+
+check_status(ACCESS_ADMINISTRATOR);
+
+//------------------------------------------------------------------- functions
+// RatioResizeImg creates a new picture (a thumbnail since it is supposed to
+// be smaller than original picture !) in the sub directory named
+// "thumbnail".
+function RatioResizeImg($path, $newWidth, $newHeight, $tn_ext)
+{
+  global $conf, $lang, $page;
+
+  if (!function_exists('gd_info'))
+  {
+    return;
+  }
+
+  $filename = basename($path);
+  $dirname = dirname($path);
+  
+  // extension of the picture filename
+  $extension = get_extension($filename);
+
+  if (in_array($extension, array('jpg', 'JPG', 'jpeg', 'JPEG')))
+  {
+    $srcImage = @imagecreatefromjpeg($path);
+  }
+  else if ($extension == 'png' or $extension == 'PNG')
+  {
+    $srcImage = @imagecreatefrompng($path);
+  }
+  else
+  {
+    unset($extension);
+  }
+
+  if ( isset( $srcImage ) )
+  {
+    // width/height
+    $srcWidth    = imagesx( $srcImage ); 
+    $srcHeight   = imagesy( $srcImage ); 
+    $ratioWidth  = $srcWidth/$newWidth;
+    $ratioHeight = $srcHeight/$newHeight;
+
+    // maximal size exceeded ?
+    if ( ( $ratioWidth > 1 ) or ( $ratioHeight > 1 ) )
+    {
+      if ( $ratioWidth < $ratioHeight)
+      { 
+        $destWidth = $srcWidth/$ratioHeight;
+        $destHeight = $newHeight; 
+      }
+      else
+      { 
+        $destWidth = $newWidth; 
+        $destHeight = $srcHeight/$ratioWidth;
+      }
+    }
+    else
+    {
+      $destWidth = $srcWidth;
+      $destHeight = $srcHeight;
+    }
+    // according to the GD version installed on the server
+    if ( $_POST['gd'] == 2 )
+    {
+      // GD 2.0 or more recent -> good results (but slower)
+      $destImage = imagecreatetruecolor( $destWidth, $destHeight); 
+      imagecopyresampled( $destImage, $srcImage, 0, 0, 0, 0,
+                          $destWidth,$destHeight,$srcWidth,$srcHeight );
+    }
+    else
+    {
+      // GD prior to version  2 -> pretty bad results :-/ (but fast)
+      $destImage = imagecreate( $destWidth, $destHeight);
+      imagecopyresized( $destImage, $srcImage, 0, 0, 0, 0,
+                        $destWidth,$destHeight,$srcWidth,$srcHeight );
+    }
+
+    if (($tndir = mkget_thumbnail_dir($dirname, $page['errors'])) == false)
+    {
+      return false;
+    }
+
+    $dest_file = $tndir.'/'.$conf['prefix_thumbnail'];
+    $dest_file.= get_filename_wo_extension($filename);
+    $dest_file.= '.'.$tn_ext;
+    
+    // creation and backup of final picture
+    if (!is_writable($tndir))
+    {
+      array_push($page['errors'], '['.$tndir.'] : '.l10n('no_write_access'));
+      return false;
+    }
+    imagejpeg($destImage, $dest_file, $conf['tn_compression_level']);
+    // freeing memory ressources
+    imagedestroy( $srcImage );
+    imagedestroy( $destImage );
+    
+    list($tn_width, $tn_height) = getimagesize($dest_file);
+    $tn_size = floor(filesize($dest_file) / 1024).' KB';
+    
+    $info = array( 'path'      => $path,
+                   'tn_file'   => $dest_file,
+                   'tn_width'  => $tn_width,
+                   'tn_height' => $tn_height,
+                   'tn_size'   => $tn_size );
+    return $info;
+  }
+  // error
+  else
+  {
+    echo l10n('tn_no_support')." ";
+    if ( isset( $extenstion ) )
+    {
+      echo l10n('tn_format').' '.$extension;
+    }
+    else
+    {
+      echo l10n('tn_thisformat');
+    }
+    exit();
+  }
+}
+
+$pictures = array();
+$stats = array();
+
+if (!function_exists('gd_info'))
+{
+  array_push($page['errors'], l10n('GD library is missing'));
+}
+
+// +-----------------------------------------------------------------------+
+// |                       template initialization                         |
+// +-----------------------------------------------------------------------+
+$template->set_filenames( array('thumbnail'=>'thumbnail.tpl') );
+
+$template->assign(array(
+  'U_HELP' => PHPWG_ROOT_PATH.'popuphelp.php?page=thumbnail',
+  ));
+// +-----------------------------------------------------------------------+
+// |                   search pictures without thumbnails                  |
+// +-----------------------------------------------------------------------+
+$wo_thumbnails = array();
+$thumbnalized = array();
+
+
+// what is the directory to search in ?
+$query = '
+SELECT galleries_url FROM '.SITES_TABLE.'
+  WHERE galleries_url NOT LIKE "http://%"
+;';
+$result = pwg_query($query);
+while ( $row=mysql_fetch_assoc($result) )
+{
+  $basedir = preg_replace('#/*$#', '', $row['galleries_url']);
+  $fs = get_fs($basedir);
+
+  // because isset is one hundred time faster than in_array
+  $fs['thumbnails'] = array_flip($fs['thumbnails']);
+
+  foreach ($fs['elements'] as $path)
+  {
+    // only pictures need thumbnails
+    if (in_array(get_extension($path), $conf['picture_ext']))
+    {
+      $dirname = dirname($path);
+      $filename = basename($path);
+  
+      // only files matching the authorized filename pattern can be considered
+      // as "without thumbnail"
+      if (!preg_match('/^[a-zA-Z0-9-_.]+$/', $filename))
+      {
+        continue;
+      }
+      
+      // searching the element
+      $filename_wo_ext = get_filename_wo_extension($filename);
+      $tn_ext = '';
+      $base_test = $dirname.'/thumbnail/';
+      $base_test.= $conf['prefix_thumbnail'].$filename_wo_ext.'.';
+      foreach ($conf['picture_ext'] as $ext)
+      {
+        if (isset($fs['thumbnails'][$base_test.$ext]))
+        {
+          $tn_ext = $ext;
+          break;
+        }
+      }
+      
+      if (empty($tn_ext))
+      {
+        array_push($wo_thumbnails, $path);
+      }
+    }
+  } // next element
+} // next site id
+// +-----------------------------------------------------------------------+
+// |                         thumbnails creation                           |
+// +-----------------------------------------------------------------------+
+if (isset($_POST['submit']))
+{
+  $times = array();
+  $infos = array();
+  
+  // checking criteria
+  if (!ereg('^[0-9]{2,3}$', $_POST['width']) or $_POST['width'] < 10)
+  {
+    array_push($page['errors'], l10n('tn_err_width').' 10');
+  }
+  if (!ereg('^[0-9]{2,3}$', $_POST['height']) or $_POST['height'] < 10)
+  {
+    array_push($page['errors'], l10n('tn_err_height').' 10');
+  }
+  
+  // picture miniaturization
+  if (count($page['errors']) == 0)
+  {
+    $num = 1;
+    foreach ($wo_thumbnails as $path)
+    {
+      if (is_numeric($_POST['n']) and $num > $_POST['n'])
+      {
+        break;
+      }
+      
+      $starttime = get_moment();
+      if ($info = RatioResizeImg($path,$_POST['width'],$_POST['height'],'jpg'))
+      {
+        $endtime = get_moment();
+        $info['time'] = ($endtime - $starttime) * 1000;
+        array_push($infos, $info);
+        array_push($times, $info['time']);
+        array_push($thumbnalized, $path);
+        $num++;
+      }
+      else
+      {
+        break;
+      }
+    }
+
+    if (count($infos) > 0)
+    {
+      $sum = array_sum($times);
+      $average = $sum / count($times);
+      sort($times, SORT_NUMERIC);
+      $max = array_pop($times);
+      if (count($thumbnalized) == 1)
+      {
+        $min = $max;
+      }
+      else
+      {
+        $min = array_shift($times);
+      }
+      
+      $tpl_var = 
+        array(
+          'TN_NB'=>count($infos),
+          'TN_TOTAL'=>number_format($sum, 2, '.', ' ').' ms',
+          'TN_MAX'=>number_format($max, 2, '.', ' ').' ms',
+          'TN_MIN'=>number_format($min, 2, '.', ' ').' ms',
+          'TN_AVERAGE'=>number_format($average, 2, '.', ' ').' ms',
+          'elements' => array()
+          );
+      
+      foreach ($infos as $i => $info)
+      {
+        $tpl_var['elements'][] =
+          array(
+            'PATH'=>$info['path'],
+            'TN_FILE_IMG'=>$info['tn_file'],
+            'TN_FILESIZE_IMG'=>$info['tn_size'],
+            'TN_WIDTH_IMG'=>$info['tn_width'],
+            'TN_HEIGHT_IMG'=>$info['tn_height'],
+            'GEN_TIME'=>number_format($info['time'], 2, '.', ' ').' ms',
+            );
+      }
+      $template->assign('results', $tpl_var);
+    }
+  }
+}
+// +-----------------------------------------------------------------------+
+// |             form & pictures without thumbnails display                |
+// +-----------------------------------------------------------------------+
+$remainings = array_diff($wo_thumbnails, $thumbnalized);
+
+if (count($remainings) > 0)
+{
+  $form_url = get_root_url().'admin.php?page=thumbnail';
+  $gd = !empty($_POST['gd']) ? $_POST['gd'] : 2;
+  $width = !empty($_POST['width']) ? $_POST['width'] : $conf['tn_width'];
+  $height = !empty($_POST['height']) ? $_POST['height'] : $conf['tn_height'];
+  $n = !empty($_POST['n']) ? $_POST['n'] : 5;
+  
+  $template->assign(
+    'params',
+    array(
+      'F_ACTION'=> $form_url,
+      'GD_SELECTED' => $gd,
+      'N_SELECTED' => $n,
+      'WIDTH_TN'=>$width,
+      'HEIGHT_TN'=>$height
+      ));
+
+  $template->assign(
+    'TOTAL_NB_REMAINING',
+    count($remainings));
+
+  foreach ($remainings as $path)
+  {
+    list($width, $height) = getimagesize($path);
+    $size = floor(filesize($path) / 1024).' KB';
+
+    $template->append(
+      'remainings',
+      array(
+        'PATH'=>$path,
+        'FILESIZE_IMG'=>$size,
+        'WIDTH_IMG'=>$width,
+        'HEIGHT_IMG'=>$height,
+        ));
+  }
+}
+
+// +-----------------------------------------------------------------------+
+// |                           return to admin                             |
+// +-----------------------------------------------------------------------+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'thumbnail');
+?>
Index: /tags/2.0.2/admin/upload.php
===================================================================
--- /tags/2.0.2/admin/upload.php	(revision 3278)
+++ /tags/2.0.2/admin/upload.php	(revision 3278)
@@ -0,0 +1,209 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if( !defined("PHPWG_ROOT_PATH") )
+{
+  die ("Hacking attempt!");
+}
+
+include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+include_once(PHPWG_ROOT_PATH.'admin/include/functions_waiting.inc.php');
+
+// +-----------------------------------------------------------------------+
+// | Check Access and exit when user status is not ok                      |
+// +-----------------------------------------------------------------------+
+check_status(ACCESS_ADMINISTRATOR);
+
+//--------------------------------------------------------------------- updates
+
+if (isset($_POST))
+{
+  $to_validate = array();
+  $to_reject = array();
+
+  if (isset($_POST['submit']))
+  {
+    foreach (explode(',', $_POST['list']) as $waiting_id)
+    {
+      if (isset($_POST['action-'.$waiting_id]))
+      {
+        switch ($_POST['action-'.$waiting_id])
+        {
+          case 'reject' :
+          {
+            array_push($to_reject, $waiting_id);
+            break;
+          }
+          case 'validate' :
+          {
+            array_push($to_validate, $waiting_id);
+            break;
+          }
+        }
+      }
+    }
+  }
+  elseif (isset($_POST['validate-all']) and !empty($_POST['list']))
+  {
+    $to_validate = explode(',', $_POST['list']);
+  }
+  elseif (isset($_POST['reject-all']) and !empty($_POST['list']))
+  {
+    $to_reject = explode(',', $_POST['list']);
+  }
+
+  if (count($to_validate) > 0)
+  {
+    $query = '
+UPDATE '.WAITING_TABLE.'
+  SET validated = \'true\'
+  WHERE id IN ('.implode(',', $to_validate).')
+;';
+    pwg_query($query);
+
+    array_push(
+      $page['infos'],
+      sprintf(
+        l10n('%d waiting pictures validated'),
+        count($to_validate)
+        )
+      );
+  }
+
+  if (count($to_reject) > 0)
+  {
+    // The uploaded element was refused, we have to delete its reference in
+    // the database and to delete the element as well.
+    $query = '
+SELECT id, storage_category_id, file, tn_ext
+  FROM '.WAITING_TABLE.'
+  WHERE id IN ('.implode(',', $to_reject).')
+;';
+    $result = pwg_query($query);
+    while($row = mysql_fetch_array($result))
+    {
+      $dir = get_complete_dir($row['storage_category_id']);
+      unlink($dir.$row['file']);
+      $element_info = array(
+        'path' => $dir.$row['file'],
+        'tn_ext' =>
+          (isset($row['tn_ext']) and $row['tn_ext']!='') ? $row['tn_ext']:'jpg'
+        );
+      $tn_path = get_thumbnail_path( $element_info );
+
+      if ( @is_file($tn_path) )
+      {
+        unlink( $tn_path );
+      }
+    }
+
+    $query = '
+DELETE
+  FROM '.WAITING_TABLE.'
+  WHERE id IN ('.implode(',', $to_reject).')
+;';
+    pwg_query($query);
+
+    array_push(
+      $page['infos'],
+      sprintf(
+        l10n('%d waiting pictures rejected'),
+        count($to_reject)
+        )
+      );
+  }
+}
+
+//----------------------------------------------------- template initialization
+$template->set_filenames(array('upload'=>'upload.tpl'));
+
+// TabSheet initialization
+waiting_tabsheet();
+
+$template->assign(array(
+  'F_ACTION'=>str_replace( '&', '&amp;', $_SERVER['REQUEST_URI'])
+  ));
+
+//---------------------------------------------------------------- form display
+$cat_names = array();
+$list = array();
+
+$query = 'SELECT * FROM '.WAITING_TABLE;
+$query.= " WHERE validated = 'false'";
+$query.= ' ORDER BY storage_category_id';
+$query.= ';';
+$result = pwg_query( $query );
+while ( $row = mysql_fetch_array( $result ) )
+{
+  if ( !isset( $cat_names[$row['storage_category_id']] ) )
+  {
+    $cat = get_cat_info( $row['storage_category_id'] );
+    $cat_names[$row['storage_category_id']] = array();
+    $cat_names[$row['storage_category_id']]['dir'] =
+      PHPWG_ROOT_PATH.get_complete_dir( $row['storage_category_id'] );
+    $cat_names[$row['storage_category_id']]['display_name'] =
+      get_cat_display_name($cat['upper_names']);
+  }
+  $preview_url = PHPWG_ROOT_PATH.$cat_names[$row['storage_category_id']]['dir'].$row['file'];
+
+  $tpl_var =
+    array(
+      'CATEGORY_IMG'=>$cat_names[$row['storage_category_id']]['display_name'],
+      'ID_IMG'=>$row['id'],
+      'DATE_IMG' => date('Y-m-d H:i:s', $row['date']),
+      'FILE_TITLE'=>$row['file'],
+      'FILE_IMG' =>
+        (strlen($row['file']) > 10) ?
+          (substr($row['file'], 0, 10)).'...' : $row['file'],
+      'PREVIEW_URL_IMG'=>$preview_url,
+      'UPLOAD_EMAIL'=>get_email_address_as_display_text($row['mail_address']),
+      'UPLOAD_USERNAME'=>$row['username']
+    );
+
+  // is there an existing associated thumnail ?
+  if ( !empty( $row['tn_ext'] ))
+  {
+    $thumbnail = $conf['prefix_thumbnail'];
+    $thumbnail.= get_filename_wo_extension( $row['file'] );
+    $thumbnail.= '.'.$row['tn_ext'];
+	$url = $cat_names[$row['storage_category_id']]['dir'];
+    $url.= 'thumbnail/'.$thumbnail;
+
+    $tpl_var['thumbnail'] =
+      array(
+        'PREVIEW_URL_TN_IMG' => $url,
+        'FILE_TN_IMG' =>
+          (strlen($thumbnail) > 10) ?
+            (substr($thumbnail, 0, 10)).'...' : $thumbnail,
+        'FILE_TN_TITLE' => $thumbnail
+      );
+  }
+  $template->append('pictures', $tpl_var);
+  array_push($list, $row['id']);
+}
+
+$template->assign('LIST',implode(',', $list) );
+
+//----------------------------------------------------------- sending html code
+$template->assign_var_from_handle('ADMIN_CONTENT', 'upload');
+?>
Index: /tags/2.0.2/admin/user_list.php
===================================================================
--- /tags/2.0.2/admin/user_list.php	(revision 3278)
+++ /tags/2.0.2/admin/user_list.php	(revision 3278)
@@ -0,0 +1,681 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+/**
+ * Add users and manage users list
+ */
+
+// +-----------------------------------------------------------------------+
+// |                              functions                                |
+// +-----------------------------------------------------------------------+
+
+/**
+ * returns a list of users depending on page filters (in $_GET)
+ *
+ * Each user comes with his related informations : id, username, mail
+ * address, list of groups.
+ *
+ * @return array
+ */
+function get_filtered_user_list()
+{
+  global $conf, $page;
+
+  $users = array();
+
+  // filter
+  $filter = array();
+
+  if (isset($_GET['username']) and !empty($_GET['username']))
+  {
+    $username = str_replace('*', '%', $_GET['username']);
+    $filter['username'] = mysql_real_escape_string($username);
+  }
+
+  if (isset($_GET['group'])
+      and -1 != $_GET['group']
+      and is_numeric($_GET['group']))
+  {
+    $filter['group'] = $_GET['group'];
+  }
+
+  if (isset($_GET['status'])
+      and in_array($_GET['status'], get_enums(USER_INFOS_TABLE, 'status')))
+  {
+    $filter['status'] = $_GET['status'];
+  }
+
+  // how to order the list?
+  $order_by = 'id';
+  if (isset($_GET['order_by'])
+      and in_array($_GET['order_by'], array_keys($page['order_by_items'])))
+  {
+    $order_by = $_GET['order_by'];
+  }
+
+  $direction = 'ASC';
+  if (isset($_GET['direction'])
+      and in_array($_GET['direction'], array_keys($page['direction_items'])))
+  {
+    $direction = strtoupper($_GET['direction']);
+  }
+
+  // search users depending on filters and order
+  $query = '
+SELECT DISTINCT u.'.$conf['user_fields']['id'].' AS id,
+                u.'.$conf['user_fields']['username'].' AS username,
+                u.'.$conf['user_fields']['email'].' AS email,
+                ui.status,
+                ui.adviser,
+                ui.enabled_high,
+                ui.level
+  FROM '.USERS_TABLE.' AS u
+    INNER JOIN '.USER_INFOS_TABLE.' AS ui
+      ON u.'.$conf['user_fields']['id'].' = ui.user_id
+    LEFT JOIN '.USER_GROUP_TABLE.' AS ug
+      ON u.'.$conf['user_fields']['id'].' = ug.user_id
+  WHERE u.'.$conf['user_fields']['id'].' > 0';
+  if (isset($filter['username']))
+  {
+    $query.= '
+  AND u.'.$conf['user_fields']['username'].' LIKE \''.$filter['username'].'\'';
+  }
+  if (isset($filter['group']))
+  {
+    $query.= '
+    AND ug.group_id = '.$filter['group'];
+  }
+  if (isset($filter['status']))
+  {
+    $query.= '
+    AND ui.status = \''.$filter['status']."'";
+  }
+  $query.= '
+  ORDER BY '.$order_by.' '.$direction.'
+;';
+
+  $result = pwg_query($query);
+  while ($row = mysql_fetch_array($result))
+  {
+    $user = $row;
+    $user['groups'] = array();
+
+    array_push($users, $user);
+  }
+
+  // add group lists
+  $user_ids = array();
+  foreach ($users as $i => $user)
+  {
+    $user_ids[$i] = $user['id'];
+  }
+  $user_nums = array_flip($user_ids);
+
+  if (count($user_ids) > 0)
+  {
+    $query = '
+SELECT user_id, group_id
+  FROM '.USER_GROUP_TABLE.'
+  WHERE user_id IN ('.implode(',', $user_ids).')
+;';
+    $result = pwg_query($query);
+    while ($row = mysql_fetch_array($result))
+    {
+      array_push(
+        $users[$user_nums[$row['user_id']]]['groups'],
+        $row['group_id']
+        );
+    }
+  }
+
+  return $users;
+}
+
+// +-----------------------------------------------------------------------+
+// |                           initialization                              |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+
+// +-----------------------------------------------------------------------+
+// | Check Access and exit when user status is not ok                      |
+// +-----------------------------------------------------------------------+
+check_status(ACCESS_ADMINISTRATOR);
+
+$page['order_by_items'] = array(
+  'id' => l10n('registration_date'),
+  'username' => l10n('Username'),
+  'level' => l10n('Privacy level'),
+  'language' => l10n('language'),
+  );
+
+$page['direction_items'] = array(
+  'asc' => l10n('ascending'),
+  'desc' => l10n('descending')
+  );
+
+// +-----------------------------------------------------------------------+
+// |                              add a user                               |
+// +-----------------------------------------------------------------------+
+
+if (isset($_POST['submit_add']))
+{
+  $page['errors'] = register_user(
+    $_POST['login'], $_POST['password'], $_POST['email'], false);
+
+  if (count($page['errors']) == 0)
+  {
+    array_push(
+      $page['infos'],
+      sprintf(
+        l10n('user "%s" added'),
+        $_POST['login']
+        )
+      );
+  }
+}
+
+// +-----------------------------------------------------------------------+
+// |                               user list                               |
+// +-----------------------------------------------------------------------+
+
+$page['filtered_users'] = get_filtered_user_list();
+
+// +-----------------------------------------------------------------------+
+// |                            selected users                             |
+// +-----------------------------------------------------------------------+
+
+if (isset($_POST['delete']) or isset($_POST['pref_submit']))
+{
+  $collection = array();
+
+  switch ($_POST['target'])
+  {
+    case 'all' :
+    {
+      foreach($page['filtered_users'] as $local_user)
+      {
+        array_push($collection, $local_user['id']);
+      }
+      break;
+    }
+    case 'selection' :
+    {
+      if (isset($_POST['selection']))
+      {
+        $collection = $_POST['selection'];
+      }
+      break;
+    }
+  }
+
+  if (count($collection) == 0)
+  {
+    array_push($page['errors'], l10n('Select at least one user'));
+  }
+}
+
+// +-----------------------------------------------------------------------+
+// |                             delete users                              |
+// +-----------------------------------------------------------------------+
+if (isset($_POST['delete']) and count($collection) > 0)
+{
+  if (in_array($conf['guest_id'], $collection))
+  {
+    array_push($page['errors'], l10n('Guest cannot be deleted'));
+  }
+  if (($conf['guest_id'] != $conf['default_user_id']) and
+      in_array($conf['default_user_id'], $collection))
+  {
+    array_push($page['errors'], l10n('Default user cannot be deleted'));
+  }
+  if (in_array($conf['webmaster_id'], $collection))
+  {
+    array_push($page['errors'], l10n('Webmaster cannot be deleted'));
+  }
+  if (in_array($user['id'], $collection))
+  {
+    array_push($page['errors'], l10n('You cannot delete your account'));
+  }
+
+  if (count($page['errors']) == 0)
+  {
+    if (isset($_POST['confirm_deletion']) and 1 == $_POST['confirm_deletion'])
+    {
+      foreach ($collection as $user_id)
+      {
+        delete_user($user_id);
+      }
+      array_push(
+        $page['infos'],
+        l10n_dec(
+          '%d user deleted', '%d users deleted',
+          count($collection)
+          )
+        );
+      foreach ($page['filtered_users'] as $filter_key => $filter_user)
+      {
+        if (in_array($filter_user['id'], $collection))
+        {
+          unset($page['filtered_users'][$filter_key]);
+        }
+      }
+    }
+    else
+    {
+      array_push($page['errors'], l10n('You need to confirm deletion'));
+    }
+  }
+}
+
+// +-----------------------------------------------------------------------+
+// |                       preferences form submission                     |
+// +-----------------------------------------------------------------------+
+
+if (isset($_POST['pref_submit']) and count($collection) > 0)
+{
+  if (-1 != $_POST['associate'])
+  {
+    $datas = array();
+
+    $query = '
+SELECT user_id
+  FROM '.USER_GROUP_TABLE.'
+  WHERE group_id = '.$_POST['associate'].'
+;';
+    $associated = array_from_query($query, 'user_id');
+
+    $associable = array_diff($collection, $associated);
+
+    if (count($associable) > 0)
+    {
+      foreach ($associable as $item)
+      {
+        array_push($datas,
+                   array('group_id'=>$_POST['associate'],
+                         'user_id'=>$item));
+      }
+
+      mass_inserts(USER_GROUP_TABLE,
+                   array('group_id', 'user_id'),
+                   $datas);
+    }
+  }
+
+  if (-1 != $_POST['dissociate'])
+  {
+    $query = '
+DELETE FROM '.USER_GROUP_TABLE.'
+  WHERE group_id = '.$_POST['dissociate'].'
+  AND user_id IN ('.implode(',', $collection).')
+';
+    pwg_query($query);
+  }
+
+  // properties to set for the collection (a user list)
+  $datas = array();
+  $dbfields = array('primary' => array('user_id'), 'update' => array());
+
+  $formfields =
+    array('nb_image_line', 'nb_line_page', 'template', 'language',
+          'recent_period', 'maxwidth', 'expand', 'show_nb_comments',
+          'show_nb_hits', 'maxheight', 'status', 'enabled_high',
+          'level');
+
+  $true_false_fields = array('expand', 'show_nb_comments',
+                       'show_nb_hits', 'enabled_high');
+  if ($conf['allow_adviser'])
+  {
+    array_push($formfields, 'adviser');
+    array_push($true_false_fields, 'adviser');
+  }
+
+  foreach ($formfields as $formfield)
+  {
+    // special for true/false fields
+    if (in_array($formfield, $true_false_fields))
+    {
+      $test = $formfield;
+    }
+    else
+    {
+      $test = $formfield.'_action';
+    }
+
+    if ($_POST[$test] != 'leave')
+    {
+      array_push($dbfields['update'], $formfield);
+    }
+  }
+
+  // updating elements is useful only if needed...
+  if (count($dbfields['update']) > 0)
+  {
+    $datas = array();
+
+    foreach ($collection as $user_id)
+    {
+      $data = array();
+      $data['user_id'] = $user_id;
+
+      // TODO : verify if submited values are semanticaly correct
+      foreach ($dbfields['update'] as $dbfield)
+      {
+        // if the action is 'unset', the key won't be in row and
+        // mass_updates function will set this field to NULL
+        if (in_array($dbfield, $true_false_fields)
+            or 'set' == $_POST[$dbfield.'_action'])
+        {
+          $data[$dbfield] = $_POST[$dbfield];
+        }
+      }
+
+      // special users checks
+      if
+        (
+          ($conf['webmaster_id'] == $user_id) or
+          ($conf['guest_id'] == $user_id) or
+          ($conf['default_user_id'] == $user_id)
+        )
+      {
+        // status must not be changed
+        if (isset($data['status']))
+        {
+          if ($conf['webmaster_id'] == $user_id)
+          {
+            $data['status'] = 'webmaster';
+          }
+          else
+          {
+            $data['status'] = 'guest';
+          }
+        }
+
+        // could not be adivser
+        if (isset($data['adviser']))
+        {
+          $data['adviser'] = 'false';
+        }
+      }
+
+      array_push($datas, $data);
+    }
+
+    mass_updates(USER_INFOS_TABLE, $dbfields, $datas);
+  }
+
+  redirect(
+    get_root_url().
+    'admin.php'.
+    get_query_string_diff(array(), false)
+    );
+}
+
+// +-----------------------------------------------------------------------+
+// |                              groups list                              |
+// +-----------------------------------------------------------------------+
+
+$groups[-1] = '------------';
+
+$query = '
+SELECT id, name
+  FROM '.GROUPS_TABLE.'
+  ORDER BY name ASC
+;';
+$result = pwg_query($query);
+
+while ($row = mysql_fetch_array($result))
+{
+  $groups[$row['id']] = $row['name'];
+}
+
+// +-----------------------------------------------------------------------+
+// |                             template init                             |
+// +-----------------------------------------------------------------------+
+
+$template->set_filenames(array('user_list'=>'user_list.tpl'));
+
+$base_url = PHPWG_ROOT_PATH.'admin.php?page=user_list';
+
+if (isset($_GET['start']) and is_numeric($_GET['start']))
+{
+  $start = $_GET['start'];
+}
+else
+{
+  $start = 0;
+}
+
+$template->assign(
+  array(
+    'U_HELP' => get_root_url().'popuphelp.php?page=user_list',
+
+    'F_ADD_ACTION' => $base_url,
+    'F_USERNAME' => @htmlentities($_GET['username']),
+    'F_FILTER_ACTION' => get_root_url().'admin.php'
+    ));
+
+// Hide radio-button if not allow to assign adviser
+if ($conf['allow_adviser'])
+{
+  $template->assign('adviser', true);
+}
+
+// Filter status options
+$status_options[-1] = '------------';
+foreach (get_enums(USER_INFOS_TABLE, 'status') as $status)
+{
+  $status_options[$status] = l10n('user_status_'.$status);
+}
+$template->assign('status_options', $status_options);
+$template->assign('status_selected',
+    isset($_GET['status']) ? $_GET['status'] : '');
+
+// Filter group options
+$template->assign('group_options', $groups);
+$template->assign('group_selected',
+    isset($_GET['group']) ? $_GET['group'] : '');
+
+// Filter order options
+$template->assign('order_options', $page['order_by_items']);
+$template->assign('order_selected',
+    isset($_GET['order_by']) ? $_GET['order_by'] : '');
+
+// Filter direction options
+$template->assign('direction_options', $page['direction_items']);
+$template->assign('direction_selected',
+    isset($_GET['direction']) ? $_GET['direction'] : '');
+
+
+if (isset($_POST['pref_submit']))
+{
+  $template->assign(
+    array(
+      'NB_IMAGE_LINE' => $_POST['nb_image_line'],
+      'NB_LINE_PAGE' => $_POST['nb_line_page'],
+      'MAXWIDTH' => $_POST['maxwidth'],
+      'MAXHEIGHT' => $_POST['maxheight'],
+      'RECENT_PERIOD' => $_POST['recent_period'],
+      ));
+}
+else
+{
+  $default_user = get_default_user_info(true);
+  $template->assign(
+    array(
+      'NB_IMAGE_LINE' => $default_user['nb_image_line'],
+      'NB_LINE_PAGE' => $default_user['nb_line_page'],
+      'MAXWIDTH' => $default_user['maxwidth'],
+      'MAXHEIGHT' => $default_user['maxheight'],
+      'RECENT_PERIOD' => $default_user['recent_period'],
+      ));
+}
+
+// Template Options
+$template->assign('template_options', get_pwg_themes());
+$template->assign('template_selected', 
+    isset($_POST['pref_submit']) ? $_POST['template'] : get_default_template());
+
+// Language options
+$template->assign('language_options', get_languages());
+$template->assign('language_selected', 
+    isset($_POST['pref_submit']) ? $_POST['language'] : get_default_language());
+
+// Status options
+foreach (get_enums(USER_INFOS_TABLE, 'status') as $status)
+{
+  // Only status <= can be assign
+  if (is_autorize_status(get_access_type_status($status)))
+  {
+    $pref_status_options[$status] = l10n('user_status_'.$status);
+  }
+}
+$template->assign('pref_status_options', $pref_status_options);
+$template->assign('pref_status_selected', 
+    isset($_POST['pref_submit']) ? $_POST['status'] : 'normal');
+
+// associate and dissociate options
+$template->assign('association_options', $groups);
+$template->assign('associate_selected',
+    isset($_POST['pref_submit']) ? $_POST['associate'] : '');
+$template->assign('dissociate_selected',
+    isset($_POST['pref_submit']) ? $_POST['dissociate'] : '');
+
+
+// user level options
+foreach ($conf['available_permission_levels'] as $level)
+{
+  $level_options[$level] = l10n(sprintf('Level %d', $level));
+}
+$template->assign('level_options', $level_options);
+$template->assign('level_selected', 
+    isset($_POST['pref_submit']) ? $_POST['level'] : $default_user['level']);
+
+// +-----------------------------------------------------------------------+
+// |                            navigation bar                             |
+// +-----------------------------------------------------------------------+
+
+$url = PHPWG_ROOT_PATH.'admin.php'.get_query_string_diff(array('start'));
+
+$navbar = create_navigation_bar(
+  $url,
+  count($page['filtered_users']),
+  $start,
+  $conf['users_page']
+  );
+
+$template->assign('NAVBAR', $navbar);
+
+// +-----------------------------------------------------------------------+
+// |                               user list                               |
+// +-----------------------------------------------------------------------+
+
+$profile_url = get_root_url().'admin.php?page=profile&amp;user_id=';
+$perm_url = get_root_url().'admin.php?page=user_perm&amp;user_id=';
+
+$visible_user_list = array();
+foreach ($page['filtered_users'] as $num => $local_user)
+{
+  // simulate LIMIT $start, $conf['users_page']
+  if ($num < $start)
+  {
+    continue;
+  }
+  if ($num >= $start + $conf['users_page'])
+  {
+    break;
+  }
+
+  $visible_user_list[] = $local_user;
+}
+
+// allow plugins to fill template var plugin_user_list_column_titles and 
+// plugin_columns/plugin_actions for each user in the list
+$visible_user_list = trigger_event('loc_visible_user_list', $visible_user_list);
+
+foreach ($visible_user_list as $local_user)
+{
+  $groups_string = preg_replace(
+    '/(\d+)/e',
+    "\$groups['$1']",
+    implode(
+      ', ',
+      $local_user['groups']
+      )
+    );
+
+  if (isset($_POST['pref_submit'])
+      and isset($_POST['selection'])
+      and in_array($local_user['id'], $_POST['selection']))
+  {
+    $checked = 'checked="checked"';
+  }
+  else
+  {
+    $checked = '';
+  }
+
+  $properties = array();
+  if ( $local_user['level'] != 0 )
+  {
+    $properties[] = l10n( sprintf('Level %d', $local_user['level']) );
+  }
+  $properties[] =
+    (isset($local_user['enabled_high']) and ($local_user['enabled_high'] == 'true'))
+        ? l10n('is_high_enabled') : l10n('is_high_disabled');
+
+  $template->append(
+    'users',
+    array(
+      'ID' => $local_user['id'],
+      'CHECKED' => $checked,
+      'U_PROFILE' => $profile_url.$local_user['id'],
+      'U_PERM' => $perm_url.$local_user['id'],
+      'USERNAME' => $local_user['username']
+        .($local_user['id'] == $conf['guest_id']
+          ? '<BR />['.l10n('is_the_guest').']' : '')
+        .($local_user['id'] == $conf['default_user_id']
+          ? '<BR />['.l10n('is_the_default').']' : ''),
+      'STATUS' => l10n('user_status_'.
+        $local_user['status']).(($local_user['adviser'] == 'true')
+        ? '<BR />['.l10n('adviser').']' : ''),
+      'EMAIL' => get_email_address_as_display_text($local_user['email']),
+      'GROUPS' => $groups_string,
+      'PROPERTIES' => implode( ', ', $properties),
+      'plugin_columns' => isset($local_user['plugin_columns']) ? $local_user['plugin_columns'] : array(),
+      'plugin_actions' => isset($local_user['plugin_actions']) ? $local_user['plugin_actions'] : array(),
+      )
+    );
+}
+
+// +-----------------------------------------------------------------------+
+// |                           html code display                           |
+// +-----------------------------------------------------------------------+
+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'user_list');
+?>
Index: /tags/2.0.2/admin/user_perm.php
===================================================================
--- /tags/2.0.2/admin/user_perm.php	(revision 3278)
+++ /tags/2.0.2/admin/user_perm.php	(revision 3278)
@@ -0,0 +1,223 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('IN_ADMIN'))
+{
+  die('Hacking attempt!');
+}
+
+include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+
+// +-----------------------------------------------------------------------+
+// | Check Access and exit when user status is not ok                      |
+// +-----------------------------------------------------------------------+
+check_status(ACCESS_ADMINISTRATOR);
+
+// +-----------------------------------------------------------------------+
+// |                            variables init                             |
+// +-----------------------------------------------------------------------+
+
+if (isset($_GET['user_id']) and is_numeric($_GET['user_id']))
+{
+  $page['user'] = $_GET['user_id'];
+}
+else
+{
+  die('user_id URL parameter is missing');
+}
+
+// +-----------------------------------------------------------------------+
+// |                                updates                                |
+// +-----------------------------------------------------------------------+
+
+if (isset($_POST['falsify'])
+    and isset($_POST['cat_true'])
+    and count($_POST['cat_true']) > 0)
+{
+  // if you forbid access to a category, all sub-categories become
+  // automatically forbidden
+  $subcats = get_subcat_ids($_POST['cat_true']);
+  $query = '
+DELETE FROM '.USER_ACCESS_TABLE.'
+  WHERE user_id = '.$page['user'].'
+    AND cat_id IN ('.implode(',', $subcats).')
+;';
+  pwg_query($query);
+}
+else if (isset($_POST['trueify'])
+         and isset($_POST['cat_false'])
+         and count($_POST['cat_false']) > 0)
+{
+  $uppercats = get_uppercat_ids($_POST['cat_false']);
+  $private_uppercats = array();
+
+  $query = '
+SELECT id
+  FROM '.CATEGORIES_TABLE.'
+  WHERE id IN ('.implode(',', $uppercats).')
+    AND status = \'private\'
+;';
+  $result = pwg_query($query);
+  while ($row = mysql_fetch_array($result))
+  {
+    array_push($private_uppercats, $row['id']);
+  }
+
+  // retrying to authorize a category which is already authorized may cause
+  // an error (in SQL statement), so we need to know which categories are
+  // accesible
+  $authorized_ids = array();
+
+  $query = '
+SELECT cat_id
+  FROM '.USER_ACCESS_TABLE.'
+  WHERE user_id = '.$page['user'].'
+;';
+  $result = pwg_query($query);
+
+  while ($row = mysql_fetch_array($result))
+  {
+    array_push($authorized_ids, $row['cat_id']);
+  }
+
+  $inserts = array();
+  $to_autorize_ids = array_diff($private_uppercats, $authorized_ids);
+  foreach ($to_autorize_ids as $to_autorize_id)
+  {
+    array_push($inserts, array('user_id' => $page['user'],
+                               'cat_id' => $to_autorize_id));
+  }
+
+  mass_inserts(USER_ACCESS_TABLE, array('user_id','cat_id'), $inserts);
+}
+
+// +-----------------------------------------------------------------------+
+// |                             template init                             |
+// +-----------------------------------------------------------------------+
+
+$template->set_filenames(
+  array(
+    'user_perm' => 'user_perm.tpl',
+    'double_select' => 'double_select.tpl'
+    )
+  );
+
+$template->assign(
+  array(
+    'TITLE' =>
+      sprintf(
+        l10n('Manage permissions for user "%s"'),
+        get_username($page['user']
+          )
+        ),
+    'L_CAT_OPTIONS_TRUE'=>l10n('authorized'),
+    'L_CAT_OPTIONS_FALSE'=>l10n('forbidden'),
+
+    'F_ACTION' =>
+        PHPWG_ROOT_PATH.
+        'admin.php?page=user_perm'.
+        '&amp;user_id='.$page['user']
+    )
+  );
+
+
+// retrieve category ids authorized to the groups the user belongs to
+$group_authorized = array();
+
+$query = '
+SELECT DISTINCT cat_id, c.uppercats, c.global_rank
+  FROM '.USER_GROUP_TABLE.' AS ug
+    INNER JOIN '.GROUP_ACCESS_TABLE.' AS ga
+      ON ug.group_id = ga.group_id
+    INNER JOIN '.CATEGORIES_TABLE.' AS c
+      ON c.id = ga.cat_id
+  WHERE ug.user_id = '.$page['user'].'
+;';
+$result = pwg_query($query);
+
+if (mysql_num_rows($result) > 0)
+{
+  $cats = array();
+  while ($row = mysql_fetch_array($result))
+  {
+    array_push($cats, $row);
+    array_push($group_authorized, $row['cat_id']);
+  }
+  usort($cats, 'global_rank_compare');
+
+  foreach ($cats as $category)
+  {
+    $template->append(
+      'categories_because_of_groups',
+      get_cat_display_name_cache($category['uppercats'], null, false)
+      );
+  }
+}
+
+// only private categories are listed
+$query_true = '
+SELECT id,name,uppercats,global_rank
+  FROM '.CATEGORIES_TABLE.' INNER JOIN '.USER_ACCESS_TABLE.' ON cat_id = id
+  WHERE status = \'private\'
+    AND user_id = '.$page['user'];
+if (count($group_authorized) > 0)
+{
+  $query_true.= '
+    AND cat_id NOT IN ('.implode(',', $group_authorized).')';
+}
+$query_true.= '
+;';
+display_select_cat_wrapper($query_true,array(),'category_option_true');
+
+$result = pwg_query($query_true);
+$authorized_ids = array();
+while ($row = mysql_fetch_array($result))
+{
+  array_push($authorized_ids, $row['id']);
+}
+
+$query_false = '
+SELECT id,name,uppercats,global_rank
+  FROM '.CATEGORIES_TABLE.'
+  WHERE status = \'private\'';
+if (count($authorized_ids) > 0)
+{
+  $query_false.= '
+    AND id NOT IN ('.implode(',', $authorized_ids).')';
+}
+if (count($group_authorized) > 0)
+{
+  $query_false.= '
+    AND id NOT IN ('.implode(',', $group_authorized).')';
+}
+$query_false.= '
+;';
+display_select_cat_wrapper($query_false,array(),'category_option_false');
+
+// +-----------------------------------------------------------------------+
+// |                           sending html code                           |
+// +-----------------------------------------------------------------------+
+
+$template->assign_var_from_handle('DOUBLE_SELECT', 'double_select');
+$template->assign_var_from_handle('ADMIN_CONTENT', 'user_perm');
+?>
Index: /tags/2.0.2/category.php
===================================================================
--- /tags/2.0.2/category.php	(revision 3278)
+++ /tags/2.0.2/category.php	(revision 3278)
@@ -0,0 +1,65 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+/*
+This file contains now only code to ensure backward url compatibility with
+versions before 1.6
+*/
+
+define('PHPWG_ROOT_PATH','./');
+include_once( PHPWG_ROOT_PATH.'include/common.inc.php' );
+
+$url_params=array();
+if ( isset($_GET['cat']) )
+{
+  if ( is_numeric($_GET['cat']) )
+  {
+    $url_params['section'] = 'categories';
+    $result = get_cat_info( $_GET['cat'] );
+    if ( !empty($result) )
+    {
+      $url_params['category'] = $result;
+    }
+  }
+  elseif ( in_array($_GET['cat'],
+              array('best_rated','most_visited','recent_pics','recent_cats')
+                  )
+         )
+  {
+    $url_params['section'] = $_GET['cat'];
+  }
+  else
+  {
+    page_not_found('');
+  }
+}
+
+$url = make_index_url($url_params);
+if (!headers_sent())
+{
+  set_status_header(301);
+  redirect_http( $url );
+}
+redirect ( $url );
+
+?>
Index: /tags/2.0.2/comments.php
===================================================================
--- /tags/2.0.2/comments.php	(revision 3278)
+++ /tags/2.0.2/comments.php	(revision 3278)
@@ -0,0 +1,394 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// +-----------------------------------------------------------------------+
+// |                           initialization                              |
+// +-----------------------------------------------------------------------+
+define('PHPWG_ROOT_PATH','./');
+include_once(PHPWG_ROOT_PATH.'include/common.inc.php');
+
+// +-----------------------------------------------------------------------+
+// | Check Access and exit when user status is not ok                      |
+// +-----------------------------------------------------------------------+
+check_status(ACCESS_GUEST);
+
+$sort_order = array(
+  'DESC' => l10n('descending'),
+  'ASC'  => l10n('ascending')
+  );
+
+// sort_by : database fields proposed for sorting comments list
+$sort_by = array(
+  'date' => l10n('comment date'),
+  'image_id' => l10n('picture')
+  );
+
+// items_number : list of number of items to display per page
+$items_number = array(5,10,20,50,'all');
+
+// since when display comments ?
+//
+$since_options = array(
+  1 => array('label' => l10n('today'),
+             'clause' => 'date > SUBDATE(CURDATE(), INTERVAL 1 DAY)'),
+  2 => array('label' => sprintf(l10n('last %d days'), 7),
+             'clause' => 'date > SUBDATE(CURDATE(), INTERVAL 7 DAY)'),
+  3 => array('label' => sprintf(l10n('last %d days'), 30),
+             'clause' => 'date > SUBDATE(CURDATE(), INTERVAL 30 DAY)'),
+  4 => array('label' => l10n('the beginning'),
+             'clause' => '1=1') // stupid but generic
+  );
+
+$page['since'] = isset($_GET['since']) ? $_GET['since'] : 4;
+
+// on which field sorting
+//
+$page['sort_by'] = 'date';
+// if the form was submitted, it overloads default behaviour
+if (isset($_GET['sort_by']) and isset($sort_by[$_GET['sort_by']]) )
+{
+  $page['sort_by'] = $_GET['sort_by'];
+}
+
+// order to sort
+//
+$page['sort_order'] = 'DESC';
+// if the form was submitted, it overloads default behaviour
+if (isset($_GET['sort_order']) and isset($sort_order[$_GET['sort_order']]))
+{
+  $page['sort_order'] = $_GET['sort_order'];
+}
+
+// number of items to display
+//
+$page['items_number'] = 10;
+if (isset($_GET['items_number']))
+{
+  $page['items_number'] = $_GET['items_number'];
+}
+
+$page['where_clauses'] = array();
+
+// which category to filter on ?
+if (isset($_GET['cat']) and 0 != $_GET['cat'])
+{
+  $page['where_clauses'][] =
+    'category_id IN ('.implode(',', get_subcat_ids(array($_GET['cat']))).')';
+}
+
+// search a particular author
+if (isset($_GET['author']) and !empty($_GET['author']))
+{
+  $page['where_clauses'][] = 'com.author = \''.$_GET['author'].'\'';
+}
+
+// search a substring among comments content
+if (isset($_GET['keyword']) and !empty($_GET['keyword']))
+{
+  $page['where_clauses'][] =
+    '('.
+    implode(' AND ',
+            array_map(
+              create_function(
+                '$s',
+                'return "content LIKE \'%$s%\'";'
+                ),
+              preg_split('/[\s,;]+/', $_GET['keyword'] )
+              )
+      ).
+    ')';
+}
+
+$page['where_clauses'][] = $since_options[$page['since']]['clause'];
+
+// which status to filter on ?
+if ( !is_admin() )
+{
+  $page['where_clauses'][] = 'validated="true"';
+}
+
+$page['where_clauses'][] = get_sql_condition_FandF
+  (
+    array
+      (
+        'forbidden_categories' => 'category_id',
+        'visible_categories' => 'category_id',
+        'visible_images' => 'ic.image_id'
+      ),
+    '', true
+  );
+
+// +-----------------------------------------------------------------------+
+// |                         comments management                           |
+// +-----------------------------------------------------------------------+
+if (isset($_GET['delete']) and is_numeric($_GET['delete'])
+      and !is_adviser() )
+{// comments deletion
+  check_status(ACCESS_ADMINISTRATOR);
+  $query = '
+DELETE FROM '.COMMENTS_TABLE.'
+  WHERE id='.$_GET['delete'].'
+;';
+  pwg_query($query);
+}
+
+if (isset($_GET['validate']) and is_numeric($_GET['validate'])
+      and !is_adviser() )
+{  // comments validation
+  check_status(ACCESS_ADMINISTRATOR);
+  $query = '
+UPDATE '.COMMENTS_TABLE.'
+  SET validated = \'true\'
+  , validation_date = NOW()
+  WHERE id='.$_GET['validate'].'
+;';
+  pwg_query($query);
+}
+
+// +-----------------------------------------------------------------------+
+// |                       page header and options                         |
+// +-----------------------------------------------------------------------+
+
+$title= l10n('User comments');
+$page['body_id'] = 'theCommentsPage';
+
+$template->set_filenames(array('comments'=>'comments.tpl'));
+$template->assign(
+  array(
+    'F_ACTION'=>PHPWG_ROOT_PATH.'comments.php',
+    'F_KEYWORD'=>@htmlspecialchars(stripslashes($_GET['keyword'])),
+    'F_AUTHOR'=>@htmlspecialchars(stripslashes($_GET['author'])),
+    )
+  );
+
+// +-----------------------------------------------------------------------+
+// |                          form construction                            |
+// +-----------------------------------------------------------------------+
+
+// Search in a particular category
+$blockname = 'categories';
+
+$query = '
+SELECT id, name, uppercats, global_rank
+  FROM '.CATEGORIES_TABLE.'
+'.get_sql_condition_FandF
+  (
+    array
+      (
+        'forbidden_categories' => 'id',
+        'visible_categories' => 'id'
+      ),
+    'WHERE'
+  ).'
+;';
+display_select_cat_wrapper($query, array(@$_GET['cat']), $blockname, true);
+
+// Filter on recent comments...
+$tpl_var=array();
+foreach ($since_options as $id => $option)
+{
+  $tpl_var[ $id ] = $option['label'];
+}
+$template->assign( 'since_options', $tpl_var);
+$template->assign( 'since_options_selected', $page['since']);
+
+// Sort by
+$template->assign( 'sort_by_options', $sort_by);
+$template->assign( 'sort_by_options_selected', $page['sort_by']);
+
+// Sorting order
+$template->assign( 'sort_order_options', $sort_order);
+$template->assign( 'sort_order_options_selected', $page['sort_order']);
+
+
+// Number of items
+$blockname = 'items_number_option';
+$tpl_var=array();
+foreach ($items_number as $option)
+{
+  $tpl_var[ $option ] = is_numeric($option) ? $option : l10n($option);
+}
+$template->assign( 'item_number_options', $tpl_var);
+$template->assign( 'item_number_options_selected', $page['items_number']);
+
+
+// +-----------------------------------------------------------------------+
+// |                            navigation bar                             |
+// +-----------------------------------------------------------------------+
+
+if (isset($_GET['start']) and is_numeric($_GET['start']))
+{
+  $start = $_GET['start'];
+}
+else
+{
+  $start = 0;
+}
+
+$query = '
+SELECT COUNT(DISTINCT(id))
+  FROM '.IMAGE_CATEGORY_TABLE.' AS ic
+    INNER JOIN '.COMMENTS_TABLE.' AS com
+    ON ic.image_id = com.image_id
+  WHERE '.implode('
+    AND ', $page['where_clauses']).'
+;';
+list($counter) = mysql_fetch_row(pwg_query($query));
+
+$url = PHPWG_ROOT_PATH
+    .'comments.php'
+    .get_query_string_diff(array('start','delete','validate'));
+
+$navbar = create_navigation_bar($url,
+                                $counter,
+                                $start,
+                                $page['items_number'],
+                                '');
+
+$template->assign('NAVBAR', $navbar);
+
+// +-----------------------------------------------------------------------+
+// |                        last comments display                          |
+// +-----------------------------------------------------------------------+
+
+$comments = array();
+$element_ids = array();
+$category_ids = array();
+
+$query = '
+SELECT com.id AS comment_id
+     , com.image_id
+     , ic.category_id
+     , com.author
+     , com.date
+     , com.content
+     , com.id AS comment_id
+     , com.validated
+  FROM '.IMAGE_CATEGORY_TABLE.' AS ic
+    INNER JOIN '.COMMENTS_TABLE.' AS com
+    ON ic.image_id = com.image_id
+  WHERE '.implode('
+    AND ', $page['where_clauses']).'
+  GROUP BY comment_id
+  ORDER BY '.$page['sort_by'].' '.$page['sort_order'];
+if ('all' != $page['items_number'])
+{
+  $query.= '
+  LIMIT '.$start.','.$page['items_number'];
+}
+$query.= '
+;';
+$result = pwg_query($query);
+while ($row = mysql_fetch_assoc($result))
+{
+  array_push($comments, $row);
+  array_push($element_ids, $row['image_id']);
+  array_push($category_ids, $row['category_id']);
+}
+
+if (count($comments) > 0)
+{
+  // retrieving element informations
+  $elements = array();
+  $query = '
+SELECT id, name, file, path, tn_ext
+  FROM '.IMAGES_TABLE.'
+  WHERE id IN ('.implode(',', $element_ids).')
+;';
+  $result = pwg_query($query);
+  while ($row = mysql_fetch_assoc($result))
+  {
+    $elements[$row['id']] = $row;
+  }
+
+  // retrieving category informations
+  $query = '
+SELECT id, name, permalink, uppercats
+  FROM '.CATEGORIES_TABLE.'
+  WHERE id IN ('.implode(',', $category_ids).')
+;';
+  $categories = hash_from_query($query, 'id');
+
+  foreach ($comments as $comment)
+  {
+    if (!empty($elements[$comment['image_id']]['name']))
+    {
+      $name=$elements[$comment['image_id']]['name'];
+    }
+    else
+    {
+      $name=get_name_from_file($elements[$comment['image_id']]['file']);
+    }
+
+    // source of the thumbnail picture
+    $thumbnail_src = get_thumbnail_url( $elements[$comment['image_id']] );
+
+    // link to the full size picture
+    $url = make_picture_url(
+            array(
+              'category' => $categories[ $comment['category_id'] ],
+              'image_id' => $comment['image_id'],
+              'image_file' => $elements[$comment['image_id']]['file'],
+            )
+          );
+
+    $author = $comment['author'];
+    if (empty($comment['author']))
+    {
+      $author = l10n('guest');
+    }
+
+    $tpl_comment =
+      array(
+        'U_PICTURE' => $url,
+        'TN_SRC' => $thumbnail_src,
+        'ALT' => $name,
+        'AUTHOR' => trigger_event('render_comment_author', $author),
+        'DATE'=>format_date($comment['date'], true),
+        'CONTENT'=>trigger_event('render_comment_content',$comment['content']),
+        );
+
+    if ( is_admin() )
+    {
+      $url = get_root_url().'comments.php'.get_query_string_diff(array('delete','validate'));
+      $tpl_comment['U_DELETE'] = add_url_params($url,
+                          array('delete'=>$comment['comment_id'])
+                         );
+
+      if ($comment['validated'] != 'true')
+      {
+        $tpl_comment['U_VALIDATE'] = add_url_params($url,
+                            array('validate'=>$comment['comment_id'])
+                           );
+      }
+    }
+    $template->append('comments', $tpl_comment);
+  }
+}
+// +-----------------------------------------------------------------------+
+// |                           html code display                           |
+// +-----------------------------------------------------------------------+
+include(PHPWG_ROOT_PATH.'include/page_header.php');
+$template->pparse('comments');
+include(PHPWG_ROOT_PATH.'include/page_tail.php');
+?>
Index: /tags/2.0.2/doc/COPYING
===================================================================
--- /tags/2.0.2/doc/COPYING	(revision 3278)
+++ /tags/2.0.2/doc/COPYING	(revision 3278)
@@ -0,0 +1,345 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+                       59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
Index: /tags/2.0.2/doc/README_en.txt
===================================================================
--- /tags/2.0.2/doc/README_en.txt	(revision 3278)
+++ /tags/2.0.2/doc/README_en.txt	(revision 3278)
@@ -0,0 +1,62 @@
+=======
+Piwigo
+=======
+
+website:        http://piwigo.org
+Installation:   http://piwigo.org/basics/installation
+Upgrade:        http://piwigo.org/basics/upgrade
+
+How to start
+============
+
+Once installed or upgraded, your gallery is ready to run. Start by
+displaying the installation directory in your browser :
+
+http://your.domain/photos
+
+Then identify as an administrator. A new link in Identification menu of main
+page will appear : Administration. Enter the administration panel.
+
+In the administration panel, take all your time for reading instructions
+explaining how to use your gallery.
+
+Communication
+=============
+
+Newsletter
+----------
+
+https://mail.gna.org/listinfo/phpwebgallery-announce/
+
+It is *highly* recommended to subscribe to Piwigo newsletter. This is
+extremely low-traffic, but will provide you with announcements of new
+Piwigo releases and serious bug notification.
+
+Freshmeat
+---------
+
+http://freshmeat.net/projects/phpwebgallery
+
+Want to stay informed at each release, stable and development
+release. Development releases notification are not send in the newsletter.
+
+Bugtracker
+----------
+
+http://piwigo.org/bugs
+
+Bugs and change requests tracking. The best way to have your bug corrected:
+it won't be forgotten (as in the forum).
+
+Documentation
+-------------
+
+http://piwigo.org/doc
+
+Wiki documentation: everyone can participate to improve documentation
+content.
+
+Forum
+-----
+
+http://piwigo.org/forum
Index: /tags/2.0.2/doc/README_fr.txt
===================================================================
--- /tags/2.0.2/doc/README_fr.txt	(revision 3278)
+++ /tags/2.0.2/doc/README_fr.txt	(revision 3278)
@@ -0,0 +1,74 @@
+=======
+Piwigo
+=======
+
+Site web:        http://fr.piwigo.org
+Installation:    http://fr.piwigo.org/basics/installation
+Mise à jour:     http://fr.piwigo.org/basics/upgrade
+
+Prendre un bon départ
+=====================
+
+Une fois installée ou mise à jour, votre galerie est prête à
+fonctionner. Commencez par vous rendre sur le répertoire d'installation dans
+votre navigateur : 
+
+http://votre.domaine/photos
+
+Ensuite, identifiez-vous en tant qu'un administrateur. Un nouveau lien dans
+le menu d'identification de la page principale va apparaître :
+Administration. Suivre ce lien :-)
+
+Dans la zone d'administration, prenez tout le temps nécessaire pour
+consulter les instructions, expliquant comment utiliser votre galerie.
+
+Communication
+=============
+
+Newsletter
+----------
+
+https://mail.gna.org/listinfo/phpwebgallery-announce-french/
+
+Il est *fortement* recommandé de souscrire à la newsletter de
+Piwigo. Très peu de mails sont envoyés, mais les informations sont
+importantes : nouvelles versions de l'application, notification de bugs
+importants (relatifs à la sécurité).
+
+Freshmeat
+---------
+
+http://freshmeat.net/projects/phpwebgallery
+
+Permet d'être au courant des sorties de toutes les releases, et en
+exclusivité les builds de la branche de développement (ce qui n'est pas
+prévu sur les mailing lists "announce").
+
+Outil de suivi de bogues
+------------------------
+
+http://piwigo.org/bugs
+
+Gestion des bugs, mais aussi demande de nouvelles fonctionnalités. Rien de
+plus efficace pour qu'un bug soit corrigé : tant qu'il ne l'est pas, la
+"fiche" reste là à attendre, on ne l'oublie pas comme un topic sur le
+forum.
+
+Les demandes d'évolutions sont également gérées dans cet outil. Ce n'est pas
+forcément idéal car il ne s'agit pas de la même chose, mais le suivi du dev
+d'une nouvelle fonctionnalité peut se modéliser de la même façon que le
+suivi de la correction d'un bug.
+
+Documentation
+-------------
+
+http://fr.piwigo.org/doc
+
+Forum de discussion
+-------------------
+
+http://fr.piwigo.org/forum
+
+Un forum est disponible et recommandé pour toutes les questions autres que
+les demandes d'évolution et rapport de bogue (installation, discussions
+techniques).
Index: /tags/2.0.2/doc/index.php
===================================================================
--- /tags/2.0.2/doc/index.php	(revision 3278)
+++ /tags/2.0.2/doc/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/feed.php
===================================================================
--- /tags/2.0.2/feed.php	(revision 3278)
+++ /tags/2.0.2/feed.php	(revision 3278)
@@ -0,0 +1,201 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+define('PHPWG_ROOT_PATH','./');
+include_once(PHPWG_ROOT_PATH.'include/common.inc.php');
+include_once(PHPWG_ROOT_PATH.'include/functions_notification.inc.php');
+
+// +-----------------------------------------------------------------------+
+// |                               functions                               |
+// +-----------------------------------------------------------------------+
+
+/**
+ * creates a Unix timestamp (number of seconds since 1970-01-01 00:00:00
+ * GMT) from a MySQL datetime format (2005-07-14 23:01:37)
+ *
+ * @param string mysql datetime format
+ * @return int timestamp
+ */
+function mysqldt_to_ts($mysqldt)
+{
+  $date = explode_mysqldt($mysqldt);
+  return mktime($date['hour'], $date['minute'], $date['second'],
+                $date['month'], $date['day'], $date['year']);
+}
+
+/**
+ * creates an ISO 8601 format date (2003-01-20T18:05:41+04:00) from Unix
+ * timestamp (number of seconds since 1970-01-01 00:00:00 GMT)
+ *
+ * function copied from Dotclear project http://dotclear.net
+ *
+ * @param int timestamp
+ * @return string ISO 8601 date format
+ */
+function ts_to_iso8601($ts)
+{
+  $tz = date('O',$ts);
+  $tz = substr($tz, 0, -2).':'.substr($tz, -2);
+  return date('Y-m-d\\TH:i:s',$ts).$tz;
+}
+
+// +-----------------------------------------------------------------------+
+// |                            initialization                             |
+// +-----------------------------------------------------------------------+
+
+$feed_id= isset($_GET['feed']) ? $_GET['feed'] : '';
+$image_only=isset($_GET['image_only']);
+
+// echo '<pre>'.generate_key(50).'</pre>';
+if ( !empty($feed_id) )
+{
+  $query = '
+SELECT user_id,
+       last_check
+  FROM '.USER_FEED_TABLE.'
+  WHERE id = \''.$feed_id.'\'
+;';
+  $feed_row = mysql_fetch_assoc(pwg_query($query));
+  if ( empty($feed_row) )
+  {
+    page_not_found('Unknown/missing feed identifier');
+  }
+  if ($feed_row['user_id']!=$user['id'])
+  { // new user
+    $user = build_user( $feed_row['user_id'], true );
+  }
+}
+else
+{
+  $image_only = true;
+  if (!is_a_guest())
+  {// auto session was created - so switch to guest
+    $user = build_user( $conf['guest_id'], true );
+  }
+}
+
+// Check the status now after the user has been loaded
+check_status(ACCESS_GUEST);
+
+list($dbnow) = mysql_fetch_row(pwg_query('SELECT NOW();'));
+
+include_once(PHPWG_ROOT_PATH.'include/feedcreator.class.php');
+
+set_make_full_url();
+
+$rss = new UniversalFeedCreator();
+$rss->encoding=get_pwg_charset();
+$rss->title = $conf['gallery_title'];
+$rss->title.= ' (as '.$user['username'].')';
+
+$rss->link = $conf['gallery_url'];
+
+// +-----------------------------------------------------------------------+
+// |                            Feed creation                              |
+// +-----------------------------------------------------------------------+
+
+$news = array();
+if (!$image_only)
+{
+  $news = news($feed_row['last_check'], $dbnow, true, true);
+
+  if (count($news) > 0)
+  {
+    $item = new FeedItem();
+    $item->title = sprintf(l10n('New on %s'), format_date($dbnow) );
+    $item->link = $conf['gallery_url'];
+
+    // content creation
+    $item->description = '<ul>';
+    foreach ($news as $line)
+    {
+      $item->description.= '<li>'.$line.'</li>';
+    }
+    $item->description.= '</ul>';
+    $item->descriptionHtmlSyndicated = true;
+
+    $item->date = mysqldt_to_ts($dbnow);
+    $item->author = $conf['rss_feed_author'];
+    $item->guid= sprintf('%s', $dbnow);;
+
+    $rss->addItem($item);
+
+    $query = '
+UPDATE '.USER_FEED_TABLE.'
+  SET last_check = \''.$dbnow.'\'
+  WHERE id = \''.$feed_id.'\'
+;';
+    pwg_query($query);
+  }
+}
+
+if ( !empty($feed_id) and empty($news) )
+{// update the last check from time to time to avoid deletion by maintenance tasks
+  if ( !isset($feed_row['last_check'])
+    or time()-mysqldt_to_ts($feed_row['last_check']) > 30*24*3600 )
+  {
+    $query = '
+UPDATE '.USER_FEED_TABLE.'
+  SET last_check = DATE_ADD(\''.$dbnow.'\', INTERVAL -15 DAY )
+  WHERE id = \''.$feed_id.'\'
+;';
+    pwg_query($query);
+  }
+}
+
+$dates = get_recent_post_dates_array($conf['recent_post_dates']['RSS']);
+
+foreach($dates as $date_detail)
+{ // for each recent post date we create a feed item
+  $item = new FeedItem();
+  $date = $date_detail['date_available'];
+  $item->title = get_title_recent_post_date($date_detail);
+  $item->link = make_index_url(
+        array(
+          'chronology_field' => 'posted',
+          'chronology_style'=> 'monthly',
+          'chronology_view' => 'calendar',
+          'chronology_date' => explode('-', substr($date,0,10) )
+        )
+      );
+
+  $item->description .=
+    '<a href="'.make_index_url().'">'.$conf['gallery_title'].'</a><br/> ';
+
+  $item->description .= get_html_description_recent_post_date($date_detail);
+
+  $item->descriptionHtmlSyndicated = true;
+
+  $item->date = mysqldt_to_ts($date);
+  $item->author = $conf['rss_feed_author'];
+  $item->guid= sprintf('%s', 'pics-'.$date);;
+
+  $rss->addItem($item);
+}
+
+$fileName= $conf['local_data_dir'].'/tmp';
+mkgetdir($fileName); // just in case
+$fileName.='/feed.xml';
+// send XML feed
+echo $rss->saveFeed('RSS2.0', $fileName, true);
+?>
Index: /tags/2.0.2/galleries/.cvsignore
===================================================================
--- /tags/2.0.2/galleries/.cvsignore	(revision 3278)
+++ /tags/2.0.2/galleries/.cvsignore	(revision 3278)
@@ -0,0 +1,1 @@
+*
Index: /tags/2.0.2/galleries/index.php
===================================================================
--- /tags/2.0.2/galleries/index.php	(revision 3278)
+++ /tags/2.0.2/galleries/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008      Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/identification.php
===================================================================
--- /tags/2.0.2/identification.php	(revision 3278)
+++ /tags/2.0.2/identification.php	(revision 3278)
@@ -0,0 +1,93 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+//--------------------------------------------------------------------- include
+define('PHPWG_ROOT_PATH','./');
+include_once( PHPWG_ROOT_PATH.'include/common.inc.php' );
+
+// +-----------------------------------------------------------------------+
+// | Check Access and exit when user status is not ok                      |
+// +-----------------------------------------------------------------------+
+check_status(ACCESS_FREE);
+
+//-------------------------------------------------------------- identification
+$errors = array();
+
+$redirect_to = '';
+if ( !empty($_GET['redirect']) )
+{
+  $redirect_to = urldecode($_GET['redirect']);
+  if ( is_a_guest() )
+  {
+    array_push($errors, l10n('access_forbiden'));
+  }
+}
+
+if (isset($_POST['login']))
+{
+  $redirect_to = isset($_POST['redirect']) ? $_POST['redirect'] : '';
+  $remember_me = isset($_POST['remember_me']) and $_POST['remember_me']==1;
+  if ( try_log_user($_POST['username'], $_POST['password'], $remember_me) )
+  {
+    redirect(empty($redirect_to) ? make_index_url() : $redirect_to);
+  }
+  else
+  {
+    array_push( $errors, l10n('invalid_pwd') );
+  }
+}
+
+//----------------------------------------------------- template initialization
+//
+// Start output of page
+//
+$title = l10n('identification');
+$page['body_id'] = 'theIdentificationPage';
+include(PHPWG_ROOT_PATH.'include/page_header.php');
+
+$template->set_filenames( array('identification'=>'identification.tpl') );
+
+$template->assign(
+  array(
+    'U_LOST_PASSWORD' => get_root_url().'password.php',
+    'U_REDIRECT' => $redirect_to,
+
+    'F_LOGIN_ACTION' => get_root_url().'identification.php',
+    'authorize_remembering' => $conf['authorize_remembering'],
+    ));
+
+if ($conf['allow_user_registration'])
+{
+  $template->assign('U_REGISTER', get_root_url().'register.php' );
+}
+
+//-------------------------------------------------------------- errors display
+if ( sizeof( $errors ) != 0 )
+{
+  $template->assign('errors', $errors);
+}
+
+//----------------------------------------------------------- html code display
+$template->pparse('identification');
+include(PHPWG_ROOT_PATH.'include/page_tail.php');
+?>
Index: /tags/2.0.2/include/block.class.php
===================================================================
--- /tags/2.0.2/include/block.class.php	(revision 3278)
+++ /tags/2.0.2/include/block.class.php	(revision 3278)
@@ -0,0 +1,214 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+class BlockManager
+{
+  protected $id;
+  protected $registered_blocks=array();
+  protected $display_blocks = array();
+
+  public function BlockManager($id)
+  {
+    $this->id = $id;
+  }
+
+  /** triggers an action that allows implementors of menu blocks to register the blocks*/
+  public function load_registered_blocks()
+  {
+    trigger_action('blockmanager_register_blocks', array(&$this) );
+  }
+
+  public function get_id()
+  {
+    return $this->id;
+  }
+
+  public function get_registered_blocks()
+  {
+    return $this->registered_blocks;
+  }
+
+  /** registers a block with this menu. usually called as a result of menubar_register_blocks action
+   * @param MenuBlock block
+  */
+  public function register_block(&$block)
+  {
+    if ( isset($this->registered_blocks[$block->get_id()] ) )
+    {
+      trigger_error("Block '".$block->get_id()."' is already registered", E_USER_WARNING);
+      return false;
+    }
+    $this->registered_blocks[$block->get_id()] = &$block;
+    return true;
+  }
+
+  /** performs one time preparation of registered blocks for display;
+   * triggers the action menubar_prepare_display where implementors can
+   * reposition or hide blocks
+  */
+  public function prepare_display()
+  {
+    global $conf;
+    $conf_id = 'blk_'.$this->id;
+    $mb_conf = isset($conf[$conf_id]) ? $conf[$conf_id] : array();
+    if ( !is_array($mb_conf) )
+      $mb_conf = @unserialize($mb_conf);
+
+    $idx = 1;
+    foreach( $this->registered_blocks as $id => $block )
+    {
+      $pos = isset( $mb_conf[$id] ) ? $mb_conf[$id] : $idx*50;
+      if ( $pos>0 )
+      {
+        $this->display_blocks[$id] = new DisplayBlock($block);
+        $this->display_blocks[$id]->set_position($pos);
+      }
+      $idx++;
+    }
+    $this->sort_blocks();
+    trigger_action( 'blockmanager_prepare_display', array(&$this) );
+    $this->sort_blocks();
+  }
+
+  /** returns true if the block whose id is hidden
+   * @param string block_id
+  */
+  public function is_hidden($block_id)
+  {
+    return isset($this->display_blocks[$block_id]) ? false : true;
+  }
+
+  public function hide_block($block_id)
+  {
+    unset( $this->display_blocks[$block_id] );
+  }
+
+  public function &get_block($block_id)
+  {
+    $tmp = null;
+    if ( isset($this->display_blocks[$block_id]) )
+    {
+      return $this->display_blocks[$block_id];
+    }
+    return $tmp;
+  }
+
+  public function set_block_position($block_id, $position)
+  {
+    if ( isset($this->display_blocks[$block_id]) )
+    {
+      $this->display_blocks[$block_id]->set_position($position);
+    }
+  }
+
+  protected function sort_blocks()
+  {
+    uasort( $this->display_blocks, array('BlockManager', 'cmp_by_position') );
+  }
+
+  static protected function cmp_by_position($a, $b)
+  {
+    return $a->get_position() - $b->get_position();
+  }
+
+  public function apply($var, $file)
+  {
+    global $template;
+
+    $template->set_filename('menubar', $file);
+    trigger_action('blockmanager_apply', array(&$this) );
+
+    foreach( $this->display_blocks as $id=>$block)
+    {
+      if (empty($block->raw_content) and empty($block->template) )
+      {
+        $this->hide_block($id);
+      }
+    }
+    $this->sort_blocks();
+    $template->assign('blocks', $this->display_blocks);
+    $template->assign_var_from_handle($var, 'menubar');
+  }
+}
+
+/**
+ * Represents a menu block registered in a Menu object.
+ */
+class RegisteredBlock
+{
+  protected $id;
+  protected $name;
+  protected $owner;
+
+  public function RegisteredBlock($id, $name, $owner)
+  {
+    $this->id = $id;
+    $this->name = $name;
+    $this->owner = $owner;
+  }
+
+  public function get_id() { return $this->id; }
+  public function get_name() { return $this->name; }
+  public function get_owner() { return $this->owner; }
+}
+
+/**
+ * Represents a menu block ready for display in the Menu object.
+ */
+class DisplayBlock
+{
+  protected $_registeredBlock;
+  protected $_position;
+
+  protected $_title;
+
+  public $data;
+  public $template;
+  public $raw_content;
+
+  public function DisplayBlock($registeredBlock)
+  {
+    $this->_registeredBlock = &$registeredBlock;
+  }
+
+  public function &get_block() { return $this->_registeredBlock; }
+
+  public function get_position() { return $this->_position; }
+  public function set_position($position)
+  {
+    $this->_position = $position;
+  }
+
+  public function get_title()
+  {
+    if (isset($this->_title))
+      return $this->_title;
+    else
+      return $this->_registeredBlock->get_name();
+  }
+
+  public function set_title($title)
+  {
+    $this->_title = $title;
+  }
+}
+
+?>
Index: /tags/2.0.2/include/calendar_base.class.php
===================================================================
--- /tags/2.0.2/include/calendar_base.class.php	(revision 3278)
+++ /tags/2.0.2/include/calendar_base.class.php	(revision 3278)
@@ -0,0 +1,357 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+/**
+ * Base class for monthly and weekly calendar styles
+ */
+class CalendarBase
+{
+  // db column on which this calendar works
+  var $date_field;
+  // used for queries (INNER JOIN or normal)
+  var $inner_sql;
+  //
+  var $calendar_levels;
+
+  /**
+   * Initialize the calendar
+   * @param string inner_sql used for queries (INNER JOIN or normal)
+   */
+  function initialize($inner_sql)
+  {
+    global $page;
+    if ($page['chronology_field']=='posted')
+    {
+      $this->date_field = 'date_available';
+    }
+    else
+    {
+      $this->date_field = 'date_creation';
+    }
+    $this->inner_sql = $inner_sql;
+  }
+
+  function get_display_name()
+  {
+    global $conf, $page;
+    $res = '';
+
+    for ($i=0; $i<count($page['chronology_date']); $i++)
+    {
+      $res .= $conf['level_separator'];
+      if ( isset($page['chronology_date'][$i+1]) )
+      {
+        $chronology_date = array_slice($page['chronology_date'],0, $i+1);
+        $url = duplicate_index_url(
+            array( 'chronology_date'=>$chronology_date ),
+            array( 'start' )
+            );
+        $res .=
+          '<a href="'.$url.'">'
+          .$this->get_date_component_label($i, $page['chronology_date'][$i])
+          .'</a>';
+      }
+      else
+      {
+        $res .=
+          '<span class="calInHere">'
+          .$this->get_date_component_label($i, $page['chronology_date'][$i])
+          .'</span>';
+      }
+    }
+    return $res;
+  }
+
+//--------------------------------------------------------- private members ---
+  /**
+   * Returns a display name for a date component optionally using labels
+  */
+  function get_date_component_label($level, $date_component)
+  {
+    $label = $date_component;
+    if (isset($this->calendar_levels[$level]['labels'][$date_component]))
+    {
+      $label = $this->calendar_levels[$level]['labels'][$date_component];
+    }
+    elseif ('any' === $date_component )
+    {
+      $label = l10n('calendar_any');
+    }
+    return $label;
+  }
+
+  /**
+   * Gets a nice display name for a date to be shown in previos/next links.
+   */
+  function get_date_nice_name($date)
+  {
+    $date_components = explode('-', $date);
+    $res = '';
+    for ($i=count($date_components)-1; $i>=0; $i--)
+    {
+      if ('any' !== $date_components[$i])
+      {
+        $label = $this->get_date_component_label($i, $date_components[$i] );
+        if ( $res!='' )
+        {
+          $res .= ' ';
+        }
+        $res .= $label;
+      }
+    }
+    return $res;
+  }
+
+  /**
+   * Creates a calendar navigation bar.
+   *
+   * @param array date_components
+   * @param array items - hash of items to put in the bar (e.g. 2005,2006)
+   * @param string class_prefix - html class attribute prefix for span elements
+   * @param bool show_any - adds any link to the end of the bar
+   * @param bool show_empty - shows all labels even those without items
+   * @param array labels - optional labels for items (e.g. Jan,Feb,...)
+   * @return string the navigation bar
+   */
+  function get_nav_bar_from_items($date_components, $items,
+                                  $class_prefix, $show_any,
+                                  $show_empty=false, $labels=null)
+  {
+    global $conf, $page, $template;
+
+    $nav_bar_datas=array();
+
+    if ($conf['calendar_show_empty'] and $show_empty and !empty($labels) )
+    {
+      foreach ($labels as $item => $label)
+      {
+        if ( ! isset($items[$item]) )
+        {
+          $items[$item] = -1;
+        }
+      }
+      ksort($items);
+    }
+
+    foreach ($items as $item => $nb_images)
+    {
+      $label = $item;
+      if (isset($labels[$item]))
+      {
+        $label = $labels[$item];
+      }
+      if ($nb_images==-1)
+      {
+        $tmp_datas=array(
+          'classname' => $class_prefix."Empty",
+          'label'=> $label
+        );
+      }
+      else
+      {
+        $url = duplicate_index_url(
+          array('chronology_date'=>array_merge($date_components,array($item))),
+          array( 'start' )
+            );
+        $tmp_datas=array(
+          'classname' => $class_prefix,
+          'label'=> $label,
+          'url' => $url
+        );
+      }
+      if ($nb_images > 0)
+      {
+        $tmp_datas['nb_images']=$nb_images;
+      }
+      $nav_bar_datas[]=$tmp_datas;
+      
+    }
+
+    if ($conf['calendar_show_any'] and $show_any and count($items)>1 and
+          count($date_components)<count($this->calendar_levels)-1 )
+    {
+      $url = duplicate_index_url(
+        array('chronology_date'=>array_merge($date_components,array('any'))),
+        array( 'start' )
+          );
+      $nav_bar_datas[]=array(
+        'label' => l10n('calendar_any'),
+        'classname' => $class_prefix,
+        'url' => $url
+      );
+    }
+
+    $template->set_filenames( array( 'nav_bar' => 'calendar_navbar.tpl',));
+    $template->assign('datas', $nav_bar_datas);
+    return($template->parse('nav_bar', true));
+  }
+
+  /**
+   * Creates a calendar navigation bar for a given level.
+   *
+   * @param int level - the level (0-year,1-month/week,2-day)
+   * @return void
+   */
+  function build_nav_bar($level, $labels=null)
+  {
+    global $template, $conf, $page;
+
+    $query = '
+SELECT DISTINCT('.$this->calendar_levels[$level]['sql']
+      .') as period';
+    $query.= $this->inner_sql;
+    $query.= $this->get_date_where($level);
+    $query.= '
+  GROUP BY period
+;';
+
+    $level_items = array();
+    $result = pwg_query($query);
+    while ($row = mysql_fetch_array($result))
+    {
+      $level_items[$row['period']] = 0;
+    }
+
+    if ( count($level_items)==1 and
+         count($page['chronology_date'])<count($this->calendar_levels)-1)
+    {
+      if ( ! isset($page['chronology_date'][$level]) )
+      {
+        list($key) = array_keys($level_items);
+        $page['chronology_date'][$level] = (int)$key;
+
+        if ( $level<count($page['chronology_date']) and
+             $level!=count($this->calendar_levels)-1 )
+        {
+          return;
+        }
+      }
+    }
+
+    $dates = $page['chronology_date'];
+    while ($level<count($dates))
+    {
+      array_pop($dates);
+    }
+
+    $nav_bar = $this->get_nav_bar_from_items(
+      $dates,
+      $level_items,
+      'calItem',
+      true,
+      true,
+      isset($labels) ? $labels : $this->calendar_levels[$level]['labels']
+      );
+
+    $template->append(
+      'chronology_navigation_bars',
+      array(
+        'CONTENT' => $nav_bar,
+        )
+      );
+  }
+
+  /**
+   * Assigns the next/previous link to the template with regards to
+   * the currently choosen date.
+   */
+  function build_next_prev()
+  {
+    global $template, $page;
+    $prev = $next =null;
+    if ( empty($page['chronology_date']) )
+      return;
+    $query = 'SELECT CONCAT_WS("-"';
+    for ($i=0; $i<count($page['chronology_date']); $i++)
+    {
+      if ( 'any' === $page['chronology_date'][$i] )
+      {
+        $query .= ','.'"any"';
+      }
+      else
+      {
+        $query .= ','.$this->calendar_levels[$i]['sql'];
+      }
+    }
+    $current = implode('-', $page['chronology_date'] );
+
+    $query.=') as period' . $this->inner_sql .'
+AND ' . $this->date_field . ' IS NOT NULL
+GROUP BY period';
+
+    $upper_items = array_from_query( $query, 'period');
+
+    usort($upper_items, 'version_compare');
+    $upper_items_rank = array_flip($upper_items);
+    if ( !isset($upper_items_rank[$current]) )
+    {
+      array_push($upper_items, $current);// just in case (external link)
+      usort($upper_items, 'version_compare');
+      $upper_items_rank = array_flip($upper_items);
+    }
+    $current_rank = $upper_items_rank[$current];
+
+    $tpl_var = array();
+    
+    if ( $current_rank>0 )
+    { // has previous
+      $prev = $upper_items[$current_rank-1];
+      $chronology_date = explode('-', $prev);
+      $tpl_var['previous'] =
+        array(
+          'LABEL' => $this->get_date_nice_name($prev),
+          'URL' => duplicate_index_url(
+                array('chronology_date'=>$chronology_date), array('start')
+                )
+        );
+    }
+    
+    if ( $current_rank < count($upper_items)-1 )
+    { // has next
+      $next = $upper_items[$current_rank+1];
+      $chronology_date = explode('-', $next);
+      $tpl_var['next'] =
+        array(
+          'LABEL' => $this->get_date_nice_name($next),
+          'URL' => duplicate_index_url(
+                array('chronology_date'=>$chronology_date), array('start')
+                )
+        );
+    }
+    
+    if ( !empty($tpl_var) )
+    {
+      $existing = & $template->get_template_vars('chronology_navigation_bars');
+      if ( !empty($existing) )
+      {
+        $existing[ sizeof($existing)-1 ] =
+          array_merge( $existing[ sizeof($existing)-1 ], $tpl_var);
+      }
+      else
+      {
+        $template->append( 'chronology_navigation_bars', $tpl_var );
+      }
+    }
+  }
+}
+?>
Index: /tags/2.0.2/include/calendar_monthly.class.php
===================================================================
--- /tags/2.0.2/include/calendar_monthly.class.php	(revision 3278)
+++ /tags/2.0.2/include/calendar_monthly.class.php	(revision 3278)
@@ -0,0 +1,515 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+include_once(PHPWG_ROOT_PATH.'include/calendar_base.class.php');
+
+define ('CYEAR',  0);
+define ('CMONTH', 1);
+define ('CDAY',   2);
+
+/**
+ * Monthly calendar style (composed of years/months and days)
+ */
+class Calendar extends CalendarBase
+{
+
+  /**
+   * Initialize the calendar
+   * @param string inner_sql used for queries (INNER JOIN or normal)
+   */
+  function initialize($inner_sql)
+  {
+    parent::initialize($inner_sql);
+    global $lang;
+    $this->calendar_levels = array(
+      array(
+          'sql'=> 'YEAR('.$this->date_field.')',
+          'labels' => null
+        ),
+      array(
+          'sql'=> 'MONTH('.$this->date_field.')',
+          'labels' => $lang['month']
+        ),
+      array(
+          'sql'=> 'DAYOFMONTH('.$this->date_field.')',
+          'labels' => null
+        ),
+     );
+  }
+
+/**
+ * Generate navigation bars for category page
+ * @return boolean false to indicate that thumbnails
+ * where not included here, true otherwise
+ */
+function generate_category_content()
+{
+  global $conf, $page;
+
+  $view_type = $page['chronology_view'];
+  if ($view_type==CAL_VIEW_CALENDAR)
+  {
+    global $template;
+    $tpl_var = array();
+    if ( count($page['chronology_date'])==0 )
+    {//case A: no year given - display all years+months
+      if ($this->build_global_calendar($tpl_var))
+      {
+        $template->assign('chronology_calendar', $tpl_var);
+        return true;
+      }
+    }
+
+    if ( count($page['chronology_date'])==1 )
+    {//case B: year given - display all days in given year
+      if ($this->build_year_calendar($tpl_var))
+      {
+        $template->assign('chronology_calendar', $tpl_var);
+        $this->build_nav_bar(CYEAR); // years
+        return true;
+      }
+    }
+
+    if ( count($page['chronology_date'])==2 )
+    {//case C: year+month given - display a nice month calendar
+      if ( $this->build_month_calendar($tpl_var) )
+      {
+        $template->assign('chronology_calendar', $tpl_var);
+      }
+      $this->build_next_prev();
+      return true;
+    }
+  }
+
+  if ($view_type==CAL_VIEW_LIST or count($page['chronology_date'])==3)
+  {
+    if ( count($page['chronology_date'])==0 )
+    {
+      $this->build_nav_bar(CYEAR); // years
+    }
+    if ( count($page['chronology_date'])==1)
+    {
+      $this->build_nav_bar(CMONTH); // month
+    }
+    if ( count($page['chronology_date'])==2 )
+    {
+      $day_labels = range( 1, $this->get_all_days_in_month(
+              $page['chronology_date'][CYEAR] ,$page['chronology_date'][CMONTH] ) );
+      array_unshift($day_labels, 0);
+      unset( $day_labels[0] );
+      $this->build_nav_bar( CDAY, $day_labels ); // days
+    }
+    $this->build_next_prev();
+  }
+  return false;
+}
+
+
+/**
+ * Returns a sql where subquery for the date field
+ * @param int max_levels return the where up to this level
+ * (e.g. 2=only year and month)
+ * @return string
+ */
+function get_date_where($max_levels=3)
+{
+  global $page;
+  $date = $page['chronology_date'];
+  while (count($date)>$max_levels)
+  {
+    array_pop($date);
+  }
+  $res = '';
+  if (isset($date[CYEAR]) and $date[CYEAR]!=='any')
+  {
+    $b = $date[CYEAR] . '-';
+    $e = $date[CYEAR] . '-';
+    if (isset($date[CMONTH]) and $date[CMONTH]!=='any')
+    {
+      $b .= $date[CMONTH] . '-';
+      $e .= $date[CMONTH] . '-';
+      if (isset($date[CDAY]) and $date[CDAY]!=='any')
+      {
+        $b .= $date[CDAY];
+        $e .= $date[CDAY];
+      }
+      else
+      {
+        $b .= '01';
+        $e .= '31';
+      }
+    }
+    else
+    {
+      $b .= '01-01';
+      $e .= '12-31';
+      if (isset($date[CMONTH]) and $date[CMONTH]!=='any')
+      {
+        $res .= ' AND '.$this->calendar_levels[CMONTH]['sql'].'='.$date[CMONTH];
+      }
+      if (isset($date[CDAY]) and $date[CDAY]!=='any')
+      {
+        $res .= ' AND '.$this->calendar_levels[CDAY]['sql'].'='.$date[CDAY];
+      }
+    }
+    $res = " AND $this->date_field BETWEEN '$b' AND '$e 23:59:59'" . $res;
+  }
+  else
+  {
+    $res = ' AND '.$this->date_field.' IS NOT NULL';
+    if (isset($date[CMONTH]) and $date[CMONTH]!=='any')
+    {
+      $res .= ' AND '.$this->calendar_levels[CMONTH]['sql'].'='.$date[CMONTH];
+    }
+    if (isset($date[CDAY]) and $date[CDAY]!=='any')
+    {
+      $res .= ' AND '.$this->calendar_levels[CDAY]['sql'].'='.$date[CDAY];
+    }
+  }
+  return $res;
+}
+
+
+
+//--------------------------------------------------------- private members ---
+
+// returns an array with alll the days in a given month
+function get_all_days_in_month($year, $month)
+{
+  $md= array(1=>31,28,31,30,31,30,31,31,30,31,30,31);
+
+  if ( is_numeric($year) and $month==2)
+  {
+    $nb_days = $md[2];
+    if ( ($year%4==0)  and ( ($year%100!=0) or ($year%400!=0) ) )
+    {
+      $nb_days++;
+    }
+  }
+  elseif ( is_numeric($month) )
+  {
+    $nb_days = $md[ $month ];
+  }
+  else
+  {
+    $nb_days = 31;
+  }
+  return $nb_days;
+}
+
+function build_global_calendar(&$tpl_var)
+{
+  global $page;
+  assert( count($page['chronology_date']) == 0 );
+  $query='SELECT DISTINCT(DATE_FORMAT('.$this->date_field.',"%Y%m")) as period,
+            COUNT( DISTINCT(id) ) as count';
+  $query.= $this->inner_sql;
+  $query.= $this->get_date_where();
+  $query.= '
+  GROUP BY period
+  ORDER BY YEAR('.$this->date_field.') DESC, MONTH('.$this->date_field.')';
+
+  $result = pwg_query($query);
+  $items=array();
+  while ($row = mysql_fetch_array($result))
+  {
+    $y = substr($row['period'], 0, 4);
+    $m = (int)substr($row['period'], 4, 2);
+    if ( ! isset($items[$y]) )
+    {
+      $items[$y] = array('nb_images'=>0, 'children'=>array() );
+    }
+    $items[$y]['children'][$m] = $row['count'];
+    $items[$y]['nb_images'] += $row['count'];
+  }
+  //echo ('<pre>'. var_export($items, true) . '</pre>');
+  if (count($items)==1)
+  {// only one year exists so bail out to year view
+    list($y) = array_keys($items);
+    $page['chronology_date'][CYEAR] = $y;
+    return false;
+  }
+
+  global $lang;
+  foreach ( $items as $year=>$year_data)
+  {
+    $chronology_date = array( $year );
+    $url = duplicate_index_url( array('chronology_date'=>$chronology_date) );
+
+    $nav_bar = $this->get_nav_bar_from_items( $chronology_date,
+            $year_data['children'], 'calCal', false, false, $lang['month'] );
+
+    $tpl_var['calendar_bars'][] =
+      array(
+        'U_HEAD'  => $url,
+        'NB_IMAGES' => $year_data['nb_images'],
+        'HEAD_LABEL' => $year,
+        'NAV_BAR' => $nav_bar,
+      );
+  }
+  return true;
+}
+
+function build_year_calendar(&$tpl_var)
+{
+  global $page;
+  assert( count($page['chronology_date']) == 1 );
+  $query='SELECT DISTINCT(DATE_FORMAT('.$this->date_field.',"%m%d")) as period,
+            COUNT( DISTINCT(id) ) as count';
+  $query.= $this->inner_sql;
+  $query.= $this->get_date_where();
+  $query.= '
+  GROUP BY period';
+
+  $result = pwg_query($query);
+  $items=array();
+  while ($row = mysql_fetch_array($result))
+  {
+    $m = (int)substr($row['period'], 0, 2);
+    $d = substr($row['period'], 2, 2);
+    if ( ! isset($items[$m]) )
+    {
+      $items[$m] = array('nb_images'=>0, 'children'=>array() );
+    }
+    $items[$m]['children'][$d] = $row['count'];
+    $items[$m]['nb_images'] += $row['count'];
+  }
+  if (count($items)==1)
+  { // only one month exists so bail out to month view
+    list($m) = array_keys($items);
+    $page['chronology_date'][CMONTH] = $m;
+    return false;
+  }
+  global $lang;
+  foreach ( $items as $month=>$month_data)
+  {
+    $chronology_date = array( $page['chronology_date'][CYEAR], $month );
+    $url = duplicate_index_url( array('chronology_date'=>$chronology_date) );
+
+    $nav_bar = $this->get_nav_bar_from_items( $chronology_date,
+                     $month_data['children'], 'calCal', false );
+
+    $tpl_var['calendar_bars'][] =
+      array(
+        'U_HEAD'  => $url,
+        'NB_IMAGES' => $month_data['nb_images'],
+        'HEAD_LABEL' => $lang['month'][$month],
+        'NAV_BAR' => $nav_bar,
+      );
+  }
+  return true;
+
+}
+
+function build_month_calendar(&$tpl_var)
+{
+  global $page;
+  $query='SELECT DISTINCT(DAYOFMONTH('.$this->date_field.')) as period,
+            COUNT( DISTINCT(id) ) as count';
+  $query.= $this->inner_sql;
+  $query.= $this->get_date_where();
+  $query.= '
+  GROUP BY period';
+
+  $items=array();
+  $result = pwg_query($query);
+  while ($row = mysql_fetch_array($result))
+  {
+    $d = (int)$row['period'];
+    $items[$d] = array('nb_images'=>$row['count']);
+  }
+
+  foreach ( $items as $day=>$data)
+  {
+    $page['chronology_date'][CDAY]=$day;
+    $query = '
+SELECT id, file,tn_ext,path, width, height, DAYOFWEEK('.$this->date_field.')-1 as dow';
+    $query.= $this->inner_sql;
+    $query.= $this->get_date_where();
+    $query.= '
+  ORDER BY RAND()
+  LIMIT 0,1';
+    unset ( $page['chronology_date'][CDAY] );
+
+    $row = mysql_fetch_assoc(pwg_query($query));
+    $items[$day]['tn_url'] = get_thumbnail_url($row);
+    $items[$day]['file'] = $row['file'];
+    $items[$day]['path'] = $row['path'];
+    $items[$day]['tn_ext'] = @$row['tn_ext'];
+    $items[$day]['width'] = $row['width'];
+    $items[$day]['height'] = $row['height'];
+    $items[$day]['dow'] = $row['dow'];
+  }
+
+  global $lang, $conf;
+
+  if ( !empty($items)
+      and $conf['calendar_month_cell_width']>0
+      and $conf['calendar_month_cell_height']>0)
+  {
+    list($known_day) = array_keys($items);
+    $known_dow = $items[$known_day]['dow'];
+    $first_day_dow = ($known_dow-($known_day-1))%7;
+    if ($first_day_dow<0)
+    {
+      $first_day_dow += 7;
+    }
+    //first_day_dow = week day corresponding to the first day of this month
+    $wday_labels = $lang['day'];
+
+    // BEGIN - pass now in week starting Monday
+    if ($first_day_dow==0)
+    {
+      $first_day_dow = 6;
+    }
+    else
+    {
+      $first_day_dow -= 1;
+    }
+    array_push( $wday_labels, array_shift($wday_labels) );
+    // END - pass now in week starting Monday
+
+    $cell_width = $conf['calendar_month_cell_width'];
+    $cell_height = $conf['calendar_month_cell_height'];
+
+    $tpl_weeks    = array();
+    $tpl_crt_week = array();
+
+    //fill the empty days in the week before first day of this month
+    for ($i=0; $i<$first_day_dow; $i++)
+    {
+      $tpl_crt_week[] = array();
+    }
+
+    for ( $day = 1;
+          $day <= $this->get_all_days_in_month(
+            $page['chronology_date'][CYEAR], $page['chronology_date'][CMONTH]
+              );
+          $day++)
+    {
+      $dow = ($first_day_dow + $day-1)%7;
+      if ($dow==0 and $day!=1)
+      {
+        $tpl_weeks[]    = $tpl_crt_week; // add finished week to week list
+        $tpl_crt_week   = array(); // start new week
+      }
+
+      if ( !isset($items[$day]) )
+      {// empty day
+        $tpl_crt_week[]   =
+          array(
+              'DAY' => $day
+            );
+      }
+      else
+      {
+        $thumb = get_thumbnail_path($items[$day]);
+        $tn_size = @getimagesize($thumb);
+
+        $tn_width = $tn_size[0];
+        $tn_height = $tn_size[1];
+
+        // now need to fit the thumbnail of size tn_size within
+        // a cell of size cell_size by playing with CSS position (left/top)
+        // and the width and height of <img>.
+        $ratio_w = $tn_width/$cell_width;
+        $ratio_h = $tn_height/$cell_height;
+
+        $pos_top=$pos_left=0;
+        $css_style = '';
+
+        if ( $ratio_w>1 and $ratio_h>1)
+        {// cell completely smaller than the thumbnail so we will let the browser
+         // resize the thumbnail
+          if ($ratio_w > $ratio_h )
+          {// thumbnail ratio compared to cell -> wide format
+            $css_style = 'height:'.$cell_height.'px;';
+            $browser_img_width = $cell_height*$tn_width/$tn_height;
+            $pos_left = ($browser_img_width-$cell_width)/2;
+          }
+          else
+          {
+            $css_style = 'width:'.$cell_width.'px;';
+            $browser_img_height = $cell_width*$tn_height/$tn_width;
+            $pos_top = ($browser_img_height-$cell_height)/2;
+          }
+        }
+        else
+        {
+          $pos_left = ($tn_width-$cell_width)/2;
+          $pos_top = ($tn_height-$cell_height)/2;
+        }
+
+        if ( round($pos_left)!=0)
+        {
+          $css_style.='left:'.round(-$pos_left).'px;';
+        }
+        if ( round($pos_top)!=0)
+        {
+          $css_style.='top:'.round(-$pos_top).'px;';
+        }
+        $url = duplicate_index_url(
+            array(
+              'chronology_date' =>
+                array(
+                  $page['chronology_date'][CYEAR],
+                  $page['chronology_date'][CMONTH],
+                  $day
+                )
+            )
+          );
+
+        $tpl_crt_week[]   =
+          array(
+              'DAY'         => $day,
+              'DOW'         => $dow,
+              'NB_ELEMENTS' => $items[$day]['nb_images'],
+              'IMAGE'       => $items[$day]['tn_url'],
+              'U_IMG_LINK'  => $url,
+              'IMAGE_STYLE' => $css_style,
+              'IMAGE_ALT'   => $items[$day]['file'],
+            );
+      }
+    }
+    //fill the empty days in the week after the last day of this month
+    while ( $dow<6 )
+    {
+      $tpl_crt_week[] = array();
+      $dow++;
+    }
+    $tpl_weeks[]    = $tpl_crt_week;
+
+    $tpl_var['month_view'] =
+        array(
+           'CELL_WIDTH'   => $cell_width,
+           'CELL_HEIGHT' => $cell_height,
+           'wday_labels' => $wday_labels,
+           'weeks' => $tpl_weeks,
+          );
+  }
+
+  return true;
+}
+
+}
+?>
Index: /tags/2.0.2/include/calendar_weekly.class.php
===================================================================
--- /tags/2.0.2/include/calendar_weekly.class.php	(revision 3278)
+++ /tags/2.0.2/include/calendar_weekly.class.php	(revision 3278)
@@ -0,0 +1,136 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+include_once(PHPWG_ROOT_PATH.'include/calendar_base.class.php');
+
+define ('CYEAR', 0);
+define ('CWEEK', 1);
+define ('CDAY',  2);
+
+/**
+ * Weekly calendar style (composed of years/week in years and days in week)
+ */
+class Calendar extends CalendarBase
+{
+
+  /**
+   * Initialize the calendar
+   * @param string inner_sql used for queries (INNER JOIN or normal)
+   */
+  function initialize($inner_sql)
+  {
+    parent::initialize($inner_sql);
+    global $lang;
+    $week_no_labels=array();
+    for ($i=1; $i<=53; $i++)
+    {
+      $week_no_labels[$i] = sprintf( l10n("Week %d"), $i);
+      //$week_no_labels[$i] = $i;
+    }
+
+    $this->calendar_levels = array(
+      array(
+          'sql'=> 'YEAR('.$this->date_field.')',
+          'labels' => null
+        ),
+      array(
+          'sql'=> 'WEEK('.$this->date_field.')+1',
+          'labels' => $week_no_labels,
+        ),
+      array(
+          'sql'=> 'DAYOFWEEK('.$this->date_field.')-1',
+          'labels' => $lang['day']
+        ),
+     );
+    //Comment next lines for week starting on Sunday or if MySQL version<4.0.17
+    //WEEK(date,5) = "0-53 - Week 1=the first week with a Monday in this year"
+    $this->calendar_levels[CWEEK]['sql'] = 'WEEK('.$this->date_field.',5)+1';
+    $this->calendar_levels[CDAY]['sql'] = 'WEEKDAY('.$this->date_field.')';
+    array_push( $this->calendar_levels[CDAY]['labels'],
+                array_shift( $this->calendar_levels[CDAY]['labels'] ) );
+  }
+
+/**
+ * Generate navigation bars for category page
+ * @return boolean false to indicate that thumbnails where not included here
+ */
+function generate_category_content()
+{
+  global $conf, $page;
+
+  if ( count($page['chronology_date'])==0 )
+  {
+    $this->build_nav_bar(CYEAR); // years
+  }
+  if ( count($page['chronology_date'])==1 )
+  {
+    $this->build_nav_bar(CWEEK, array()); // week nav bar 1-53
+  }
+  if ( count($page['chronology_date'])==2 )
+  {
+    $this->build_nav_bar(CDAY); // days nav bar Mon-Sun
+  }
+  $this->build_next_prev();
+  return false;
+}
+
+
+/**
+ * Returns a sql where subquery for the date field
+ * @param int max_levels return the where up to this level
+ * (e.g. 2=only year and week in year)
+ * @return string
+ */
+function get_date_where($max_levels=3)
+{
+  global $page;
+  $date = $page['chronology_date'];
+  while (count($date)>$max_levels)
+  {
+    array_pop($date);
+  }
+  $res = '';
+  if (isset($date[CYEAR]) and $date[CYEAR]!=='any')
+  {
+    $y = $date[CYEAR];
+    $res = " AND $this->date_field BETWEEN '$y-01-01' AND '$y-12-31 23:59:59'";
+  }
+
+  if (isset($date[CWEEK]) and $date[CWEEK]!=='any')
+  {
+    $res .= ' AND '.$this->calendar_levels[CWEEK]['sql'].'='.$date[CWEEK];
+  }
+  if (isset($date[CDAY]) and $date[CDAY]!=='any')
+  {
+    $res .= ' AND '.$this->calendar_levels[CDAY]['sql'].'='.$date[CDAY];
+  }
+  if (empty($res))
+  {
+    $res = ' AND '.$this->date_field.' IS NOT NULL';
+  }
+  return $res;
+}
+
+}
+
+?>
Index: /tags/2.0.2/include/category_cats.inc.php
===================================================================
--- /tags/2.0.2/include/category_cats.inc.php	(revision 3278)
+++ /tags/2.0.2/include/category_cats.inc.php	(revision 3278)
@@ -0,0 +1,307 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+/**
+ * This file is included by the main page to show thumbnails for a category
+ * that have only subcategories or to show recent categories
+ *
+ */
+
+if ($page['section']=='recent_cats')
+{
+  // $user['forbidden_categories'] including with USER_CACHE_CATEGORIES_TABLE
+  $query = '
+SELECT
+  c.*, nb_images, date_last, max_date_last, count_images, count_categories
+  FROM '.CATEGORIES_TABLE.' c INNER JOIN '.USER_CACHE_CATEGORIES_TABLE.'
+  ON id = cat_id and user_id = '.$user['id'].'
+  WHERE date_last >= SUBDATE(
+    CURRENT_DATE,INTERVAL '.$user['recent_period'].' DAY
+  )
+'.get_sql_condition_FandF
+  (
+    array
+      (
+        'visible_categories' => 'id',
+      ),
+    'AND'
+  ).'
+;';
+}
+else
+{
+  // $user['forbidden_categories'] including with USER_CACHE_CATEGORIES_TABLE
+  $query = '
+SELECT
+  c.*, nb_images, date_last, max_date_last, count_images, count_categories
+  FROM '.CATEGORIES_TABLE.' c INNER JOIN '.USER_CACHE_CATEGORIES_TABLE.'
+  ON id = cat_id and user_id = '.$user['id'].'
+  WHERE id_uppercat '.
+  (!isset($page['category']) ? 'is NULL' : '= '.$page['category']['id']).'
+'.get_sql_condition_FandF
+  (
+    array
+      (
+        'visible_categories' => 'id',
+      ),
+    'AND'
+  ).'
+  ORDER BY rank
+;';
+}
+
+$result = pwg_query($query);
+$categories = array();
+$category_ids = array();
+$image_ids = array();
+
+while ($row = mysql_fetch_assoc($result))
+{
+  $row['is_child_date_last'] = @$row['max_date_last']>@$row['date_last'];
+
+  if (isset($row['representative_picture_id'])
+      and is_numeric($row['representative_picture_id']))
+  { // if a representative picture is set, it has priority
+    $image_id = $row['representative_picture_id'];
+  }
+  else if ($conf['allow_random_representative'])
+  {// searching a random representant among elements in sub-categories
+    if ($row['count_images']>0)
+    {
+      $query = '
+SELECT image_id
+  FROM '.CATEGORIES_TABLE.' AS c INNER JOIN '.IMAGE_CATEGORY_TABLE.' AS ic
+    ON ic.category_id = c.id';
+      $query.= '
+  WHERE (c.id='.$row['id'].' OR uppercats LIKE \''.$row['uppercats'].',%\')'
+    .get_sql_condition_FandF
+    (
+      array
+        (
+          'forbidden_categories' => 'c.id',
+          'visible_categories' => 'c.id',
+          'visible_images' => 'image_id'
+        ),
+      "\n  AND"
+    ).'
+  ORDER BY RAND()
+  LIMIT 0,1
+;';
+      $subresult = pwg_query($query);
+      if (mysql_num_rows($subresult) > 0)
+      {
+        list($image_id) = mysql_fetch_row($subresult);
+      }
+    }
+  }
+  else
+  { // searching a random representant among representant of sub-categories
+    if ($row['count_categories']>0 and $row['count_images']>0)
+    {
+      $query = '
+  SELECT representative_picture_id
+    FROM '.CATEGORIES_TABLE.' INNER JOIN '.USER_CACHE_CATEGORIES_TABLE.'
+    ON id = cat_id and user_id = '.$user['id'].'
+    WHERE uppercats LIKE \''.$row['uppercats'].',%\'
+      AND representative_picture_id IS NOT NULL'
+    .get_sql_condition_FandF
+    (
+      array
+        (
+          'visible_categories' => 'id',
+        ),
+      "\n  AND"
+    ).'
+    ORDER BY RAND()
+    LIMIT 0,1
+  ;';
+      $subresult = pwg_query($query);
+      if (mysql_num_rows($subresult) > 0)
+      {
+        list($image_id) = mysql_fetch_row($subresult);
+      }
+    }
+  }
+
+  if (isset($image_id))
+  {
+    $row['representative_picture_id'] = $image_id;
+    array_push($image_ids, $image_id);
+    array_push($categories, $row);
+    array_push($category_ids, $row['id']);
+  }
+  unset($image_id);
+}
+
+if ($conf['display_fromto'])
+{
+  $dates_of_category = array();
+  if (count($category_ids) > 0)
+  {
+    $query = '
+SELECT
+    category_id,
+    MIN(date_creation) AS date_creation_min,
+    MAX(date_creation) AS date_creation_max
+  FROM '.IMAGE_CATEGORY_TABLE.'
+    INNER JOIN '.IMAGES_TABLE.' ON image_id = id
+  WHERE category_id IN ('.implode(',', $category_ids).')
+'.get_sql_condition_FandF
+  (
+    array
+      (
+        'visible_categories' => 'category_id',
+        'visible_images' => 'id'
+      ),
+    'AND'
+  ).'
+  GROUP BY category_id
+;';
+    $result = pwg_query($query);
+    while ($row = mysql_fetch_array($result))
+    {
+      $dates_of_category[ $row['category_id'] ] = array(
+        'from' => $row['date_creation_min'],
+        'to'   => $row['date_creation_max'],
+        );
+    }
+  }
+}
+
+if ($page['section']=='recent_cats')
+{
+  usort($categories, 'global_rank_compare');
+}
+if (count($categories) > 0)
+{
+  $thumbnail_src_of = array();
+
+  $query = '
+SELECT id, path, tn_ext
+  FROM '.IMAGES_TABLE.'
+  WHERE id IN ('.implode(',', $image_ids).')
+;';
+  $result = pwg_query($query);
+  while ($row = mysql_fetch_assoc($result))
+  {
+    $thumbnail_src_of[$row['id']] = get_thumbnail_url($row);
+  }
+}
+
+if (count($categories) > 0)
+{
+  // Update filtered data
+  if (function_exists('update_cats_with_filtered_data'))
+  {
+    update_cats_with_filtered_data($categories);
+  }
+
+  $template->set_filename('index_category_thumbnails', 'mainpage_categories.tpl');
+
+  trigger_action('loc_begin_index_category_thumbnails', $categories);
+
+  $tpl_thumbnails_var = array();
+
+  foreach ($categories as $category)
+  {
+    $category['name'] = trigger_event(
+        'render_category_name',
+        $category['name'],
+        'subcatify_category_name'
+        );
+
+    if ($page['section']=='recent_cats')
+    {
+      $name = get_cat_display_name_cache($category['uppercats'], null, false);
+    }
+    else
+    {
+      $name = $category['name'];
+    }
+
+    $tpl_var =
+        array(
+          'ID'    => $category['id'],
+          'TN_SRC'   => $thumbnail_src_of[$category['representative_picture_id']],
+          'TN_ALT'   => strip_tags($category['name']),
+          'ICON_TS'  => get_icon($category['max_date_last'], $category['is_child_date_last']),
+
+          'URL'   => make_index_url(
+            array(
+              'category' => $category
+              )
+            ),
+          'CAPTION_NB_IMAGES' => get_display_images_count
+                                  (
+                                    $category['nb_images'],
+                                    $category['count_images'],
+                                    $category['count_categories'],
+                                    true,
+                                    '<br />'
+                                  ),
+          'DESCRIPTION' =>
+            trigger_event('render_category_literal_description',
+              trigger_event('render_category_description',
+                @$category['comment'],
+                'subcatify_category_description')),
+          'NAME'  => $name,
+        );
+
+    if ($conf['display_fromto'])
+    {
+      if (isset($dates_of_category[ $category['id'] ]))
+      {
+        $from = $dates_of_category[ $category['id'] ]['from'];
+        $to   = $dates_of_category[ $category['id'] ]['to'];
+
+        if (!empty($from))
+        {
+          $info = '';
+
+          if ($from == $to)
+          {
+            $info = format_date($from);
+          }
+          else
+          {
+            $info = sprintf(
+              l10n('from %s to %s'),
+              format_date($from),
+              format_date($to)
+              );
+          }
+          $tpl_var['INFO_DATES'] = $info;
+        }
+      }
+    }//fromto
+
+    $tpl_thumbnails_var[] = $tpl_var;
+  }
+
+  $tpl_thumbnails_var = trigger_event('loc_end_index_category_thumbnails', $tpl_thumbnails_var, $categories);
+  $template->assign( 'category_thumbnails', $tpl_thumbnails_var);
+
+  $template->assign_var_from_handle('CATEGORIES', 'index_category_thumbnails');
+}
+pwg_debug('end include/category_cats.inc.php');
+?>
Index: /tags/2.0.2/include/category_default.inc.php
===================================================================
--- /tags/2.0.2/include/category_default.inc.php	(revision 3278)
+++ /tags/2.0.2/include/category_default.inc.php	(revision 3278)
@@ -0,0 +1,180 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+/**
+ * This file is included by the main page to show thumbnails for the default
+ * case
+ *
+ */
+
+$pictures = array();
+
+$selection = array_slice(
+  $page['items'],
+  $page['start'],
+  $page['nb_image_page']
+  );
+
+if (count($selection) > 0)
+{
+  $rank_of = array_flip($page['items']);
+
+  $query = '
+SELECT *
+  FROM '.IMAGES_TABLE.'
+  WHERE id IN ('.implode(',', $selection).')
+;';
+  $result = pwg_query($query);
+  while ($row = mysql_fetch_assoc($result))
+  {
+    $row['rank'] = $rank_of[ $row['id'] ];
+
+    array_push($pictures, $row);
+  }
+
+  usort($pictures, 'rank_compare');
+  unset($rank_of);
+}
+
+if (count($pictures) > 0)
+{
+  // define category slideshow url
+  $row = reset($pictures);
+  $page['cat_slideshow_url'] =
+    add_url_params(
+      duplicate_picture_url(
+        array(
+          'image_id' => $row['id'],
+          'image_file' => $row['file']
+        ),
+        array('start')
+      ),
+      array('slideshow' =>
+        (isset($_GET['slideshow']) ? $_GET['slideshow']
+                                   : '' ))
+    );
+
+  if ($user['show_nb_comments'])
+  {
+    $query = '
+SELECT image_id, COUNT(*) AS nb_comments
+  FROM '.COMMENTS_TABLE.'
+  WHERE validated = \'true\'
+    AND image_id IN ('.implode(',', $selection).')
+  GROUP BY image_id
+;';
+    $nb_comments_of = simple_hash_from_query($query, 'image_id', 'nb_comments');
+  }
+}
+
+// template thumbnail initialization
+$template->set_filenames( array( 'index_thumbnails' => 'thumbnails.tpl',));
+
+trigger_action('loc_begin_index_thumbnails', $pictures);
+$tpl_thumbnails_var = array();
+
+foreach ($pictures as $row)
+{
+  // link on picture.php page
+  $url = duplicate_picture_url(
+        array(
+          'image_id' => $row['id'],
+          'image_file' => $row['file']
+        ),
+        array('start')
+      );
+
+  $tpl_var =
+    array(
+      'ID'        => $row['id'],
+      'TN_SRC'    => get_thumbnail_url($row),
+      'TN_ALT'    => $row['file'],
+      'TN_TITLE'  => get_thumbnail_title($row),
+      'ICON_TS'   => get_icon($row['date_available']),
+      'URL'       => $url,
+
+   /* Fields for template-extension usage */
+      'FILE_PATH' => $row['path'],
+      'FILE_POSTED' => $row['date_available'],
+      'FILE_CREATED' => $row['date_creation'],
+      'FILE_DESC' => $row['comment'],
+      'FILE_AUTHOR' => $row['author'],
+      'FILE_HIT' => $row['hit'],
+      'FILE_SIZE' => $row['filesize'],
+      'FILE_WIDTH' => $row['width'],
+      'FILE_HEIGHT' => $row['height'],
+      'FILE_METADATE' => $row['date_metadata_update'],
+      'FILE_HAS_HD' => ($row['has_high'] and $user['enabled_high']=='true') ?
+                true:false, /* lack of include/functions_picture.inc.php */
+    );
+
+  if ($user['show_nb_hits'])
+  {
+    $tpl_var['NB_HITS'] = $row['hit'];
+  }
+
+  if ($conf['show_thumbnail_caption'])
+  {// name of the picture
+    if (isset($row['name']) and $row['name'] != '')
+    {
+      $name = $row['name'];
+    }
+    else
+    {
+      $name = str_replace('_', ' ', get_filename_wo_extension($row['file']));
+    }
+
+    switch ($page['section'])
+    {
+      case 'best_rated' :
+      {
+        $name = '('.$row['average_rate'].') '.$name;
+        break;
+      }
+      case 'most_visited' :
+      {
+        if ( !$user['show_nb_hits']) {
+          $name = '('.$row['hit'].') '.$name;
+        }
+        break;
+      }
+    }
+
+    $tpl_var['NAME'] = $name;
+  }
+
+  if ( isset($nb_comments_of) )
+  {
+    $tpl_var['NB_COMMENTS'] = (int)@$nb_comments_of[$row['id']];
+  }
+
+  $tpl_thumbnails_var[] = $tpl_var;
+}
+
+$tpl_thumbnails_var = trigger_event('loc_end_index_thumbnails', $tpl_thumbnails_var, $pictures);
+$template->assign('thumbnails', $tpl_thumbnails_var);
+
+$template->assign_var_from_handle('THUMBNAILS', 'index_thumbnails');
+
+pwg_debug('end include/category_default.inc.php');
+?>
Index: /tags/2.0.2/include/class_smtp_mail.inc.php
===================================================================
--- /tags/2.0.2/include/class_smtp_mail.inc.php	(revision 3278)
+++ /tags/2.0.2/include/class_smtp_mail.inc.php	(revision 3278)
@@ -0,0 +1,183 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// These function were originally a part of the punBB.
+
+class smtp_mail
+{
+  var $socket;
+  var $no_error;
+  var $host;
+  var $user;
+  var $password;
+  var $email_webmaster;
+
+  function smtp_mail($host, $user, $password, $email_webmaster)
+  {
+    $this->host = $host;
+    $this->user = $user;
+    $this->password = $password;
+    $this->email_webmaster = $email_webmaster;
+  }
+
+  // Adaptation of server_parse
+  function server_parse($expected_response)
+  {
+    if ($this->no_error)
+    {
+      $server_response = '';
+      while (substr($server_response, 3, 1) != ' ')
+      {
+        if (!($server_response = fgets($this->socket, 256)))
+        {
+          trigger_error('Couldn\'t get mail server response codes.', E_USER_WARNING);
+          $this->no_error = false;
+        }
+      }
+    }
+
+    if ($this->no_error)
+    {
+      if (!(substr($server_response, 0, 3) == $expected_response))
+      {
+        trigger_error('Unable to send e-mail. Error message reported by the SMTP server: "'.$server_response.'"', E_USER_WARNING);
+        $this->no_error = false;
+      }
+    }
+    return $this->no_error;
+  }
+
+  function server_write($s)
+  {
+    $this->no_error = $this->no_error && (fwrite($this->socket, $s) !== false);
+    return $this->no_error;
+  }
+
+  function add_recipients(&$recipients, $headers, $type_header)
+  {
+    if (preg_match('/^\s*'.$type_header.'\s*:.*/mi', $headers, $matches) != 0)
+    {
+      $list = explode(',', $matches[0]);
+      foreach ($list as $email)
+      {
+        if (strpos($email, '<') !== false)
+        {
+           $email = preg_replace('/.*<(.*)>.*/i', '$1', $email);
+        }
+        $recipients[] = trim($email);
+      }
+    }
+  }
+
+  // Adaptation of pun_mail
+  function mail($to, $subject, $message, $headers = '')
+  {
+    $this->no_error = true;
+
+    // Are we using port 25 or a custom port?
+    if (strpos($this->host, ':') !== false)
+    {
+      list($smtp_host, $smtp_port) = explode(':', $this->host);
+    }
+    else
+    {
+      $smtp_host = $this->host;
+      $smtp_port = 25;
+    }
+
+    if ($this->socket = fsockopen($smtp_host, $smtp_port, $errno, $errstr, 15))
+    {
+      $this->server_parse('220');
+
+      if (!empty($this->user) && !empty($this->password))
+      {
+        $this->server_write('EHLO '.$smtp_host."\r\n");
+        $this->server_parse('250');
+
+        $this->server_write('AUTH LOGIN'."\r\n");
+        $this->server_parse('334');
+
+        $this->server_write(base64_encode($this->user)."\r\n");
+        $this->no_error = $this->no_error && $this->no_error = $this->server_parse('334');
+
+        $this->server_write(base64_encode($this->password)."\r\n");
+        $this->server_parse('235');
+      }
+      else
+      {
+        $this->server_write('HELO '.$smtp_host."\r\n");
+        $this->server_parse('250');
+      }
+
+      $this->server_write('MAIL FROM:<'.$this->email_webmaster.'>'."\r\n");
+      $this->server_parse('250');
+
+      if ((preg_match('/^\s*to\s*:.*/mi', $headers) === 0) and !empty($to))
+      {
+        $to_header = 'To:'.implode(',', array_map(create_function('$email','return "<".$email.">";'), explode(',', $to)));
+      }
+      else
+      {
+        $to_header = '';
+      }
+
+      if (!empty($to))
+      {
+        $recipients = explode(',', $to);
+      }
+      else
+      {
+        $recipients = array();
+      }
+
+      $this->add_recipients($recipients, $headers, 'Cc');
+      $this->add_recipients($recipients, $headers, 'Bcc');
+
+      @reset($recipients);
+      while (list(, $email) = @each($recipients))
+      {
+        $this->server_write('RCPT TO:<'.$email.'>'."\r\n");
+        $this->server_parse('250');
+      }
+
+      $this->server_write('DATA'."\r\n");
+      $this->server_parse('354');
+
+      $this->server_write('Subject:'.$subject."\r\n".(empty($to_header) ? "" : $to_header."\r\n").$headers."\r\n\r\n".$message."\r\n");
+      $this->server_write('.'."\r\n");
+      $this->server_parse('250');
+
+      $this->server_write('QUIT'."\r\n");
+      fclose($this->socket);
+    }
+    else
+    {
+      trigger_error('Could not connect to smtp host "'.$this->host.'" ('.$errno.') ('.$errstr.')', E_USER_WARNING);
+      $this->no_error = false;;
+    }
+
+    return $this->no_error;
+  }
+}
+
+?>
Index: /tags/2.0.2/include/common.inc.php
===================================================================
--- /tags/2.0.2/include/common.inc.php	(revision 3278)
+++ /tags/2.0.2/include/common.inc.php	(revision 3278)
@@ -0,0 +1,240 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+defined('PHPWG_ROOT_PATH') or trigger_error('Hacking attempt!', E_USER_ERROR);
+
+// determine the initial instant to indicate the generation time of this page
+$t1 = explode( ' ', microtime() );
+$t2 = explode( '.', $t1[0] );
+$t2 = $t1[1].'.'.$t2[1];
+
+set_magic_quotes_runtime(0); // Disable magic_quotes_runtime
+
+//
+// addslashes to vars if magic_quotes_gpc is off this is a security
+// precaution to prevent someone trying to break out of a SQL statement.
+//
+if( !get_magic_quotes_gpc() )
+{
+  function sanitize_mysql_kv(&$v, $k)
+  {
+    $v = addslashes($v);
+  }
+  if( is_array( $_GET ) )
+  {
+    array_walk_recursive( $_GET, 'sanitize_mysql_kv' );
+  }
+  if( is_array( $_POST ) )
+  {
+    array_walk_recursive( $_POST, 'sanitize_mysql_kv' );
+  }
+  if( is_array( $_COOKIE ) )
+  {
+    array_walk_recursive( $_COOKIE, 'sanitize_mysql_kv' );
+  }
+}
+if ( !empty($_SERVER["PATH_INFO"]) )
+{
+  $_SERVER["PATH_INFO"] = addslashes($_SERVER["PATH_INFO"]);
+}
+
+//
+// Define some basic configuration arrays this also prevents malicious
+// rewriting of language and otherarray values via URI params
+//
+$conf = array();
+$page = array();
+$user = array();
+$lang = array();
+$header_msgs = array();
+$header_notes = array();
+$filter = array();
+
+@include(PHPWG_ROOT_PATH .'include/mysql.inc.php');
+if (!defined('PHPWG_INSTALLED'))
+{
+  header('Location: install.php');
+  exit;
+}
+
+foreach( array(
+  'array_intersect_key', //PHP 5 >= 5.1.0RC1
+  'hash_hmac', //(hash) - enabled by default as of PHP 5.1.2
+  'preg_last_error', // PHP 5 >= 5.2.0
+  'file_put_contents', //PHP5
+  ) as $func)
+{
+  if (!function_exists($func))
+  {
+    include_once(PHPWG_ROOT_PATH . 'include/php_compat/'.$func.'.php');
+  }
+}
+
+include(PHPWG_ROOT_PATH . 'include/config_default.inc.php');
+@include(PHPWG_ROOT_PATH. 'include/config_local.inc.php');
+
+if(isset($conf['show_php_errors']) && !empty($conf['show_php_errors']))
+{
+  @ini_set('error_reporting', $conf['show_php_errors']);
+  @ini_set('display_errors', true);
+}
+
+include(PHPWG_ROOT_PATH . 'include/constants.php');
+include(PHPWG_ROOT_PATH . 'include/functions.inc.php');
+include( PHPWG_ROOT_PATH .'include/template.class.php');
+
+// Database connection
+@mysql_connect( $cfgHote, $cfgUser, $cfgPassword ) or my_error( 'mysql_connect', true );
+@mysql_select_db( $cfgBase ) or my_error( 'mysql_select_db', true );
+
+defined('PWG_CHARSET') and defined('DB_CHARSET')
+  or fatal_error('PWG_CHARSET and/or DB_CHARSET is not defined');
+if ( version_compare(mysql_get_server_info(), '4.1.0', '>=') )
+{
+  if (DB_CHARSET!='')
+  {
+    pwg_query('SET NAMES "'.DB_CHARSET.'"');
+  }
+}
+elseif ( strtolower(PWG_CHARSET)!='iso-8859-1' )
+{
+  fatal_error('PWG supports only iso-8859-1 charset on MySql version '.mysql_get_server_info());
+}
+
+load_conf_from_db();
+load_plugins();
+
+include(PHPWG_ROOT_PATH.'include/user.inc.php');
+
+if ('fr_FR' == $user['language']) {
+  define('PHPWG_DOMAIN', 'fr.piwigo.org');
+}
+else if ('it_IT' == $user['language']) {
+  define('PHPWG_DOMAIN', 'it.piwigo.org');
+}
+else {
+  define('PHPWG_DOMAIN', 'piwigo.org');
+}
+define('PHPWG_URL', 'http://'.PHPWG_DOMAIN);
+define('PEM_URL', 'http://'.PHPWG_DOMAIN.'/ext');
+
+
+// language files
+load_language('common.lang');
+if ( is_admin() || (defined('IN_ADMIN') and IN_ADMIN) )
+{
+  load_language('admin.lang');
+}
+trigger_action('loading_lang');
+load_language('local.lang', '', array('no_fallback'=>true) );
+
+// only now we can set the localized username of the guest user (and not in
+// include/user.inc.php)
+if (is_a_guest())
+{
+  $user['username'] = l10n('guest');
+}
+
+// template instance
+if ( defined('IN_ADMIN') and IN_ADMIN )
+{// Admin template
+  list($user['admin_template'], $user['admin_theme']) =
+    explode ('/', $conf['admin_layout']);
+  $template = new Template(PHPWG_ROOT_PATH.'admin/template/'
+    . $user['admin_template'], $user['admin_theme'] );
+}
+else
+{ // Classic template
+  $template = new Template(PHPWG_ROOT_PATH.'template/'
+    . $user['template'], $user['theme'] );
+}
+
+if (isset($user['internal_status']['guest_must_be_guest'])
+    and
+    $user['internal_status']['guest_must_be_guest'] === true)
+{
+  $header_msgs[] = l10n('guest_must_be_guest');
+}
+
+if ($conf['gallery_locked'])
+{
+  $header_msgs[] = l10n('gallery_locked_message');
+
+  if ( script_basename() != 'identification' and !is_admin() )
+  {
+    set_status_header(503, 'Service Unavailable');
+    @header('Retry-After: 900');
+    header('Content-Type: text/html; charset='.get_pwg_charset());
+    echo '<a href="'.get_absolute_root_url(false).'identification.php">'.l10n('gallery_locked_message').'</a>';
+    echo str_repeat( ' ', 512); //IE6 doesn't error output if below a size
+    exit();
+  }
+}
+
+if ($conf['check_upgrade_feed'])
+{
+  include_once(PHPWG_ROOT_PATH.'admin/include/functions_upgrade.php');
+  if (check_upgrade_feed())
+  {
+    $header_msgs[] = 'Some database upgrades are missing, '
+      .'<a href="'.get_absolute_root_url(false).'upgrade_feed.php">upgrade now</a>';
+  }
+}
+
+if (is_adviser())
+{
+  $header_msgs[] = l10n('adviser_mode_enabled');
+}
+
+if (count($header_msgs) > 0)
+{
+  $template->assign('header_msgs', $header_msgs);
+  $header_msgs=array();
+}
+
+if (!empty($conf['filter_pages']) and get_filter_page_value('used'))
+{
+  include(PHPWG_ROOT_PATH.'include/filter.inc.php');
+}
+else
+{
+  $filter['enabled'] = false;
+}
+
+if (isset($conf['header_notes']))
+{
+  $header_notes = array_merge($header_notes, $conf['header_notes']);
+}
+
+// default event handlers
+add_event_handler('render_category_literal_description', 'render_category_literal_description');
+if ( !$conf['allow_html_descriptions'] )
+{
+  add_event_handler('render_category_description', 'nl2br');
+}
+add_event_handler('render_comment_content', 'htmlspecialchars');
+add_event_handler('render_comment_content', 'parse_comment_content');
+add_event_handler('render_comment_author', 'strip_tags');
+add_event_handler('blockmanager_register_blocks', 'register_default_menubar_blocks', EVENT_HANDLER_PRIORITY_NEUTRAL-1);
+trigger_action('init');
+?>
Index: /tags/2.0.2/include/config_default.inc.php
===================================================================
--- /tags/2.0.2/include/config_default.inc.php	(revision 3278)
+++ /tags/2.0.2/include/config_default.inc.php	(revision 3278)
@@ -0,0 +1,723 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+/**
+ *                           configuration page
+ *
+ * Set configuration parameters that are not in the table config. In the
+ * application, configuration parameters are considered in the same way
+ * coming from config table or config_default.inc.php.
+ *
+ * It is recommended to let config_default.inc.php as provided and to
+ * overwrite configuration in your local configuration file
+ * config_local.inc.php. See tools/config_local.inc.php as an example.
+ *
+ * Why having some parameters in config table and others in
+ * config_*.inc.php? Modifying config_*.inc.php is a "hard" task for low
+ * skilled users, they need a GUI for this : admin/configuration. But only
+ * parameters that might be modified by low skilled users are in config
+ * table, other parameters are in config_*.inc.php
+ */
+
+// +-----------------------------------------------------------------------+
+// |                                 misc                                  |
+// +-----------------------------------------------------------------------+
+
+// order_by : how to change the order of display for images in a category ?
+//
+// There are several fields that can order the display :
+//
+//  - date_available : the date of the adding to the gallery
+//  - file : the name of the file
+//  - id : element identifier
+//  - date_creation : date of element creation
+//
+// Once you've chosen which field(s) to use for ordering, you must chose the
+// ascending or descending order for each field.  examples :
+//
+// 1. $conf['order_by'] = " order by date_available desc, file asc";
+//    will order pictures by date_available descending & by filename ascending
+//
+// 2. $conf['order_by'] = " order by file asc";
+//    will only order pictures by file ascending without taking into account
+//    the date_available
+$conf['order_by'] = ' ORDER BY date_available DESC, file ASC, id ASC';
+
+// order_by_inside_category : inside a category, images can also be ordered
+// by rank. A manually defined rank on each image for the category.
+//
+// In addition to fields of #images table, you can use the
+// #image_category.rank column
+//
+// $conf['order_by_inside_category'] = ' ORDER BY rank';
+// will sort images by the manually defined rank of images in this category.
+$conf['order_by_inside_category'] = $conf['order_by'];
+
+// file_ext : file extensions (case sensitive) authorized
+$conf['file_ext'] = array('jpg','JPG','jpeg','JPEG',
+                          'png','PNG','gif','GIF','mpg','zip',
+                          'avi','mp3','ogg');
+
+// picture_ext : file extensions for picture file, must be a subset of
+// file_ext
+$conf['picture_ext'] = array('jpg','JPG','jpeg','JPEG',
+                             'png','PNG','gif','GIF');
+
+// top_number : number of element to display for "best rated" and "most
+// visited" categories
+$conf['top_number'] = 15;
+
+// anti-flood_time : number of seconds between 2 comments : 0 to disable
+$conf['anti-flood_time'] = 60;
+
+// qualified spam comments are not registered (false will register them
+// but they will require admin validation)
+$conf['comment_spam_reject'] = true;
+
+// maximum number of links in a comment before it is qualified spam
+$conf['comment_spam_max_links'] = 3;
+
+// calendar_datefield : date field of table "images" used for calendar
+// catgory
+$conf['calendar_datefield'] = 'date_creation';
+
+// calendar_show_any : the calendar shows an aditional 'any' button in the
+// year/month/week/day navigation bars
+$conf['calendar_show_any'] = true;
+
+// calendar_show_empty : the calendar shows month/weeks/days even if there are
+//no elements for these
+$conf['calendar_show_empty'] = true;
+
+// calendar_month_cell_width, calendar_month_cell_height : define the
+// width and the height of a cell in the monthly calendar when viewing a
+// given month. a value of 0 means that the pretty view is not shown.
+// a good suggestion would be to have the width and the height equal
+// and smaller than tn_width and tn_height.
+$conf['calendar_month_cell_width'] =80;
+$conf['calendar_month_cell_height']=80;
+
+// newcat_default_commentable : at creation, must a category be commentable
+// or not ?
+$conf['newcat_default_commentable'] = true;
+
+// newcat_default_uploadable : at creation, must a category be uploadable or
+// not ?
+$conf['newcat_default_uploadable'] = false;
+
+// newcat_default_visible : at creation, must a category be visible or not ?
+// Warning : if the parent category is invisible, the category is
+// automatically create invisible. (invisible = locked)
+$conf['newcat_default_visible'] = true;
+
+// newcat_default_status : at creation, must a category be public or private
+// ? Warning : if the parent category is private, the category is
+// automatically create private.
+$conf['newcat_default_status'] = 'public';
+
+// level_separator : character string used for separating a category level
+// to the sub level. Suggestions : ' / ', ' &raquo; ', ' &rarr; ', ' - ',
+// ' &gt;'
+$conf['level_separator'] = ' / ';
+
+// paginate_pages_around : on paginate navigation bar, how many pages
+// display before and after the current page ?
+$conf['paginate_pages_around'] = 2;
+
+// tn_width : default width for thumbnails creation
+$conf['tn_width'] = 128;
+
+// tn_height : default height for thumbnails creation
+$conf['tn_height'] = 128;
+
+// tn_compression_level: compression level for thumbnail creation. 0 is low
+// quality, 100 is high quality.
+$conf['tn_compression_level'] = 75;
+
+// show_version : shall the version of Piwigo be displayed at the
+// bottom of each page ?
+$conf['show_version'] = true;
+
+// meta_ref to reference multiple sets of incorporated pages or elements
+// Set it false to avoid referencing in google, and other search engines.
+$conf['meta_ref'] = true;
+
+// links : list of external links to add in the menu. An example is the best
+// than a long explanation :
+//
+// Simple use:
+//  for each link is associated a label
+//  $conf['links'] = array(
+//    'http://piwigo.org' => 'PWG website',
+//    'http://piwigo.org/forum' => 'PWG forum',
+//    );
+//
+// Advenced use:
+//  You can also used special options. Instead to pass a string like parameter value
+//  you can pass a array with different optional parameter values
+//  $conf['links'] = array(
+//    'http://piwigo.org' => array('label' => 'PWG website', 'new_window' => false, 'eval_visible' => 'return true;'),
+//    'http://piwigo.org/forum' => array('label' => 'For ADMIN', 'new_window' => true, 'eval_visible' => 'return is_admin();'),
+//    'http://piwigo.org/ext' => array('label' => 'For Guest', 'new_window' => true, 'eval_visible' => 'return is_a_guest();'),
+//    'http://piwigo.org/downloads' =>
+//      array('label' => 'PopUp', 'new_window' => true,
+//      'nw_name' => 'PopUp', 'nw_features' => 'width=800,height=450,location=no,status=no,toolbar=no,scrollbars=no,menubar=no'),
+//    );
+// Parameters:
+//  'label':
+//    Label to display for the link, must be defined
+//  'new_window':
+//    If true open link on tab/window
+//    [Default value is true if it's not defined]
+//  'nw_name':
+//    Name use when new_window is true
+//    [Default value is '' if it's not defined]
+//  'nw_features':
+//    features use when new_window is true
+//    [Default value is '' if it's not defined]
+//  'eval_visible':
+//    It's php code witch must return if the link is visible or not
+//    [Default value is true if it's not defined]
+//
+// Equivalence:
+//  $conf['links'] = array(
+//    'http://piwigo.org' => 'PWG website',
+//    );
+//  $conf['links'] = array(
+//    'http://piwigo.org' => array('label' => 'PWG website', 'new_window' => false, 'visible' => 'return true;'),
+//    );
+//
+// If the array is empty, the "Links" box won't be displayed on the main
+// page.
+$conf['links'] = array();
+
+// random_index_redirect: list of 'internal' links to use when no section is defined on index.php.
+// An example is the best than a long explanation :
+//
+//  for each link is associated a php condition
+//  '' condition is equivalent to 'return true;'
+//  $conf['random_index_redirect'] = array(
+//    PHPWG_ROOT_PATH.'index.php?/best_rated' => 'return true;',
+//    PHPWG_ROOT_PATH.'index.php?/recent_pics' => 'return is_a_guest();',
+//    PHPWG_ROOT_PATH.'random.php' => '',
+//    PHPWG_ROOT_PATH.'index.php?/categories' => '',
+//    );
+$conf['random_index_redirect'] = array();
+
+// reverse_home_title: if Piwigo is your home page for a better robot index
+// we recommend to set it true (Only index page will reverse its title)
+$conf['reverse_home_title'] = false;
+
+// List of notes to display on all header page
+// example $conf['header_notes']  = array('Test', 'Hello');
+$conf['header_notes']  = array();
+
+// show_thumbnail_caption : on thumbnails page, show thumbnail captions ?
+$conf['show_thumbnail_caption'] = true;
+
+// show_picture_name_on_title : on picture presentation page, show picture
+// name ?
+$conf['show_picture_name_on_title'] = true;
+
+// display_fromto: display the date creation bounds of a
+// category.
+$conf['display_fromto'] = false;
+
+// allow_random_representative : do you wish Piwigo to search among
+// categories elements a new representative at each reload ?
+//
+// If false, an element is randomly or manually chosen to represent its
+// category and remains the representative as long as an admin does not
+// change it.
+//
+// Warning : setting this parameter to true is CPU consuming. Each time you
+// change the value of this parameter from false to true, an administrator
+// must update categories informations in screen [Admin > General >
+// Maintenance].
+$conf['allow_random_representative'] = false;
+
+// allow_html_descriptions : authorize administrators to use HTML in
+// category and element description.
+$conf['allow_html_descriptions'] = true;
+
+// prefix_thumbnail : string before filename. Thumbnail's prefix must only
+// contain characters among : a to z (case insensitive), "-" or "_".
+$conf['prefix_thumbnail'] = 'TN-';
+
+// users_page: how many users to display in screen
+// Administration>Identification>Users?
+$conf['users_page'] = 20;
+
+// image level permissions available in the admin interface
+$conf['available_permission_levels'] = array(0,1,2,4,8);
+
+// mail_options: only set it true if you have a send mail warning with
+// "options" parameter missing on mail() function execution.
+$conf['mail_options'] = false;
+
+// send_bcc_mail_webmaster: send bcc mail to webmaster. Set true for debug
+// or test.
+$conf['send_bcc_mail_webmaster'] = false;
+
+// default_email_format:
+//  Define the default email format use to send email
+//  Value could be text/plain  or text/html
+$conf['default_email_format'] = 'text/html';
+
+// define the name of sender mail:
+// If value is empty, gallery title is used
+$conf['mail_sender_name'] = '';
+
+// smtp configuration
+// (work if fsockopen function is allowed for smtp port)
+// smtp_host: smtp server host
+//  if null, regular mail function is used
+//   format: hoststring[:port]
+//   exemple: smtp.pwg.net:21
+// smtp_user/smtp_password: user & password for smtp identication
+$conf['smtp_host'] = '';
+$conf['smtp_user'] = '';
+$conf['smtp_password'] = '';
+
+
+// check_upgrade_feed: check if there are database upgrade required. Set to
+// true, a message will strongly encourage you to upgrade your database if
+// needed.
+//
+// This configuration parameter is set to true in BSF branch and to false
+// elsewhere.
+$conf['check_upgrade_feed'] = true;
+
+// rate_items: available rates for a picture
+$conf['rate_items'] = array(0,1,2,3,4,5);
+
+// Define default method to use ('http' or 'html' in order to do redirect)
+$conf['default_redirect_method'] = 'http';
+
+// +-----------------------------------------------------------------------+
+// |                               metadata                                |
+// +-----------------------------------------------------------------------+
+
+// show_iptc: Show IPTC metadata on picture.php if asked by user
+$conf['show_iptc'] = false;
+
+// show_iptc_mapping : is used for showing IPTC metadata on picture.php
+// page. For each key of the array, you need to have the same key in the
+// $lang array. For example, if my first key is 'iptc_keywords' (associated
+// to '2#025') then you need to have $lang['iptc_keywords'] set in
+// language/$user['language']/common.lang.php. If you don't have the lang
+// var set, the key will be simply displayed
+//
+// To know how to associated iptc_field with their meaning, use
+// tools/metadata.php
+$conf['show_iptc_mapping'] = array(
+  'iptc_keywords'        => '2#025',
+  'iptc_caption_writer'  => '2#122',
+  'iptc_byline_title'    => '2#085',
+  'iptc_caption'         => '2#120'
+  );
+
+// use_iptc: Use IPTC data during database synchronization with files
+// metadata
+$conf['use_iptc'] = false;
+
+// use_iptc_mapping : in which IPTC fields will Piwigo find image
+// information ? This setting is used during metadata synchronisation. It
+// associates a piwigo_images column name to a IPTC key
+$conf['use_iptc_mapping'] = array(
+  'keywords'        => '2#025',
+  'date_creation'   => '2#055',
+  'author'          => '2#122',
+  'name'            => '2#005',
+  'comment'         => '2#120'
+  );
+
+// show_exif: Show EXIF metadata on picture.php (table or line presentation
+// avalaible)
+$conf['show_exif'] = true;
+
+// show_exif_fields : in EXIF fields, you can choose to display fields in
+// sub-arrays, for example ['COMPUTED']['ApertureFNumber']. for this, add
+// 'COMPUTED;ApertureFNumber' in $conf['show_exif_fields']
+//
+// The key displayed in picture.php will be $lang['exif_field_Make'] for
+// example and if it exists. For compound fields, only take into account the
+// last part : for key 'COMPUTED;ApertureFNumber', you need
+// $lang['exif_field_ApertureFNumber']
+//
+// for PHP version newer than 4.1.2 :
+// $conf['show_exif_fields'] = array('CameraMake','CameraModel','DateTime');
+//
+$conf['show_exif_fields'] = array(
+  'Make',
+  'Model',
+  'DateTimeOriginal',
+  'COMPUTED;ApertureFNumber'
+  );
+
+// use_exif: Use EXIF data during database synchronization with files
+// metadata
+$conf['use_exif'] = true;
+
+// use_exif_mapping: same behaviour as use_iptc_mapping
+$conf['use_exif_mapping'] = array(
+  'date_creation' => 'DateTimeOriginal'
+  );
+
+// +-----------------------------------------------------------------------+
+// |                               sessions                                |
+// +-----------------------------------------------------------------------+
+
+// session_use_cookies: specifies to use cookie to store
+// the session id on client side
+$conf['session_use_cookies'] = true;
+
+// session_use_only_cookies: specifies to only use cookie to store
+// the session id on client side
+$conf['session_use_only_cookies'] = true;
+
+// session_use_trans_sid: do not use transparent session id support
+$conf['session_use_trans_sid'] = false;
+
+// session_name: specifies the name of the session which is used as cookie name
+$conf['session_name'] = 'pwg_id';
+
+// session_save_handler: comment the line below
+// to use file handler for sessions.
+$conf['session_save_handler'] = 'db';
+
+// authorize_remembering : permits user to stay logged for a long time. It
+// creates a cookie on client side.
+$conf['authorize_remembering'] = true;
+
+// remember_me_name: specifies the name of the cookie used to stay logged
+$conf['remember_me_name'] = 'pwg_remember';
+
+// remember_me_length : time of validity for "remember me" cookies, in
+// seconds.
+$conf['remember_me_length'] = 5184000;
+
+// session_length : time of validity for normal session, in seconds.
+$conf['session_length'] = 3600;
+
+// +-----------------------------------------------------------------------+
+// |                            debug/performance                          |
+// +-----------------------------------------------------------------------+
+
+// show_queries : for debug purpose, show queries and execution times
+$conf['show_queries'] = false;
+
+// show_gt : display generation time at the bottom of each page
+$conf['show_gt'] = true;
+
+// debug_l10n : display a warning message each time an unset language key is
+// accessed
+$conf['debug_l10n'] = false;
+
+// activate template debugging - a new window will appear
+$conf['debug_template'] = false;
+
+// die_on_sql_error: if an SQL query fails, should everything stop?
+$conf['die_on_sql_error'] = true;
+
+// if true, some language strings are replaced during template compilation
+// (insted of template output). this results in better performance. however
+// any change in the language file will not be propagated until you purge
+// the compiled templates from the admin / maintenance menu
+$conf['compiled_template_cache_language'] = false;
+
+// This tells Smarty whether to check for recompiling or not. Recompiling
+// does not need to happen unless a template is changed. false results in
+// better performance.
+$conf['template_compile_check'] = true;
+
+// this permit to show the php errors reporting (see INI 'error_reporting'
+// for possible values)
+// gives an empty value '' to deactivate
+$conf['show_php_errors'] = E_ALL;
+
+// +-----------------------------------------------------------------------+
+// |                            authentication                             |
+// +-----------------------------------------------------------------------+
+
+// apache_authentication : use Apache authentication as reference instead of
+// users table ?
+$conf['apache_authentication'] = false;
+
+// users_table: which table is the reference for users? Can be a different
+// table than Piwigo table
+//
+// If you decide to use another table than the default one, you need to
+// prepare your database by deleting some datas :
+//
+// delete from piwigo_user_access;
+// delete from piwigo_user_cache;
+// delete from piwigo_user_feed;
+// delete from piwigo_user_group;
+// delete from piwigo_user_infos;
+// delete from piwigo_sessions;
+// delete from piwigo_rate;
+// update piwigo_images set average_rate = null;
+// delete from piwigo_caddie;
+// delete from piwigo_favorites;
+//
+// All informations contained in these tables and column are related to
+// piwigo_users table.
+$conf['users_table'] = $prefixeTable.'users';
+
+// Other tables can be changed, if you define associated constants
+// Example:
+//   define('USER_INFOS_TABLE', 'pwg_main'.'user_infos');
+
+
+// user_fields : mapping between generic field names and table specific
+// field names. For example, in PWG, the mail address is names
+// "mail_address" and in punbb, it's called "email".
+$conf['user_fields'] = array(
+  'id' => 'id',
+  'username' => 'username',
+  'password' => 'password',
+  'email' => 'mail_address'
+  );
+
+// pass_convert : function to crypt or hash the clear user password to store
+// it in the database
+$conf['pass_convert'] = create_function('$s', 'return md5($s);');
+
+// guest_id : id of the anonymous user
+$conf['guest_id'] = 2;
+// default_user_id : id of user used for default value
+$conf['default_user_id'] = $conf['guest_id'];
+
+// Registering process and guest/generic members get language from the browser
+// if language isn't available PHPWG_DEFAULT_LANGUAGE is used as previously
+$conf['browser_language'] = true;
+
+// webmaster_id : webmaster'id.
+$conf['webmaster_id'] = 1;
+
+// allow to use adviser mode
+$conf['allow_adviser'] = false;
+
+// does the guest have access ?
+// (not a security feature, set your categories "private" too)
+// If false it'll be redirected from index.php to identification.php
+$conf['guest_access'] = true;
+
+// +-----------------------------------------------------------------------+
+// |                                upload                                 |
+// +-----------------------------------------------------------------------+
+
+// upload_maxfilesize: maximum filesize for the uploaded pictures. In
+// kilobytes.
+$conf['upload_maxfilesize'] = 200;
+
+// upload_maxheight: maximum height authorized for the uploaded images. In
+// pixels.
+$conf['upload_maxheight'] = 800;
+
+// upload_maxwidth: maximum width authorized for the uploaded images. In
+// pixels.
+$conf['upload_maxwidth'] = 800;
+
+// upload_maxheight_thumbnail: maximum height authorized for the uploaded
+// thumbnails
+$conf['upload_maxheight_thumbnail'] = 128;
+
+// upload_maxwidth_thumbnail: maximum width authorized for the uploaded
+// thumbnails
+$conf['upload_maxwidth_thumbnail'] = 128;
+
+// +-----------------------------------------------------------------------+
+// |                               history                                 |
+// +-----------------------------------------------------------------------+
+
+// nb_logs_page :  how many logs to display on a page
+$conf['nb_logs_page'] = 300;
+
+// +-----------------------------------------------------------------------+
+// |                                 urls                                  |
+// +-----------------------------------------------------------------------+
+
+// question_mark_in_urls : the generated urls contain a ? sign. This can be
+// changed to false only if the server translates PATH_INFO variable
+// (depends on the server AcceptPathInfo directive configuration)
+$conf['question_mark_in_urls'] = true;
+
+// php_extension_in_urls : if true, the urls generated for picture and
+// category will not contain the .php extension. This will work only if
+// .htaccess defines Options +MultiViews parameter or url rewriting rules
+// are active.
+$conf['php_extension_in_urls'] = true;
+
+// category_url_style : one of 'id' (default) or 'id-name'. 'id-name'
+// means that an simplified ascii represntation of the category name will
+// appear in the url
+$conf['category_url_style'] = 'id';
+
+// picture_url_style : one of 'id' (default), 'id-file' or 'file'. 'id-file'
+// or 'file' mean that the file name (without extension will appear in the
+// url). Note that one aditionnal sql query will occur if 'file' is choosen.
+// Note that you might experience navigation issues if you choose 'file'
+// and your file names are not unique
+$conf['picture_url_style'] = 'id';
+
+// tag_url_style : one of 'id-tag' (default), 'id' or 'tag'.
+// Note that if you choose 'tag' and the url (ascii) representation of your
+// tags is not unique, all tags with the same url representation will be shown
+$conf['tag_url_style'] = 'id-tag';
+
+// +-----------------------------------------------------------------------+
+// |                                 tags                                  |
+// +-----------------------------------------------------------------------+
+
+// full_tag_cloud_items_number: number of tags to show in the full tag
+// cloud. Only the most represented tags will be shown
+$conf['full_tag_cloud_items_number'] = 200;
+
+// menubar_tag_cloud_items_number: number of tags to show in the tag
+// cloud in the menubar. Only the most represented tags will be shown
+$conf['menubar_tag_cloud_items_number'] = 100;
+
+// content_tag_cloud_items_number: number of tags to show in the tag
+// cloud on the content page. Only the most represented tags will be shown
+$conf['content_tag_cloud_items_number'] = 12;
+
+// tags_levels: number of levels to use for display. Each level is bind to a
+// CSS class tagLevelX.
+$conf['tags_levels'] = 5;
+
+// tags_default_display_mode: group tags by letter or display a tag cloud by
+// default? 'letters' or 'cloud'.
+$conf['tags_default_display_mode'] = 'cloud';
+
+// tag_letters_column_number: how many columns to display tags by letter
+$conf['tag_letters_column_number'] = 4;
+
+// +-----------------------------------------------------------------------+
+// | Notification by mail                                                  |
+// +-----------------------------------------------------------------------+
+
+// Default Value for nbm user
+$conf['nbm_default_value_user_enabled'] = false;
+
+// Search list user to send quickly (List all without to check news)
+// More quickly but less fun to use
+$conf['nbm_list_all_enabled_users_to_send'] = false;
+
+// Max time used on one pass in order to send mails.
+// Timeout delay ratio.
+$conf['nbm_max_treatment_timeout_percent'] = 0.8;
+
+// If timeout cannot be compite with nbm_max_treatment_timeout_percent,
+// nbm_treatment_timeout_default is used by default
+$conf['nbm_treatment_timeout_default'] = 20;
+
+// Parameters used in get_recent_post_dates for the 2 kind of notification
+$conf['recent_post_dates'] = array(
+  'RSS' => array('max_dates' => 5, 'max_elements' => 6, 'max_cats' => 6),
+  'NBM' => array('max_dates' => 7, 'max_elements' => 3, 'max_cats' => 9)
+  );
+
+// the author shown in the RSS feed <author> element
+$conf['rss_feed_author'] = 'Piwigo notifier';
+
+// +-----------------------------------------------------------------------+
+// | Set admin layout                                                      |
+// +-----------------------------------------------------------------------+
+
+$conf['admin_layout'] = 'goto/roma';
+
+// should we load the active plugins ? true=Yes, false=No
+$conf['enable_plugins']=true;
+
+// Web services are allowed (true) or completely forbidden (false)
+$conf['allow_web_services'] = true;
+
+// Maximum number of images to be returned foreach call to the web service
+$conf['ws_max_images_per_page'] = 500;
+
+// +-----------------------------------------------------------------------+
+// | Filter                                                                |
+// +-----------------------------------------------------------------------+
+// $conf['filter_pages'] contains configuration for each pages
+//   o If values are not defined for a specific page, default value are used
+//   o Array is composed by the basename of each page without extention
+//   o List of value names:
+//     - used: filter function are used
+//       (if false nothing is done [start, cancel, stop, ...]
+//     - cancel: cancel current started filter
+//     - add_notes: add notes about current started filter on the header
+//   o Empty configuration in order to disable completely filter functions
+//     No filter, No icon,...
+//     $conf['filter_pages'] = array();
+$conf['filter_pages'] = array
+  (
+    // Default page
+    'default' => array(
+      'used' => true, 'cancel' => false, 'add_notes' => false),
+    // Real pages
+    'index' => array('add_notes' => true),
+    'tags' => array('add_notes' => true),
+    'search' => array('add_notes' => true),
+    'comments' => array('add_notes' => true),
+    'admin' => array('used' => false),
+    'feed' => array('used' => false),
+    'notification' => array('used' => false),
+    'nbm' => array('used' => false),
+    'popuphelp' => array('used' => false),
+    'profile' => array('used' => false),
+    'ws' => array('used' => false),
+    'identification' => array('cancel' => true),
+    'install' => array('cancel' => true),
+    'password' => array('cancel' => true),
+    'register' => array('cancel' => true),
+  );
+
+// +-----------------------------------------------------------------------+
+// | Slideshow                                                             |
+// +-----------------------------------------------------------------------+
+// slideshow_period : waiting time in seconds before loading a new page
+// during automated slideshow
+// slideshow_period_min, slideshow_period_max are bounds of slideshow_period
+// slideshow_period_step is the step of navigation between min and max
+$conf['slideshow_period_min'] = 1;
+$conf['slideshow_period_max'] = 10;
+$conf['slideshow_period_step'] = 1;
+$conf['slideshow_period'] = 4;
+
+// slideshow_repeat : slideshow loops on pictures
+$conf['slideshow_repeat'] = true;
+
+// $conf['light_slideshow'] indicates to use slideshow.tpl in state of
+// picture.tpl for slideshow
+// Take care to have slideshow.tpl in all available templates
+// Or set it false.
+// Check if Picture's plugins are compliant with it
+// Every plugin from 1.7 would be design to manage light_slideshow case.
+$conf['light_slideshow'] = true;
+
+// the local data directory is used to store data such as compiled templates
+// or other plugin variables etc
+$conf['local_data_dir'] = dirname(dirname(__FILE__)).'/_data';
+?>
Index: /tags/2.0.2/include/constants.php
===================================================================
--- /tags/2.0.2/include/constants.php	(revision 3278)
+++ /tags/2.0.2/include/constants.php	(revision 3278)
@@ -0,0 +1,101 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Default settings
+define('PHPWG_VERSION', '2.0');
+define('PHPWG_DEFAULT_LANGUAGE', 'en_UK');
+define('PHPWG_DEFAULT_TEMPLATE', 'yoga/Sylvia');
+
+// Required versions
+define('REQUIRED_PHP_VERSION', '5.0.0');
+define('REQUIRED_MYSQL_VERSION', '4.1.22');
+
+// Access codes
+define('ACCESS_FREE', 0);
+define('ACCESS_GUEST', 1);
+define('ACCESS_CLASSIC', 2);
+define('ACCESS_ADMINISTRATOR', 3);
+define('ACCESS_WEBMASTER', 4);
+define('ACCESS_CLOSED', 5);
+
+// Table names
+if (!defined('CATEGORIES_TABLE'))
+  define('CATEGORIES_TABLE', $prefixeTable.'categories');
+if (!defined('COMMENTS_TABLE'))
+  define('COMMENTS_TABLE', $prefixeTable.'comments');
+if (!defined('CONFIG_TABLE'))
+  define('CONFIG_TABLE', $prefixeTable.'config');
+if (!defined('FAVORITES_TABLE'))
+  define('FAVORITES_TABLE', $prefixeTable.'favorites');
+if (!defined('GROUP_ACCESS_TABLE'))
+  define('GROUP_ACCESS_TABLE', $prefixeTable.'group_access');
+if (!defined('GROUPS_TABLE'))
+  define('GROUPS_TABLE', $prefixeTable.'groups');
+if (!defined('HISTORY_TABLE'))
+  define('HISTORY_TABLE', $prefixeTable.'history');
+if (!defined('HISTORY_SUMMARY_TABLE'))
+  define('HISTORY_SUMMARY_TABLE', $prefixeTable.'history_summary');
+if (!defined('IMAGE_CATEGORY_TABLE'))
+  define('IMAGE_CATEGORY_TABLE', $prefixeTable.'image_category');
+if (!defined('IMAGES_TABLE'))
+  define('IMAGES_TABLE', $prefixeTable.'images');
+if (!defined('SESSIONS_TABLE'))
+  define('SESSIONS_TABLE', $prefixeTable.'sessions');
+if (!defined('SITES_TABLE'))
+  define('SITES_TABLE', $prefixeTable.'sites');
+if (!defined('USER_ACCESS_TABLE'))
+  define('USER_ACCESS_TABLE', $prefixeTable.'user_access');
+if (!defined('USER_GROUP_TABLE'))
+  define('USER_GROUP_TABLE', $prefixeTable.'user_group');
+if (!defined('USERS_TABLE'))
+  define('USERS_TABLE', $conf['users_table']);
+if (!defined('USER_INFOS_TABLE'))
+  define('USER_INFOS_TABLE', $prefixeTable.'user_infos');
+if (!defined('USER_FEED_TABLE'))
+  define('USER_FEED_TABLE', $prefixeTable.'user_feed');
+if (!defined('WAITING_TABLE'))
+  define('WAITING_TABLE', $prefixeTable.'waiting');
+if (!defined('RATE_TABLE'))
+  define('RATE_TABLE', $prefixeTable.'rate');
+if (!defined('USER_CACHE_TABLE'))
+  define('USER_CACHE_TABLE', $prefixeTable.'user_cache');
+if (!defined('USER_CACHE_CATEGORIES_TABLE'))
+  define('USER_CACHE_CATEGORIES_TABLE', $prefixeTable.'user_cache_categories');
+if (!defined('CADDIE_TABLE'))
+  define('CADDIE_TABLE', $prefixeTable.'caddie');
+if (!defined('UPGRADE_TABLE'))
+  define('UPGRADE_TABLE', $prefixeTable.'upgrade');
+if (!defined('SEARCH_TABLE'))
+  define('SEARCH_TABLE', $prefixeTable.'search');
+if (!defined('USER_MAIL_NOTIFICATION_TABLE'))
+  define('USER_MAIL_NOTIFICATION_TABLE', $prefixeTable.'user_mail_notification');
+if (!defined('TAGS_TABLE'))
+  define('TAGS_TABLE', $prefixeTable.'tags');
+if (!defined('IMAGE_TAG_TABLE'))
+  define('IMAGE_TAG_TABLE', $prefixeTable.'image_tag');
+if (!defined('PLUGINS_TABLE'))
+  define('PLUGINS_TABLE', $prefixeTable.'plugins');
+if (!defined('OLD_PERMALINKS_TABLE'))
+  define('OLD_PERMALINKS_TABLE', $prefixeTable.'old_permalinks');
+
+?>
Index: /tags/2.0.2/include/feedcreator.class.php
===================================================================
--- /tags/2.0.2/include/feedcreator.class.php	(revision 3278)
+++ /tags/2.0.2/include/feedcreator.class.php	(revision 3278)
@@ -0,0 +1,1541 @@
+<?php
+/***************************************************************************
+
+FeedCreator class v1.7.2
+originally (c) Kai Blankenhorn
+www.bitfolge.de
+kaib@bitfolge.de
+v1.3 work by Scott Reynen (scott@randomchaos.com) and Kai Blankenhorn
+v1.5 OPML support by Dirk Clemens
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+****************************************************************************
+
+
+Changelog:
+
+v1.7.2	10-11-04
+	license changed to LGPL
+
+v1.7.1
+	fixed a syntax bug
+	fixed left over debug code
+
+v1.7	07-18-04
+	added HTML and JavaScript feeds (configurable via CSS) (thanks to Pascal Van Hecke)
+	added HTML descriptions for all feed formats (thanks to Pascal Van Hecke)
+	added a switch to select an external stylesheet (thanks to Pascal Van Hecke)
+	changed default content-type to application/xml
+	added character encoding setting
+	fixed numerous smaller bugs (thanks to Sören Fuhrmann of golem.de)
+	improved changing ATOM versions handling (thanks to August Trometer)
+	improved the UniversalFeedCreator's useCached method (thanks to Sören Fuhrmann of golem.de)
+	added charset output in HTTP headers (thanks to Sören Fuhrmann of golem.de)
+	added Slashdot namespace to RSS 1.0 (thanks to Sören Fuhrmann of golem.de)
+
+v1.6	05-10-04
+	added stylesheet to RSS 1.0 feeds
+	fixed generator comment (thanks Kevin L. Papendick and Tanguy Pruvot)
+	fixed RFC822 date bug (thanks Tanguy Pruvot)
+	added TimeZone customization for RFC8601 (thanks Tanguy Pruvot)
+	fixed Content-type could be empty (thanks Tanguy Pruvot)
+	fixed author/creator in RSS1.0 (thanks Tanguy Pruvot)
+
+v1.6 beta	02-28-04
+	added Atom 0.3 support (not all features, though)
+	improved OPML 1.0 support (hopefully - added more elements)
+	added support for arbitrary additional elements (use with caution)
+	code beautification :-)
+	considered beta due to some internal changes
+
+v1.5.1	01-27-04
+	fixed some RSS 1.0 glitches (thanks to Stéphane Vanpoperynghe)
+	fixed some inconsistencies between documentation and code (thanks to Timothy Martin)
+
+v1.5	01-06-04
+	added support for OPML 1.0
+	added more documentation
+
+v1.4	11-11-03
+	optional feed saving and caching
+	improved documentation
+	minor improvements
+
+v1.3    10-02-03
+	renamed to FeedCreator, as it not only creates RSS anymore
+	added support for mbox
+	tentative support for echo/necho/atom/pie/???
+
+v1.2    07-20-03
+	intelligent auto-truncating of RSS 0.91 attributes
+	don't create some attributes when they're not set
+	documentation improved
+	fixed a real and a possible bug with date conversions
+	code cleanup
+
+v1.1    06-29-03
+	added images to feeds
+	now includes most RSS 0.91 attributes
+	added RSS 2.0 feeds
+
+v1.0    06-24-03
+	initial release
+
+
+
+***************************************************************************/
+
+/*** GENERAL USAGE *********************************************************
+
+include("feedcreator.class.php");
+
+$rss = new UniversalFeedCreator();
+$rss->useCached(); // use cached version if age<1 hour
+$rss->title = "PHP news";
+$rss->description = "daily news from the PHP scripting world";
+
+//optional
+$rss->descriptionTruncSize = 500;
+$rss->descriptionHtmlSyndicated = true;
+
+$rss->link = "http://www.dailyphp.net/news";
+$rss->syndicationURL = "http://www.dailyphp.net/".$_SERVER["PHP_SELF"];
+
+$image = new FeedImage();
+$image->title = "dailyphp.net logo";
+$image->url = "http://www.dailyphp.net/images/logo.gif";
+$image->link = "http://www.dailyphp.net";
+$image->description = "Feed provided by dailyphp.net. Click to visit.";
+
+//optional
+$image->descriptionTruncSize = 500;
+$image->descriptionHtmlSyndicated = true;
+
+$rss->image = $image;
+
+// get your news items from somewhere, e.g. your database:
+mysql_select_db($dbHost, $dbUser, $dbPass);
+$res = mysql_query("SELECT * FROM news ORDER BY newsdate DESC");
+while ($data = mysql_fetch_object($res)) {
+    $item = new FeedItem();
+    $item->title = $data->title;
+    $item->link = $data->url;
+    $item->description = $data->short;
+
+    //optional
+    item->descriptionTruncSize = 500;
+    item->descriptionHtmlSyndicated = true;
+
+    $item->date = $data->newsdate;
+    $item->source = "http://www.dailyphp.net";
+    $item->author = "John Doe";
+
+    $rss->addItem($item);
+}
+
+// valid format strings are: RSS0.91, RSS1.0, RSS2.0, PIE0.1 (deprecated),
+// MBOX, OPML, ATOM, ATOM0.3, HTML, JS
+echo $rss->saveFeed("RSS1.0", "news/feed.xml");
+
+
+***************************************************************************
+*          A little setup                                                 *
+**************************************************************************/
+
+// your local timezone, set to "" to disable or for GMT
+define("TIME_ZONE","+00:00");
+
+
+
+
+/**
+ * Version string.
+ **/
+define("FEEDCREATOR_VERSION", "FeedCreator 1.7.2");
+
+
+
+/**
+ * A FeedItem is a part of a FeedCreator feed.
+ *
+ * @author Kai Blankenhorn <kaib@bitfolge.de>
+ * @since 1.3
+ */
+class FeedItem extends HtmlDescribable {
+	/**
+	 * Mandatory attributes of an item.
+	 */
+	var $title, $description, $link;
+
+	/**
+	 * Optional attributes of an item.
+	 */
+	var $author, $authorEmail, $image, $category, $comments, $guid, $source, $creator;
+
+	/**
+	 * Publishing date of an item. May be in one of the following formats:
+	 *
+	 *	RFC 822:
+	 *	"Mon, 20 Jan 03 18:05:41 +0400"
+	 *	"20 Jan 03 18:05:41 +0000"
+	 *
+	 *	ISO 8601:
+	 *	"2003-01-20T18:05:41+04:00"
+	 *
+	 *	Unix:
+	 *	1043082341
+	 */
+	var $date;
+
+	/**
+	 * Any additional elements to include as an assiciated array. All $key => $value pairs
+	 * will be included unencoded in the feed item in the form
+	 *     <$key>$value</$key>
+	 * Again: No encoding will be used! This means you can invalidate or enhance the feed
+	 * if $value contains markup. This may be abused to embed tags not implemented by
+	 * the FeedCreator class used.
+	 */
+	var $additionalElements = Array();
+
+	// on hold
+	// var $source;
+}
+
+
+
+/**
+ * An FeedImage may be added to a FeedCreator feed.
+ * @author Kai Blankenhorn <kaib@bitfolge.de>
+ * @since 1.3
+ */
+class FeedImage extends HtmlDescribable {
+	/**
+	 * Mandatory attributes of an image.
+	 */
+	var $title, $url, $link;
+
+	/**
+	 * Optional attributes of an image.
+	 */
+	var $width, $height, $description;
+}
+
+
+
+/**
+ * An HtmlDescribable is an item within a feed that can have a description that may
+ * include HTML markup.
+ */
+class HtmlDescribable {
+	/**
+	 * Indicates whether the description field should be rendered in HTML.
+	 */
+	var $descriptionHtmlSyndicated;
+
+	/**
+	 * Indicates whether and to how many characters a description should be truncated.
+	 */
+	var $descriptionTruncSize;
+
+	/**
+	 * Returns a formatted description field, depending on descriptionHtmlSyndicated and
+	 * $descriptionTruncSize properties
+	 * @return    string    the formatted description
+	 */
+	function getDescription() {
+		$descriptionField = new FeedHtmlField($this->description);
+		$descriptionField->syndicateHtml = $this->descriptionHtmlSyndicated;
+		$descriptionField->truncSize = $this->descriptionTruncSize;
+		return $descriptionField->output();
+	}
+
+}
+
+
+/**
+ * An FeedHtmlField describes and generates
+ * a feed, item or image html field (probably a description). Output is
+ * generated based on $truncSize, $syndicateHtml properties.
+ * @author Pascal Van Hecke <feedcreator.class.php@vanhecke.info>
+ * @version 1.6
+ */
+class FeedHtmlField {
+	/**
+	 * Mandatory attributes of a FeedHtmlField.
+	 */
+	var $rawFieldContent;
+
+	/**
+	 * Optional attributes of a FeedHtmlField.
+	 *
+	 */
+	var $truncSize, $syndicateHtml;
+
+	/**
+	 * Creates a new instance of FeedHtmlField.
+	 * @param  $string: if given, sets the rawFieldContent property
+	 */
+	function FeedHtmlField($parFieldContent) {
+		if ($parFieldContent) {
+			$this->rawFieldContent = $parFieldContent;
+		}
+	}
+
+
+	/**
+	 * Creates the right output, depending on $truncSize, $syndicateHtml properties.
+	 * @return string    the formatted field
+	 */
+	function output() {
+		// when field available and syndicated in html we assume
+		// - valid html in $rawFieldContent and we enclose in CDATA tags
+		// - no truncation (truncating risks producing invalid html)
+		if (!$this->rawFieldContent) {
+			$result = "";
+		}	elseif ($this->syndicateHtml) {
+			$result = "<![CDATA[".$this->rawFieldContent."]]>";
+		} else {
+			if ($this->truncSize and is_int($this->truncSize)) {
+				$result = FeedCreator::iTrunc(htmlspecialchars($this->rawFieldContent),$this->truncSize);
+			} else {
+				$result = htmlspecialchars($this->rawFieldContent);
+			}
+		}
+		return $result;
+	}
+
+}
+
+
+
+/**
+ * UniversalFeedCreator lets you choose during runtime which
+ * format to build.
+ * For general usage of a feed class, see the FeedCreator class
+ * below or the example above.
+ *
+ * @since 1.3
+ * @author Kai Blankenhorn <kaib@bitfolge.de>
+ */
+class UniversalFeedCreator extends FeedCreator {
+	var $_feed;
+
+	function _setFormat($format) {
+		switch (strtoupper($format)) {
+
+			case "2.0":
+				// fall through
+			case "RSS2.0":
+				$this->_feed = new RSSCreator20();
+				break;
+
+			case "1.0":
+				// fall through
+			case "RSS1.0":
+				$this->_feed = new RSSCreator10();
+				break;
+
+			case "0.91":
+				// fall through
+			case "RSS0.91":
+				$this->_feed = new RSSCreator091();
+				break;
+
+			case "PIE0.1":
+				$this->_feed = new PIECreator01();
+				break;
+
+			case "MBOX":
+				$this->_feed = new MBOXCreator();
+				break;
+
+			case "OPML":
+				$this->_feed = new OPMLCreator();
+				break;
+
+			case "ATOM":
+				// fall through: always the latest ATOM version
+
+			case "ATOM0.3":
+				$this->_feed = new AtomCreator03();
+				break;
+
+			case "HTML":
+				$this->_feed = new HTMLCreator();
+				break;
+
+			case "JS":
+				// fall through
+			case "JAVASCRIPT":
+				$this->_feed = new JSCreator();
+				break;
+
+			default:
+				$this->_feed = new RSSCreator091();
+				break;
+		}
+
+		$vars = get_object_vars($this);
+		foreach ($vars as $key => $value) {
+			// prevent overwriting of properties "contentType", "encoding"; do not copy "_feed" itself
+			if (!in_array($key, array("_feed", "contentType"/*PWG, "encoding"*/))) {
+				$this->_feed->{$key} = $this->{$key};
+			}
+		}
+	}
+
+	/**
+	 * Creates a syndication feed based on the items previously added.
+	 *
+	 * @see        FeedCreator::addItem()
+	 * @param    string    format    format the feed should comply to. Valid values are:
+	 *			"PIE0.1", "mbox", "RSS0.91", "RSS1.0", "RSS2.0", "OPML", "ATOM0.3", "HTML", "JS"
+	 * @return    string    the contents of the feed.
+	 */
+	function createFeed($format = "RSS0.91") {
+		$this->_setFormat($format);
+		return $this->_feed->createFeed();
+	}
+
+
+
+	/**
+	 * Saves this feed as a file on the local disk. After the file is saved, an HTTP redirect
+	 * header may be sent to redirect the use to the newly created file.
+	 * @since 1.4
+	 *
+	 * @param	string	format	format the feed should comply to. Valid values are:
+	 *			"PIE0.1" (deprecated), "mbox", "RSS0.91", "RSS1.0", "RSS2.0", "OPML", "ATOM", "ATOM0.3", "HTML", "JS"
+	 * @param	string	filename	optional	the filename where a recent version of the feed is saved. If not specified, the filename is $_SERVER["PHP_SELF"] with the extension changed to .xml (see _generateFilename()).
+	 * @param	boolean	displayContents	optional	send the content of the file or not. If true, the file will be sent in the body of the response.
+	 */
+	function saveFeed($format="RSS0.91", $filename="", $displayContents=true) {
+		$this->_setFormat($format);
+		$this->_feed->saveFeed($filename, $displayContents);
+	}
+
+
+   /**
+    * Turns on caching and checks if there is a recent version of this feed in the cache.
+    * If there is, an HTTP redirect header is sent.
+    * To effectively use caching, you should create the FeedCreator object and call this method
+    * before anything else, especially before you do the time consuming task to build the feed
+    * (web fetching, for example).
+    *
+    * @param   string   format   format the feed should comply to. Valid values are:
+    *       "PIE0.1" (deprecated), "mbox", "RSS0.91", "RSS1.0", "RSS2.0", "OPML", "ATOM0.3".
+    * @param filename   string   optional the filename where a recent version of the feed is saved. If not specified, the filename is $_SERVER["PHP_SELF"] with the extension changed to .xml (see _generateFilename()).
+    * @param timeout int      optional the timeout in seconds before a cached version is refreshed (defaults to 3600 = 1 hour)
+    */
+   function useCached($format="RSS0.91", $filename="", $timeout=3600) {
+      $this->_setFormat($format);
+      $this->_feed->useCached($filename, $timeout);
+   }
+
+}
+
+
+/**
+ * FeedCreator is the abstract base implementation for concrete
+ * implementations that implement a specific format of syndication.
+ *
+ * @abstract
+ * @author Kai Blankenhorn <kaib@bitfolge.de>
+ * @since 1.4
+ */
+class FeedCreator extends HtmlDescribable {
+
+	/**
+	 * Mandatory attributes of a feed.
+	 */
+	var $title, $description, $link;
+
+
+	/**
+	 * Optional attributes of a feed.
+	 */
+	var $syndicationURL, $image, $language, $copyright, $pubDate, $lastBuildDate, $editor, $editorEmail, $webmaster, $category, $docs, $ttl, $rating, $skipHours, $skipDays;
+
+	/**
+	* The url of the external xsl stylesheet used to format the naked rss feed.
+	* Ignored in the output when empty.
+	*/
+	var $xslStyleSheet = "";
+
+
+	/**
+	 * @access private
+	 */
+	var $items = Array();
+
+
+	/**
+	 * This feed's MIME content type.
+	 * @since 1.4
+	 * @access private
+	 */
+	var $contentType = "application/xml";
+
+
+	/**
+	 * This feed's character encoding.
+	 * @since 1.6.1
+	 **/
+	var $encoding = "ISO-8859-1";
+
+
+	/**
+	 * Any additional elements to include as an assiciated array. All $key => $value pairs
+	 * will be included unencoded in the feed in the form
+	 *     <$key>$value</$key>
+	 * Again: No encoding will be used! This means you can invalidate or enhance the feed
+	 * if $value contains markup. This may be abused to embed tags not implemented by
+	 * the FeedCreator class used.
+	 */
+	var $additionalElements = Array();
+
+
+	/**
+	 * Adds an FeedItem to the feed.
+	 *
+	 * @param object FeedItem $item The FeedItem to add to the feed.
+	 * @access public
+	 */
+	function addItem($item) {
+		$this->items[] = $item;
+	}
+
+
+	/**
+	 * Truncates a string to a certain length at the most sensible point.
+	 * First, if there's a '.' character near the end of the string, the string is truncated after this character.
+	 * If there is no '.', the string is truncated after the last ' ' character.
+	 * If the string is truncated, " ..." is appended.
+	 * If the string is already shorter than $length, it is returned unchanged.
+	 *
+	 * @static
+	 * @param string    string A string to be truncated.
+	 * @param int        length the maximum length the string should be truncated to
+	 * @return string    the truncated string
+	 */
+	function iTrunc($string, $length) {
+		if (strlen($string)<=$length) {
+			return $string;
+		}
+
+		$pos = strrpos($string,".");
+		if ($pos>=$length-4) {
+			$string = substr($string,0,$length-4);
+			$pos = strrpos($string,".");
+		}
+		if ($pos>=$length*0.4) {
+			return substr($string,0,$pos+1)." ...";
+		}
+
+		$pos = strrpos($string," ");
+		if ($pos>=$length-4) {
+			$string = substr($string,0,$length-4);
+			$pos = strrpos($string," ");
+		}
+		if ($pos>=$length*0.4) {
+			return substr($string,0,$pos)." ...";
+		}
+
+		return substr($string,0,$length-4)." ...";
+
+	}
+
+
+	/**
+	 * Creates a comment indicating the generator of this feed.
+	 * The format of this comment seems to be recognized by
+	 * Syndic8.com.
+	 */
+	function _createGeneratorComment() {
+		return "<!-- generator=\"".FEEDCREATOR_VERSION."\" -->\n";
+	}
+
+
+	/**
+	 * Creates a string containing all additional elements specified in
+	 * $additionalElements.
+	 * @param	elements	array	an associative array containing key => value pairs
+	 * @param indentString	string	a string that will be inserted before every generated line
+	 * @return    string    the XML tags corresponding to $additionalElements
+	 */
+	function _createAdditionalElements($elements, $indentString="") {
+		$ae = "";
+		if (is_array($elements)) {
+			foreach($elements AS $key => $value) {
+				$ae.= $indentString."<$key>$value</$key>\n";
+			}
+		}
+		return $ae;
+	}
+
+	function _createStylesheetReferences() {
+		$xml = "";
+		if (isset($this->cssStyleSheet)) $xml .= "<?xml-stylesheet href=\"".$this->cssStyleSheet."\" type=\"text/css\"?>\n";
+		if ($this->xslStyleSheet) $xml .= "<?xml-stylesheet href=\"".$this->xslStyleSheet."\" type=\"text/xsl\"?>\n";
+		return $xml;
+	}
+
+
+	/**
+	 * Builds the feed's text.
+	 * @abstract
+	 * @return    string    the feed's complete text
+	 */
+	function createFeed() {
+	}
+
+	/**
+	 * Generate a filename for the feed cache file. The result will be $_SERVER["PHP_SELF"] with the extension changed to .xml.
+	 * For example:
+	 *
+	 * echo $_SERVER["PHP_SELF"]."\n";
+	 * echo FeedCreator::_generateFilename();
+	 *
+	 * would produce:
+	 *
+	 * /rss/latestnews.php
+	 * latestnews.xml
+	 *
+	 * @return string the feed cache filename
+	 * @since 1.4
+	 * @access private
+	 */
+	function _generateFilename() {
+		$fileInfo = pathinfo($_SERVER["PHP_SELF"]);
+		return substr($fileInfo["basename"],0,-(strlen($fileInfo["extension"])+1)).".xml";
+	}
+
+
+	/**
+	 * @since 1.4
+	 * @access private
+	 */
+	function _redirect($filename) {
+		// attention, heavily-commented-out-area
+
+		// maybe use this in addition to file time checking
+		//Header("Expires: ".date("r",time()+$this->_timeout));
+
+		/* no caching at all, doesn't seem to work as good:
+		Header("Cache-Control: no-cache");
+		Header("Pragma: no-cache");
+		*/
+
+		// HTTP redirect, some feed readers' simple HTTP implementations don't follow it
+		//Header("Location: ".$filename);
+
+		Header("Content-Type: ".$this->contentType."; charset=".$this->encoding."; filename=".basename($filename));
+		Header("Content-Disposition: inline; filename=".basename($filename));
+		readfile($filename, "r");
+		die();
+	}
+
+	/**
+	 * Turns on caching and checks if there is a recent version of this feed in the cache.
+	 * If there is, an HTTP redirect header is sent.
+	 * To effectively use caching, you should create the FeedCreator object and call this method
+	 * before anything else, especially before you do the time consuming task to build the feed
+	 * (web fetching, for example).
+	 * @since 1.4
+	 * @param filename	string	optional	the filename where a recent version of the feed is saved. If not specified, the filename is $_SERVER["PHP_SELF"] with the extension changed to .xml (see _generateFilename()).
+	 * @param timeout	int		optional	the timeout in seconds before a cached version is refreshed (defaults to 3600 = 1 hour)
+	 */
+	function useCached($filename="", $timeout=3600) {
+		$this->_timeout = $timeout;
+		if ($filename=="") {
+			$filename = $this->_generateFilename();
+		}
+		if (file_exists($filename) AND (time()-filemtime($filename) < $timeout)) {
+			$this->_redirect($filename);
+		}
+	}
+
+
+	/**
+	 * Saves this feed as a file on the local disk. After the file is saved, a redirect
+	 * header may be sent to redirect the user to the newly created file.
+	 * @since 1.4
+	 *
+	 * @param filename	string	optional	the filename where a recent version of the feed is saved. If not specified, the filename is $_SERVER["PHP_SELF"] with the extension changed to .xml (see _generateFilename()).
+	 * @param redirect	boolean	optional	send an HTTP redirect header or not. If true, the user will be automatically redirected to the created file.
+	 */
+	function saveFeed($filename="", $displayContents=true) {
+		if ($filename=="") {
+			$filename = $this->_generateFilename();
+		}
+		$feedFile = fopen($filename, "w+");
+		if ($feedFile) {
+			fputs($feedFile,$this->createFeed());
+			fclose($feedFile);
+			if ($displayContents) {
+				$this->_redirect($filename);
+			}
+		} else {
+			echo "<br /><b>Error creating feed file, please check write permissions.</b><br />";
+		}
+	}
+
+}
+
+
+/**
+ * FeedDate is an internal class that stores a date for a feed or feed item.
+ * Usually, you won't need to use this.
+ */
+class FeedDate {
+	var $unix;
+
+	/**
+	 * Creates a new instance of FeedDate representing a given date.
+	 * Accepts RFC 822, ISO 8601 date formats as well as unix time stamps.
+	 * @param mixed $dateString optional the date this FeedDate will represent. If not specified, the current date and time is used.
+	 */
+	function FeedDate($dateString="") {
+		if ($dateString=="") $dateString = date("r");
+
+		if (is_integer($dateString)) {
+			$this->unix = $dateString;
+			return;
+		}
+		if (preg_match("~(?:(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun),\\s+)?(\\d{1,2})\\s+([a-zA-Z]{3})\\s+(\\d{4})\\s+(\\d{2}):(\\d{2}):(\\d{2})\\s+(.*)~",$dateString,$matches)) {
+			$months = Array("Jan"=>1,"Feb"=>2,"Mar"=>3,"Apr"=>4,"May"=>5,"Jun"=>6,"Jul"=>7,"Aug"=>8,"Sep"=>9,"Oct"=>10,"Nov"=>11,"Dec"=>12);
+			$this->unix = mktime($matches[4],$matches[5],$matches[6],$months[$matches[2]],$matches[1],$matches[3]);
+			if (substr($matches[7],0,1)=='+' OR substr($matches[7],0,1)=='-') {
+				$tzOffset = (substr($matches[7],0,3) * 60 + substr($matches[7],-2)) * 60;
+			} else {
+				if (strlen($matches[7])==1) {
+					$oneHour = 3600;
+					$ord = ord($matches[7]);
+					if ($ord < ord("M")) {
+						$tzOffset = (ord("A") - $ord - 1) * $oneHour;
+					} elseif ($ord >= ord("M") AND $matches[7]!="Z") {
+						$tzOffset = ($ord - ord("M")) * $oneHour;
+					} elseif ($matches[7]=="Z") {
+						$tzOffset = 0;
+					}
+				}
+				switch ($matches[7]) {
+					case "UT":
+					case "GMT":	$tzOffset = 0;
+				}
+			}
+			$this->unix += $tzOffset;
+			return;
+		}
+		if (preg_match("~(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2})(.*)~",$dateString,$matches)) {
+			$this->unix = mktime($matches[4],$matches[5],$matches[6],$matches[2],$matches[3],$matches[1]);
+			if (substr($matches[7],0,1)=='+' OR substr($matches[7],0,1)=='-') {
+				$tzOffset = (substr($matches[7],0,3) * 60 + substr($matches[7],-2)) * 60;
+			} else {
+				if ($matches[7]=="Z") {
+					$tzOffset = 0;
+				}
+			}
+			$this->unix += $tzOffset;
+			return;
+		}
+		$this->unix = 0;
+	}
+
+	/**
+	 * Gets the date stored in this FeedDate as an RFC 822 date.
+	 *
+	 * @return a date in RFC 822 format
+	 */
+	function rfc822() {
+		//return gmdate("r",$this->unix);
+		$date = gmdate("D, d M Y H:i:s", $this->unix);
+		if (TIME_ZONE!="") $date .= " ".str_replace(":","",TIME_ZONE);
+		return $date;
+	}
+
+	/**
+	 * Gets the date stored in this FeedDate as an ISO 8601 date.
+	 *
+	 * @return a date in ISO 8601 format
+	 */
+	function iso8601() {
+		$date = gmdate("Y-m-d\TH:i:sO",$this->unix);
+		$date = substr($date,0,22) . ':' . substr($date,-2);
+		if (TIME_ZONE!="") $date = str_replace("+00:00",TIME_ZONE,$date);
+		return $date;
+	}
+
+	/**
+	 * Gets the date stored in this FeedDate as unix time stamp.
+	 *
+	 * @return a date as a unix time stamp
+	 */
+	function unix() {
+		return $this->unix;
+	}
+}
+
+
+/**
+ * RSSCreator10 is a FeedCreator that implements RDF Site Summary (RSS) 1.0.
+ *
+ * @see http://www.purl.org/rss/1.0/
+ * @since 1.3
+ * @author Kai Blankenhorn <kaib@bitfolge.de>
+ */
+class RSSCreator10 extends FeedCreator {
+
+	/**
+	 * Builds the RSS feed's text. The feed will be compliant to RDF Site Summary (RSS) 1.0.
+	 * The feed will contain all items previously added in the same order.
+	 * @return    string    the feed's complete text
+	 */
+	function createFeed() {
+		$feed = "<?xml version=\"1.0\" encoding=\"".$this->encoding."\"?>\n";
+		$feed.= $this->_createGeneratorComment();
+		if ($this->cssStyleSheet=="") {
+			$cssStyleSheet = "http://www.w3.org/2000/08/w3c-synd/style.css";
+		}
+		$feed.= $this->_createStylesheetReferences();
+		$feed.= "<rdf:RDF\n";
+		$feed.= "    xmlns=\"http://purl.org/rss/1.0/\"\n";
+		$feed.= "    xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n";
+		$feed.= "    xmlns:slash=\"http://purl.org/rss/1.0/modules/slash/\"\n";
+		$feed.= "    xmlns:dc=\"http://purl.org/dc/elements/1.1/\">\n";
+		$feed.= "    <channel rdf:about=\"".$this->syndicationURL."\">\n";
+		$feed.= "        <title>".htmlspecialchars($this->title)."</title>\n";
+		$feed.= "        <description>".htmlspecialchars($this->description)."</description>\n";
+		$feed.= "        <link>".$this->link."</link>\n";
+		if ($this->image!=null) {
+			$feed.= "        <image rdf:resource=\"".$this->image->url."\" />\n";
+		}
+		$now = new FeedDate();
+		$feed.= "       <dc:date>".htmlspecialchars($now->iso8601())."</dc:date>\n";
+		$feed.= "        <items>\n";
+		$feed.= "            <rdf:Seq>\n";
+		for ($i=0;$i<count($this->items);$i++) {
+			$feed.= "                <rdf:li rdf:resource=\"".htmlspecialchars($this->items[$i]->link)."\"/>\n";
+		}
+		$feed.= "            </rdf:Seq>\n";
+		$feed.= "        </items>\n";
+		$feed.= "    </channel>\n";
+		if ($this->image!=null) {
+			$feed.= "    <image rdf:about=\"".$this->image->url."\">\n";
+			$feed.= "        <title>".$this->image->title."</title>\n";
+			$feed.= "        <link>".$this->image->link."</link>\n";
+			$feed.= "        <url>".$this->image->url."</url>\n";
+			$feed.= "    </image>\n";
+		}
+		$feed.= $this->_createAdditionalElements($this->additionalElements, "    ");
+
+		for ($i=0;$i<count($this->items);$i++) {
+			$feed.= "    <item rdf:about=\"".htmlspecialchars($this->items[$i]->link)."\">\n";
+			//$feed.= "        <dc:type>Posting</dc:type>\n";
+			$feed.= "        <dc:format>text/html</dc:format>\n";
+			if ($this->items[$i]->date!=null) {
+				$itemDate = new FeedDate($this->items[$i]->date);
+				$feed.= "        <dc:date>".htmlspecialchars($itemDate->iso8601())."</dc:date>\n";
+			}
+			if ($this->items[$i]->source!="") {
+				$feed.= "        <dc:source>".htmlspecialchars($this->items[$i]->source)."</dc:source>\n";
+			}
+			if ($this->items[$i]->author!="") {
+				$feed.= "        <dc:creator>".htmlspecialchars($this->items[$i]->author)."</dc:creator>\n";
+			}
+			$feed.= "        <title>".htmlspecialchars(strip_tags(strtr($this->items[$i]->title,"\n\r","  ")))."</title>\n";
+			$feed.= "        <link>".htmlspecialchars($this->items[$i]->link)."</link>\n";
+			$feed.= "        <description>".htmlspecialchars($this->items[$i]->description)."</description>\n";
+			$feed.= $this->_createAdditionalElements($this->items[$i]->additionalElements, "        ");
+			$feed.= "    </item>\n";
+		}
+		$feed.= "</rdf:RDF>\n";
+		return $feed;
+	}
+}
+
+
+
+/**
+ * RSSCreator091 is a FeedCreator that implements RSS 0.91 Spec, revision 3.
+ *
+ * @see http://my.netscape.com/publish/formats/rss-spec-0.91.html
+ * @since 1.3
+ * @author Kai Blankenhorn <kaib@bitfolge.de>
+ */
+class RSSCreator091 extends FeedCreator {
+
+	/**
+	 * Stores this RSS feed's version number.
+	 * @access private
+	 */
+	var $RSSVersion;
+
+	function RSSCreator091() {
+		$this->_setRSSVersion("0.91");
+		$this->contentType = "application/rss+xml";
+	}
+
+	/**
+	 * Sets this RSS feed's version number.
+	 * @access private
+	 */
+	function _setRSSVersion($version) {
+		$this->RSSVersion = $version;
+	}
+
+	/**
+	 * Builds the RSS feed's text. The feed will be compliant to RDF Site Summary (RSS) 1.0.
+	 * The feed will contain all items previously added in the same order.
+	 * @return    string    the feed's complete text
+	 */
+	function createFeed() {
+		$feed = "<?xml version=\"1.0\" encoding=\"".$this->encoding."\"?>\n";
+		$feed.= $this->_createGeneratorComment();
+		$feed.= $this->_createStylesheetReferences();
+		$feed.= "<rss version=\"".$this->RSSVersion."\">\n";
+		$feed.= "    <channel>\n";
+		$feed.= "        <title>".FeedCreator::iTrunc(htmlspecialchars($this->title),100)."</title>\n";
+		$this->descriptionTruncSize = 500;
+		$feed.= "        <description>".$this->getDescription()."</description>\n";
+		$feed.= "        <link>".$this->link."</link>\n";
+		$now = new FeedDate();
+		$feed.= "        <lastBuildDate>".htmlspecialchars($now->rfc822())."</lastBuildDate>\n";
+		$feed.= "        <generator>".FEEDCREATOR_VERSION."</generator>\n";
+
+		if ($this->image!=null) {
+			$feed.= "        <image>\n";
+			$feed.= "            <url>".$this->image->url."</url>\n";
+			$feed.= "            <title>".FeedCreator::iTrunc(htmlspecialchars($this->image->title),100)."</title>\n";
+			$feed.= "            <link>".$this->image->link."</link>\n";
+			if ($this->image->width!="") {
+				$feed.= "            <width>".$this->image->width."</width>\n";
+			}
+			if ($this->image->height!="") {
+				$feed.= "            <height>".$this->image->height."</height>\n";
+			}
+			if ($this->image->description!="") {
+				$feed.= "            <description>".$this->image->getDescription()."</description>\n";
+			}
+			$feed.= "        </image>\n";
+		}
+		if ($this->language!="") {
+			$feed.= "        <language>".$this->language."</language>\n";
+		}
+		if ($this->copyright!="") {
+			$feed.= "        <copyright>".FeedCreator::iTrunc(htmlspecialchars($this->copyright),100)."</copyright>\n";
+		}
+		if ($this->editor!="") {
+			$feed.= "        <managingEditor>".FeedCreator::iTrunc(htmlspecialchars($this->editor),100)."</managingEditor>\n";
+		}
+		if ($this->webmaster!="") {
+			$feed.= "        <webMaster>".FeedCreator::iTrunc(htmlspecialchars($this->webmaster),100)."</webMaster>\n";
+		}
+		if ($this->pubDate!="") {
+			$pubDate = new FeedDate($this->pubDate);
+			$feed.= "        <pubDate>".htmlspecialchars($pubDate->rfc822())."</pubDate>\n";
+		}
+		if ($this->category!="") {
+			$feed.= "        <category>".htmlspecialchars($this->category)."</category>\n";
+		}
+		if ($this->docs!="") {
+			$feed.= "        <docs>".FeedCreator::iTrunc(htmlspecialchars($this->docs),500)."</docs>\n";
+		}
+		if ($this->ttl!="") {
+			$feed.= "        <ttl>".htmlspecialchars($this->ttl)."</ttl>\n";
+		}
+		if ($this->rating!="") {
+			$feed.= "        <rating>".FeedCreator::iTrunc(htmlspecialchars($this->rating),500)."</rating>\n";
+		}
+		if ($this->skipHours!="") {
+			$feed.= "        <skipHours>".htmlspecialchars($this->skipHours)."</skipHours>\n";
+		}
+		if ($this->skipDays!="") {
+			$feed.= "        <skipDays>".htmlspecialchars($this->skipDays)."</skipDays>\n";
+		}
+		$feed.= $this->_createAdditionalElements($this->additionalElements, "    ");
+
+		for ($i=0;$i<count($this->items);$i++) {
+			$feed.= "        <item>\n";
+			$feed.= "            <title>".FeedCreator::iTrunc(htmlspecialchars(strip_tags($this->items[$i]->title)),100)."</title>\n";
+			$feed.= "            <link>".htmlspecialchars($this->items[$i]->link)."</link>\n";
+			$feed.= "            <description>".$this->items[$i]->getDescription()."</description>\n";
+
+			if ($this->items[$i]->author!="") {
+				$feed.= "            <author>".htmlspecialchars($this->items[$i]->author)."</author>\n";
+			}
+			/*
+			// on hold
+			if ($this->items[$i]->source!="") {
+					$feed.= "            <source>".htmlspecialchars($this->items[$i]->source)."</source>\n";
+			}
+			*/
+			if ($this->items[$i]->category!="") {
+				$feed.= "            <category>".htmlspecialchars($this->items[$i]->category)."</category>\n";
+			}
+			if ($this->items[$i]->comments!="") {
+				$feed.= "            <comments>".htmlspecialchars($this->items[$i]->comments)."</comments>\n";
+			}
+			if ($this->items[$i]->date!="") {
+			$itemDate = new FeedDate($this->items[$i]->date);
+				$feed.= "            <pubDate>".htmlspecialchars($itemDate->rfc822())."</pubDate>\n";
+			}
+			if ($this->items[$i]->guid!="") {
+				$feed.= "            <guid isPermaLink=\"false\">".htmlspecialchars($this->items[$i]->guid)."</guid>\n";
+			}
+			$feed.= $this->_createAdditionalElements($this->items[$i]->additionalElements, "        ");
+			$feed.= "        </item>\n";
+		}
+		$feed.= "    </channel>\n";
+		$feed.= "</rss>\n";
+		return $feed;
+	}
+}
+
+
+
+/**
+ * RSSCreator20 is a FeedCreator that implements RDF Site Summary (RSS) 2.0.
+ *
+ * @see http://backend.userland.com/rss
+ * @since 1.3
+ * @author Kai Blankenhorn <kaib@bitfolge.de>
+ */
+class RSSCreator20 extends RSSCreator091 {
+
+    function RSSCreator20() {
+        parent::_setRSSVersion("2.0");
+    }
+
+}
+
+
+/**
+ * PIECreator01 is a FeedCreator that implements the emerging PIE specification,
+ * as in http://intertwingly.net/wiki/pie/Syntax.
+ *
+ * @deprecated
+ * @since 1.3
+ * @author Scott Reynen <scott@randomchaos.com> and Kai Blankenhorn <kaib@bitfolge.de>
+ */
+class PIECreator01 extends FeedCreator {
+
+	function PIECreator01() {
+		$this->encoding = "utf-8";
+	}
+
+	function createFeed() {
+		$feed = "<?xml version=\"1.0\" encoding=\"".$this->encoding."\"?>\n";
+		$feed.= $this->_createStylesheetReferences();
+		$feed.= "<feed version=\"0.1\" xmlns=\"http://example.com/newformat#\">\n";
+		$feed.= "    <title>".FeedCreator::iTrunc(htmlspecialchars($this->title),100)."</title>\n";
+		$this->truncSize = 500;
+		$feed.= "    <subtitle>".$this->getDescription()."</subtitle>\n";
+		$feed.= "    <link>".$this->link."</link>\n";
+		for ($i=0;$i<count($this->items);$i++) {
+			$feed.= "    <entry>\n";
+			$feed.= "        <title>".FeedCreator::iTrunc(htmlspecialchars(strip_tags($this->items[$i]->title)),100)."</title>\n";
+			$feed.= "        <link>".htmlspecialchars($this->items[$i]->link)."</link>\n";
+			$itemDate = new FeedDate($this->items[$i]->date);
+			$feed.= "        <created>".htmlspecialchars($itemDate->iso8601())."</created>\n";
+			$feed.= "        <issued>".htmlspecialchars($itemDate->iso8601())."</issued>\n";
+			$feed.= "        <modified>".htmlspecialchars($itemDate->iso8601())."</modified>\n";
+			$feed.= "        <id>".htmlspecialchars($this->items[$i]->guid)."</id>\n";
+			if ($this->items[$i]->author!="") {
+				$feed.= "        <author>\n";
+				$feed.= "            <name>".htmlspecialchars($this->items[$i]->author)."</name>\n";
+				if ($this->items[$i]->authorEmail!="") {
+					$feed.= "            <email>".$this->items[$i]->authorEmail."</email>\n";
+				}
+				$feed.="        </author>\n";
+			}
+			$feed.= "        <content type=\"text/html\" xml:lang=\"en-us\">\n";
+			$feed.= "            <div xmlns=\"http://www.w3.org/1999/xhtml\">".$this->items[$i]->getDescription()."</div>\n";
+			$feed.= "        </content>\n";
+			$feed.= "    </entry>\n";
+		}
+		$feed.= "</feed>\n";
+		return $feed;
+	}
+}
+
+
+/**
+ * AtomCreator03 is a FeedCreator that implements the atom specification,
+ * as in http://www.intertwingly.net/wiki/pie/FrontPage.
+ * Please note that just by using AtomCreator03 you won't automatically
+ * produce valid atom files. For example, you have to specify either an editor
+ * for the feed or an author for every single feed item.
+ *
+ * Some elements have not been implemented yet. These are (incomplete list):
+ * author URL, item author's email and URL, item contents, alternate links,
+ * other link content types than text/html. Some of them may be created with
+ * AtomCreator03::additionalElements.
+ *
+ * @see FeedCreator#additionalElements
+ * @since 1.6
+ * @author Kai Blankenhorn <kaib@bitfolge.de>, Scott Reynen <scott@randomchaos.com>
+ */
+class AtomCreator03 extends FeedCreator {
+
+	function AtomCreator03() {
+		$this->contentType = "application/atom+xml";
+		$this->encoding = "utf-8";
+	}
+
+	function createFeed() {
+		$feed = "<?xml version=\"1.0\" encoding=\"".$this->encoding."\"?>\n";
+		$feed.= $this->_createGeneratorComment();
+		$feed.= $this->_createStylesheetReferences();
+		$feed.= "<feed version=\"0.3\" xmlns=\"http://purl.org/atom/ns#\"";
+		if ($this->language!="") {
+			$feed.= " xml:lang=\"".$this->language."\"";
+		}
+		$feed.= ">\n";
+		$feed.= "    <title>".htmlspecialchars($this->title)."</title>\n";
+		$feed.= "    <tagline>".htmlspecialchars($this->description)."</tagline>\n";
+		$feed.= "    <link rel=\"alternate\" type=\"text/html\" href=\"".htmlspecialchars($this->link)."\"/>\n";
+		$feed.= "    <id>".htmlspecialchars($this->link)."</id>\n";
+		$now = new FeedDate();
+		$feed.= "    <modified>".htmlspecialchars($now->iso8601())."</modified>\n";
+		if ($this->editor!="") {
+			$feed.= "    <author>\n";
+			$feed.= "        <name>".$this->editor."</name>\n";
+			if ($this->editorEmail!="") {
+				$feed.= "        <email>".$this->editorEmail."</email>\n";
+			}
+			$feed.= "    </author>\n";
+		}
+		$feed.= "    <generator>".FEEDCREATOR_VERSION."</generator>\n";
+		$feed.= $this->_createAdditionalElements($this->additionalElements, "    ");
+		for ($i=0;$i<count($this->items);$i++) {
+			$feed.= "    <entry>\n";
+			$feed.= "        <title>".htmlspecialchars(strip_tags($this->items[$i]->title))."</title>\n";
+			$feed.= "        <link rel=\"alternate\" type=\"text/html\" href=\"".htmlspecialchars($this->items[$i]->link)."\"/>\n";
+			if ($this->items[$i]->date=="") {
+				$this->items[$i]->date = time();
+			}
+			$itemDate = new FeedDate($this->items[$i]->date);
+			$feed.= "        <created>".htmlspecialchars($itemDate->iso8601())."</created>\n";
+			$feed.= "        <issued>".htmlspecialchars($itemDate->iso8601())."</issued>\n";
+			$feed.= "        <modified>".htmlspecialchars($itemDate->iso8601())."</modified>\n";
+			$feed.= "        <id>".htmlspecialchars($this->items[$i]->link)."</id>\n";
+			$feed.= $this->_createAdditionalElements($this->items[$i]->additionalElements, "        ");
+			if ($this->items[$i]->author!="") {
+				$feed.= "        <author>\n";
+				$feed.= "            <name>".htmlspecialchars($this->items[$i]->author)."</name>\n";
+				$feed.= "        </author>\n";
+			}
+			if ($this->items[$i]->description!="") {
+				$feed.= "        <summary>".htmlspecialchars($this->items[$i]->description)."</summary>\n";
+			}
+			$feed.= "    </entry>\n";
+		}
+		$feed.= "</feed>\n";
+		return $feed;
+	}
+}
+
+
+/**
+ * MBOXCreator is a FeedCreator that implements the mbox format
+ * as described in http://www.qmail.org/man/man5/mbox.html
+ *
+ * @since 1.3
+ * @author Kai Blankenhorn <kaib@bitfolge.de>
+ */
+class MBOXCreator extends FeedCreator {
+
+	function MBOXCreator() {
+		$this->contentType = "text/plain";
+		$this->encoding = "ISO-8859-15";
+	}
+
+	function qp_enc($input = "", $line_max = 76) {
+		$hex = array('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F');
+		$lines = preg_split("/(?:\r\n|\r|\n)/", $input);
+		$eol = "\r\n";
+		$escape = "=";
+		$output = "";
+		while( list(, $line) = each($lines) ) {
+			//$line = rtrim($line); // remove trailing white space -> no =20\r\n necessary
+			$linlen = strlen($line);
+			$newline = "";
+			for($i = 0; $i < $linlen; $i++) {
+				$c = substr($line, $i, 1);
+				$dec = ord($c);
+				if ( ($dec == 32) && ($i == ($linlen - 1)) ) { // convert space at eol only
+					$c = "=20";
+				} elseif ( ($dec == 61) || ($dec < 32 ) || ($dec > 126) ) { // always encode "\t", which is *not* required
+					$h2 = floor($dec/16); $h1 = floor($dec%16);
+					$c = $escape.$hex["$h2"].$hex["$h1"];
+				}
+				if ( (strlen($newline) + strlen($c)) >= $line_max ) { // CRLF is not counted
+					$output .= $newline.$escape.$eol; // soft line break; " =\r\n" is okay
+					$newline = "";
+				}
+				$newline .= $c;
+			} // end of for
+			$output .= $newline.$eol;
+		}
+		return trim($output);
+	}
+
+
+	/**
+	 * Builds the MBOX contents.
+	 * @return    string    the feed's complete text
+	 */
+	function createFeed() {
+		for ($i=0;$i<count($this->items);$i++) {
+			if ($this->items[$i]->author!="") {
+				$from = $this->items[$i]->author;
+			} else {
+				$from = $this->title;
+			}
+			$itemDate = new FeedDate($this->items[$i]->date);
+			$feed.= "From ".strtr(MBOXCreator::qp_enc($from)," ","_")." ".date("D M d H:i:s Y",$itemDate->unix())."\n";
+			$feed.= "Content-Type: text/plain;\n";
+			$feed.= "	charset=\"".$this->encoding."\"\n";
+			$feed.= "Content-Transfer-Encoding: quoted-printable\n";
+			$feed.= "Content-Type: text/plain\n";
+			$feed.= "From: \"".MBOXCreator::qp_enc($from)."\"\n";
+			$feed.= "Date: ".$itemDate->rfc822()."\n";
+			$feed.= "Subject: ".MBOXCreator::qp_enc(FeedCreator::iTrunc($this->items[$i]->title,100))."\n";
+			$feed.= "\n";
+			$body = chunk_split(MBOXCreator::qp_enc($this->items[$i]->description));
+			$feed.= preg_replace("~\nFrom ([^\n]*)(\n?)~","\n>From $1$2\n",$body);
+			$feed.= "\n";
+			$feed.= "\n";
+		}
+		return $feed;
+	}
+
+	/**
+	 * Generate a filename for the feed cache file. Overridden from FeedCreator to prevent XML data types.
+	 * @return string the feed cache filename
+	 * @since 1.4
+	 * @access private
+	 */
+	function _generateFilename() {
+		$fileInfo = pathinfo($_SERVER["PHP_SELF"]);
+		return substr($fileInfo["basename"],0,-(strlen($fileInfo["extension"])+1)).".mbox";
+	}
+}
+
+
+/**
+ * OPMLCreator is a FeedCreator that implements OPML 1.0.
+ *
+ * @see http://opml.scripting.com/spec
+ * @author Dirk Clemens, Kai Blankenhorn
+ * @since 1.5
+ */
+class OPMLCreator extends FeedCreator {
+
+	function OPMLCreator() {
+		$this->encoding = "utf-8";
+	}
+
+	function createFeed() {
+		$feed = "<?xml version=\"1.0\" encoding=\"".$this->encoding."\"?>\n";
+		$feed.= $this->_createGeneratorComment();
+		$feed.= $this->_createStylesheetReferences();
+		$feed.= "<opml xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n";
+		$feed.= "    <head>\n";
+		$feed.= "        <title>".htmlspecialchars($this->title)."</title>\n";
+		if ($this->pubDate!="") {
+			$date = new FeedDate($this->pubDate);
+			$feed.= "         <dateCreated>".$date->rfc822()."</dateCreated>\n";
+		}
+		if ($this->lastBuildDate!="") {
+			$date = new FeedDate($this->lastBuildDate);
+			$feed.= "         <dateModified>".$date->rfc822()."</dateModified>\n";
+		}
+		if ($this->editor!="") {
+			$feed.= "         <ownerName>".$this->editor."</ownerName>\n";
+		}
+		if ($this->editorEmail!="") {
+			$feed.= "         <ownerEmail>".$this->editorEmail."</ownerEmail>\n";
+		}
+		$feed.= "    </head>\n";
+		$feed.= "    <body>\n";
+		for ($i=0;$i<count($this->items);$i++) {
+			$feed.= "    <outline type=\"rss\" ";
+			$title = htmlspecialchars(strip_tags(strtr($this->items[$i]->title,"\n\r","  ")));
+			$feed.= " title=\"".$title."\"";
+			$feed.= " text=\"".$title."\"";
+			//$feed.= " description=\"".htmlspecialchars($this->items[$i]->description)."\"";
+			$feed.= " url=\"".htmlspecialchars($this->items[$i]->link)."\"";
+			$feed.= "/>\n";
+		}
+		$feed.= "    </body>\n";
+		$feed.= "</opml>\n";
+		return $feed;
+	}
+}
+
+
+
+/**
+ * HTMLCreator is a FeedCreator that writes an HTML feed file to a specific
+ * location, overriding the createFeed method of the parent FeedCreator.
+ * The HTML produced can be included over http by scripting languages, or serve
+ * as the source for an IFrame.
+ * All output by this class is embedded in <div></div> tags to enable formatting
+ * using CSS.
+ *
+ * @author Pascal Van Hecke
+ * @since 1.7
+ */
+class HTMLCreator extends FeedCreator {
+
+	var $contentType = "text/html";
+
+	/**
+	 * Contains HTML to be output at the start of the feed's html representation.
+	 */
+	var $header;
+
+	/**
+	 * Contains HTML to be output at the end of the feed's html representation.
+	 */
+	var $footer ;
+
+	/**
+	 * Contains HTML to be output between entries. A separator is only used in
+	 * case of multiple entries.
+	 */
+	var $separator;
+
+	/**
+	 * Used to prefix the stylenames to make sure they are unique
+	 * and do not clash with stylenames on the users' page.
+	 */
+	var $stylePrefix;
+
+	/**
+	 * Determines whether the links open in a new window or not.
+	 */
+	var $openInNewWindow = true;
+
+	var $imageAlign ="right";
+
+	/**
+	 * In case of very simple output you may want to get rid of the style tags,
+	 * hence this variable.  There's no equivalent on item level, but of course you can
+	 * add strings to it while iterating over the items ($this->stylelessOutput .= ...)
+	 * and when it is non-empty, ONLY the styleless output is printed, the rest is ignored
+	 * in the function createFeed().
+	 */
+	var $stylelessOutput ="";
+
+	/**
+	 * Writes the HTML.
+	 * @return    string    the scripts's complete text
+	 */
+	function createFeed() {
+		// if there is styleless output, use the content of this variable and ignore the rest
+		if ($this->stylelessOutput!="") {
+			return $this->stylelessOutput;
+		}
+
+		//if no stylePrefix is set, generate it yourself depending on the script name
+		if ($this->stylePrefix=="") {
+			$this->stylePrefix = str_replace(".", "_", $this->_generateFilename())."_";
+		}
+
+		//set an openInNewWindow_token_to be inserted or not
+		if ($this->openInNewWindow) {
+			$targetInsert = " target='_blank'";
+		}
+
+		// use this array to put the lines in and implode later with "document.write" javascript
+		$feedArray = array();
+		if ($this->image!=null) {
+			$imageStr = "<a href='".$this->image->link."'".$targetInsert.">".
+							"<img src='".$this->image->url."' border='0' alt='".
+							FeedCreator::iTrunc(htmlspecialchars($this->image->title),100).
+							"' align='".$this->imageAlign."' ";
+			if ($this->image->width) {
+				$imageStr .=" width='".$this->image->width. "' ";
+			}
+			if ($this->image->height) {
+				$imageStr .=" height='".$this->image->height."' ";
+			}
+			$imageStr .="/></a>";
+			$feedArray[] = $imageStr;
+		}
+
+		if ($this->title) {
+			$feedArray[] = "<div class='".$this->stylePrefix."title'><a href='".$this->link."' ".$targetInsert." class='".$this->stylePrefix."title'>".
+				FeedCreator::iTrunc(htmlspecialchars($this->title),100)."</a></div>";
+		}
+		if ($this->getDescription()) {
+			$feedArray[] = "<div class='".$this->stylePrefix."description'>".
+				str_replace("]]>", "", str_replace("<![CDATA[", "", $this->getDescription())).
+				"</div>";
+		}
+
+		if ($this->header) {
+			$feedArray[] = "<div class='".$this->stylePrefix."header'>".$this->header."</div>";
+		}
+
+		for ($i=0;$i<count($this->items);$i++) {
+			if ($this->separator and $i > 0) {
+				$feedArray[] = "<div class='".$this->stylePrefix."separator'>".$this->separator."</div>";
+			}
+
+			if ($this->items[$i]->title) {
+				if ($this->items[$i]->link) {
+					$feedArray[] =
+						"<div class='".$this->stylePrefix."item_title'><a href='".$this->items[$i]->link."' class='".$this->stylePrefix.
+						"item_title'".$targetInsert.">".FeedCreator::iTrunc(htmlspecialchars(strip_tags($this->items[$i]->title)),100).
+						"</a></div>";
+				} else {
+					$feedArray[] =
+						"<div class='".$this->stylePrefix."item_title'>".
+						FeedCreator::iTrunc(htmlspecialchars(strip_tags($this->items[$i]->title)),100).
+						"</div>";
+				}
+			}
+			if ($this->items[$i]->getDescription()) {
+				$feedArray[] =
+				"<div class='".$this->stylePrefix."item_description'>".
+					str_replace("]]>", "", str_replace("<![CDATA[", "", $this->items[$i]->getDescription())).
+					"</div>";
+			}
+		}
+		if ($this->footer) {
+			$feedArray[] = "<div class='".$this->stylePrefix."footer'>".$this->footer."</div>";
+		}
+
+		$feed= "".join($feedArray, "\r\n");
+		return $feed;
+	}
+
+	/**
+	 * Overrrides parent to produce .html extensions
+	 *
+	 * @return string the feed cache filename
+	 * @since 1.4
+	 * @access private
+	 */
+	function _generateFilename() {
+		$fileInfo = pathinfo($_SERVER["PHP_SELF"]);
+		return substr($fileInfo["basename"],0,-(strlen($fileInfo["extension"])+1)).".html";
+	}
+}
+
+
+/**
+ * JSCreator is a class that writes a js file to a specific
+ * location, overriding the createFeed method of the parent HTMLCreator.
+ *
+ * @author Pascal Van Hecke
+ */
+class JSCreator extends HTMLCreator {
+	var $contentType = "text/javascript";
+
+	/**
+	 * writes the javascript
+	 * @return    string    the scripts's complete text
+	 */
+	function createFeed()
+	{
+		$feed = parent::createFeed();
+		$feedArray = explode("\n",$feed);
+
+		$jsFeed = "";
+		foreach ($feedArray as $value) {
+			$jsFeed .= "document.write('".trim(addslashes($value))."');\n";
+		}
+		return $jsFeed;
+	}
+
+	/**
+	 * Overrrides parent to produce .js extensions
+	 *
+	 * @return string the feed cache filename
+	 * @since 1.4
+	 * @access private
+	 */
+	function _generateFilename() {
+		$fileInfo = pathinfo($_SERVER["PHP_SELF"]);
+		return substr($fileInfo["basename"],0,-(strlen($fileInfo["extension"])+1)).".js";
+	}
+
+}
+
+
+
+/*** TEST SCRIPT *********************************************************
+
+//include("feedcreator.class.php");
+
+$rss = new UniversalFeedCreator();
+$rss->useCached();
+$rss->title = "PHP news";
+$rss->description = "daily news from the PHP scripting world";
+
+//optional
+//$rss->descriptionTruncSize = 500;
+//$rss->descriptionHtmlSyndicated = true;
+//$rss->xslStyleSheet = "http://feedster.com/rss20.xsl";
+
+$rss->link = "http://www.dailyphp.net/news";
+$rss->feedURL = "http://www.dailyphp.net/".$PHP_SELF;
+
+$image = new FeedImage();
+$image->title = "dailyphp.net logo";
+$image->url = "http://www.dailyphp.net/images/logo.gif";
+$image->link = "http://www.dailyphp.net";
+$image->description = "Feed provided by dailyphp.net. Click to visit.";
+
+//optional
+$image->descriptionTruncSize = 500;
+$image->descriptionHtmlSyndicated = true;
+
+$rss->image = $image;
+
+// get your news items from somewhere, e.g. your database:
+//mysql_select_db($dbHost, $dbUser, $dbPass);
+//$res = mysql_query("SELECT * FROM news ORDER BY newsdate DESC");
+//while ($data = mysql_fetch_object($res)) {
+	$item = new FeedItem();
+	$item->title = "This is an the test title of an item";
+	$item->link = "http://localhost/item/";
+	$item->description = "<b>description in </b><br/>HTML";
+
+	//optional
+	//item->descriptionTruncSize = 500;
+	$item->descriptionHtmlSyndicated = true;
+
+	$item->date = time();
+	$item->source = "http://www.dailyphp.net";
+	$item->author = "John Doe";
+
+	$rss->addItem($item);
+//}
+
+// valid format strings are: RSS0.91, RSS1.0, RSS2.0, PIE0.1, MBOX, OPML, ATOM0.3, HTML, JS
+echo $rss->saveFeed("RSS0.91", "feed.xml");
+
+
+
+***************************************************************************/
+
+?>
Index: /tags/2.0.2/include/filter.inc.php
===================================================================
--- /tags/2.0.2/include/filter.inc.php	(revision 3278)
+++ /tags/2.0.2/include/filter.inc.php	(revision 3278)
@@ -0,0 +1,144 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// $filter['enabled']: Filter is enabled
+// $filter['recent_period']: Recent period used to computed filter data
+// $filter['categories']: Computed data of filtered categories
+// $filter['visible_categories']:
+//  List of visible categories (count(visible) < count(forbidden) more often)
+// $filter['visible_images']: List of visible images
+
+if (!get_filter_page_value('cancel'))
+{
+  if (isset($_GET['filter']))
+  {
+    $filter['matches'] = array();
+    $filter['enabled'] =
+      preg_match('/^start-recent-(\d+)$/', $_GET['filter'], $filter['matches']) === 1;
+  }
+  else
+  {
+    $filter['enabled'] = pwg_get_session_var('filter_enabled', false);
+  }
+}
+else
+{
+  $filter['enabled'] = false;
+}
+
+if ($filter['enabled'])
+{
+  $filter_key = pwg_get_session_var('filter_check_key', array('user'=>0,'recent_period'=>-1, 'time'=>0, 'date'=> '') );
+
+  if (isset($filter['matches']))
+  {
+    $filter['recent_period'] = $filter['matches'][1];
+  }
+  else
+  {
+    $filter['recent_period'] = $filter_key['recent_period']>0 ? $filter_key['recent_period'] : $user['recent_period'];
+  }
+
+  if (
+      // New filter
+      !pwg_get_session_var('filter_enabled', false) or
+      // Cache data updated
+      $filter_key['time'] <= $user['cache_update_time'] or
+      // Date, period, user are changed
+      $filter_key['user'] != $user['id'] or
+      $filter_key['recent_period'] != $filter['recent_period'] or
+      $filter_key['date'] != date('Ymd')
+    )
+  {
+    // Need to compute dats
+    $filter_key = array(
+      'user'=>(int)$user['id'],'recent_period'=>(int)$filter['recent_period'], 'time'=>time(), 'date'=> date('Ymd')
+     );
+
+    $filter['categories'] = get_computed_categories($user, (int)$filter['recent_period']);
+
+    $filter['visible_categories'] = implode(',', array_keys($filter['categories']));
+    if (empty($filter['visible_categories']))
+    {
+      // Must be not empty
+      $filter['visible_categories'] = -1;
+    }
+
+    $query ='
+SELECT
+  distinct image_id
+FROM '.
+  IMAGE_CATEGORY_TABLE.' INNER JOIN '.IMAGES_TABLE.' ON image_id = id
+WHERE ';
+    if (!empty($filter['visible_categories']))
+    {
+    $query.= '
+  category_id  IN ('.$filter['visible_categories'].') and';
+    }
+  $query.= '
+    date_available >= SUBDATE(
+      CURRENT_DATE,INTERVAL '.$filter['recent_period'].' DAY)';
+
+    $filter['visible_images'] = implode(',', array_from_query($query, 'image_id'));
+
+    if (empty($filter['visible_images']))
+    {
+      // Must be not empty
+      $filter['visible_images'] = -1;
+    }
+
+    // Save filter data on session
+    pwg_set_session_var('filter_enabled', $filter['enabled']);
+    pwg_set_session_var('filter_check_key', $filter_key);
+    pwg_set_session_var('filter_categories', serialize($filter['categories']));
+    pwg_set_session_var('filter_visible_categories', $filter['visible_categories']);
+    pwg_set_session_var('filter_visible_images', $filter['visible_images']);
+  }
+  else
+  {
+    // Read only data
+    $filter['categories'] = unserialize(pwg_get_session_var('filter_categories', serialize(array())));
+    $filter['visible_categories'] = pwg_get_session_var('filter_visible_categories', '');
+    $filter['visible_images'] = pwg_get_session_var('filter_visible_images', '');
+  }
+  unset($filter_key);
+  if (get_filter_page_value('add_notes'))
+  {
+    $header_notes[] = l10n_dec('note_filter_day', 'note_filter_days', $filter['recent_period']);
+  }
+  include_once(PHPWG_ROOT_PATH.'include/functions_filter.inc.php');
+}
+else
+{
+  if (pwg_get_session_var('filter_enabled', false))
+  {
+    pwg_unset_session_var('filter_enabled');
+    pwg_unset_session_var('filter_check_key');
+    pwg_unset_session_var('filter_categories');
+    pwg_unset_session_var('filter_visible_categories');
+    pwg_unset_session_var('filter_visible_images');
+  }
+}
+
+
+?>
Index: /tags/2.0.2/include/functions.inc.php
===================================================================
--- /tags/2.0.2/include/functions.inc.php	(revision 3278)
+++ /tags/2.0.2/include/functions.inc.php	(revision 3278)
@@ -0,0 +1,1495 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+include_once( PHPWG_ROOT_PATH .'include/functions_user.inc.php' );
+include_once( PHPWG_ROOT_PATH .'include/functions_cookie.inc.php' );
+include_once( PHPWG_ROOT_PATH .'include/functions_session.inc.php' );
+include_once( PHPWG_ROOT_PATH .'include/functions_category.inc.php' );
+include_once( PHPWG_ROOT_PATH .'include/functions_xml.inc.php' );
+include_once( PHPWG_ROOT_PATH .'include/functions_html.inc.php' );
+include_once( PHPWG_ROOT_PATH .'include/functions_tag.inc.php' );
+include_once( PHPWG_ROOT_PATH .'include/functions_url.inc.php' );
+include_once( PHPWG_ROOT_PATH .'include/functions_plugins.inc.php' );
+
+//----------------------------------------------------------- generic functions
+
+/**
+ * returns an array containing the possible values of an enum field
+ *
+ * @param string tablename
+ * @param string fieldname
+ */
+function get_enums($table, $field)
+{
+  // retrieving the properties of the table. Each line represents a field :
+  // columns are 'Field', 'Type'
+  $result = pwg_query('desc '.$table);
+  while ($row = mysql_fetch_array($result))
+  {
+    // we are only interested in the the field given in parameter for the
+    // function
+    if ($row['Field'] == $field)
+    {
+      // retrieving possible values of the enum field
+      // enum('blue','green','black')
+      $options = explode(',', substr($row['Type'], 5, -1));
+      foreach ($options as $i => $option)
+      {
+        $options[$i] = str_replace("'", '',$option);
+      }
+    }
+  }
+  mysql_free_result($result);
+  return $options;
+}
+
+// get_boolean transforms a string to a boolean value. If the string is
+// "false" (case insensitive), then the boolean value false is returned. In
+// any other case, true is returned.
+function get_boolean( $string )
+{
+  $boolean = true;
+  if ( 'false' == strtolower($string) )
+  {
+    $boolean = false;
+  }
+  return $boolean;
+}
+
+/**
+ * returns boolean string 'true' or 'false' if the given var is boolean
+ *
+ * @param mixed $var
+ * @return mixed
+ */
+function boolean_to_string($var)
+{
+  if (is_bool($var))
+  {
+    return $var ? 'true' : 'false';
+  }
+  else
+  {
+    return $var;
+  }
+}
+
+// The function get_moment returns a float value coresponding to the number
+// of seconds since the unix epoch (1st January 1970) and the microseconds
+// are precised : e.g. 1052343429.89276600
+function get_moment()
+{
+  $t1 = explode( ' ', microtime() );
+  $t2 = explode( '.', $t1[0] );
+  $t2 = $t1[1].'.'.$t2[1];
+  return $t2;
+}
+
+// The function get_elapsed_time returns the number of seconds (with 3
+// decimals precision) between the start time and the end time given.
+function get_elapsed_time( $start, $end )
+{
+  return number_format( $end - $start, 3, '.', ' ').' s';
+}
+
+// - The replace_space function replaces space and '-' characters
+//   by their HTML equivalent  &nbsb; and &minus;
+// - The function does not replace characters in HTML tags
+// - This function was created because IE5 does not respect the
+//   CSS "white-space: nowrap;" property unless space and minus
+//   characters are replaced like this function does.
+// - Example :
+//                 <div class="foo">My friend</div>
+//               ( 01234567891111111111222222222233 )
+//               (           0123456789012345678901 )
+// becomes :
+//             <div class="foo">My&nbsp;friend</div>
+function replace_space( $string )
+{
+  //return $string;
+  $return_string = '';
+  // $remaining is the rest of the string where to replace spaces characters
+  $remaining = $string;
+  // $start represents the position of the next '<' character
+  // $end   represents the position of the next '>' character
+  ; // -> 0
+  $end   = strpos ( $remaining, '>' ); // -> 16
+  // as long as a '<' and his friend '>' are found, we loop
+  while ( ($start=strpos( $remaining, '<' )) !==false
+        and ($end=strpos( $remaining, '>' )) !== false )
+  {
+    // $treatment is the part of the string to treat
+    // In the first loop of our example, this variable is empty, but in the
+    // second loop, it equals 'My friend'
+    $treatment = substr ( $remaining, 0, $start );
+    // Replacement of ' ' by his equivalent '&nbsp;'
+    $treatment = str_replace( ' ', '&nbsp;', $treatment );
+    $treatment = str_replace( '-', '&minus;', $treatment );
+    // composing the string to return by adding the treated string and the
+    // following HTML tag -> 'My&nbsp;friend</div>'
+    $return_string.= $treatment.substr( $remaining, $start, $end-$start+1 );
+    // the remaining string is deplaced to the part after the '>' of this
+    // loop
+    $remaining = substr ( $remaining, $end + 1, strlen( $remaining ) );
+  }
+  $treatment = str_replace( ' ', '&nbsp;', $remaining );
+  $treatment = str_replace( '-', '&minus;', $treatment );
+  $return_string.= $treatment;
+
+  return $return_string;
+}
+
+// get_extension returns the part of the string after the last "."
+function get_extension( $filename )
+{
+  return substr( strrchr( $filename, '.' ), 1, strlen ( $filename ) );
+}
+
+// get_filename_wo_extension returns the part of the string before the last
+// ".".
+// get_filename_wo_extension( 'test.tar.gz' ) -> 'test.tar'
+function get_filename_wo_extension( $filename )
+{
+  $pos = strrpos( $filename, '.' );
+  return ($pos===false) ? $filename : substr( $filename, 0, $pos);
+}
+
+/**
+ * returns an array contening sub-directories, excluding ".svn"
+ *
+ * @param string $dir
+ * @return array
+ */
+function get_dirs($directory)
+{
+  $sub_dirs = array();
+  if ($opendir = opendir($directory))
+  {
+    while ($file = readdir($opendir))
+    {
+      if ($file != '.'
+          and $file != '..'
+          and is_dir($directory.'/'.$file)
+          and $file != '.svn')
+      {
+        array_push($sub_dirs, $file);
+      }
+    }
+    closedir($opendir);
+  }
+  return $sub_dirs;
+}
+
+define('MKGETDIR_NONE', 0);
+define('MKGETDIR_RECURSIVE', 1);
+define('MKGETDIR_DIE_ON_ERROR', 2);
+define('MKGETDIR_PROTECT_INDEX', 4);
+define('MKGETDIR_PROTECT_HTACCESS', 8);
+define('MKGETDIR_DEFAULT', 7);
+/**
+ * creates directory if not exists; ensures that directory is writable
+ * @param:
+ *  string $dir
+ *  int $flags combination of MKGETDIR_xxx
+ * @return bool false on error else true
+ */
+function mkgetdir($dir, $flags=MKGETDIR_DEFAULT)
+{
+  if ( !is_dir($dir) )
+  {
+    $umask = umask(0);
+    $mkd = @mkdir($dir, 0755, ($flags&MKGETDIR_RECURSIVE) ? true:false );
+    umask($umask);
+    if ($mkd==false)
+    {
+      !($flags&MKGETDIR_DIE_ON_ERROR) or fatal_error( "$dir ".l10n('no_write_access'));
+      return false;
+    }
+    if( $flags&MKGETDIR_PROTECT_HTACCESS )
+    {
+      $file = $dir.'/.htaccess';
+      file_exists($file) or @file_put_contents( $file, 'deny from all' );
+    }
+    if( $flags&MKGETDIR_PROTECT_INDEX )
+    {
+      $file = $dir.'/index.htm';
+      file_exists($file) or @file_put_contents( $file, 'Not allowed!' );
+    }
+  }
+  if ( !is_writable($dir) )
+  {
+    !($flags&MKGETDIR_DIE_ON_ERROR) or fatal_error( "$dir ".l10n('no_write_access'));
+    return false;
+  }
+  return true;
+}
+
+/**
+ * returns thumbnail directory name of input diretoty name
+ * make thumbnail directory is necessary
+ * set error messages on array messages
+ *
+ * @param:
+ *  string $dirname
+ *  arrayy $errors
+ * @return bool false on error else string directory name
+ */
+function mkget_thumbnail_dir($dirname, &$errors)
+{
+  $tndir = $dirname.'/thumbnail';
+  if (! mkgetdir($tndir, MKGETDIR_NONE) )
+  {
+    array_push($errors,
+          '['.$dirname.'] : '.l10n('no_write_access'));
+    return false;
+  }
+  return $tndir;
+}
+
+/* Returns true if the string appears to be encoded in UTF-8. (from wordpress)
+ * @param string Str
+ */
+function seems_utf8($Str) { # by bmorel at ssi dot fr
+  for ($i=0; $i<strlen($Str); $i++) {
+    if (ord($Str[$i]) < 0x80) continue; # 0bbbbbbb
+    elseif ((ord($Str[$i]) & 0xE0) == 0xC0) $n=1; # 110bbbbb
+    elseif ((ord($Str[$i]) & 0xF0) == 0xE0) $n=2; # 1110bbbb
+    elseif ((ord($Str[$i]) & 0xF8) == 0xF0) $n=3; # 11110bbb
+    elseif ((ord($Str[$i]) & 0xFC) == 0xF8) $n=4; # 111110bb
+    elseif ((ord($Str[$i]) & 0xFE) == 0xFC) $n=5; # 1111110b
+    else return false; # Does not match any model
+    for ($j=0; $j<$n; $j++) { # n bytes matching 10bbbbbb follow ?
+      if ((++$i == strlen($Str)) || ((ord($Str[$i]) & 0xC0) != 0x80))
+      return false;
+    }
+  }
+  return true;
+}
+
+/* Remove accents from a UTF-8 or ISO-859-1 string (from wordpress)
+ * @param string sstring - an UTF-8 or ISO-8859-1 string
+ */
+function remove_accents($string)
+{
+  if ( !preg_match('/[\x80-\xff]/', $string) )
+    return $string;
+
+  if (seems_utf8($string)) {
+    $chars = array(
+    // Decompositions for Latin-1 Supplement
+    chr(195).chr(128) => 'A', chr(195).chr(129) => 'A',
+    chr(195).chr(130) => 'A', chr(195).chr(131) => 'A',
+    chr(195).chr(132) => 'A', chr(195).chr(133) => 'A',
+    chr(195).chr(135) => 'C', chr(195).chr(136) => 'E',
+    chr(195).chr(137) => 'E', chr(195).chr(138) => 'E',
+    chr(195).chr(139) => 'E', chr(195).chr(140) => 'I',
+    chr(195).chr(141) => 'I', chr(195).chr(142) => 'I',
+    chr(195).chr(143) => 'I', chr(195).chr(145) => 'N',
+    chr(195).chr(146) => 'O', chr(195).chr(147) => 'O',
+    chr(195).chr(148) => 'O', chr(195).chr(149) => 'O',
+    chr(195).chr(150) => 'O', chr(195).chr(153) => 'U',
+    chr(195).chr(154) => 'U', chr(195).chr(155) => 'U',
+    chr(195).chr(156) => 'U', chr(195).chr(157) => 'Y',
+    chr(195).chr(159) => 's', chr(195).chr(160) => 'a',
+    chr(195).chr(161) => 'a', chr(195).chr(162) => 'a',
+    chr(195).chr(163) => 'a', chr(195).chr(164) => 'a',
+    chr(195).chr(165) => 'a', chr(195).chr(167) => 'c',
+    chr(195).chr(168) => 'e', chr(195).chr(169) => 'e',
+    chr(195).chr(170) => 'e', chr(195).chr(171) => 'e',
+    chr(195).chr(172) => 'i', chr(195).chr(173) => 'i',
+    chr(195).chr(174) => 'i', chr(195).chr(175) => 'i',
+    chr(195).chr(177) => 'n', chr(195).chr(178) => 'o',
+    chr(195).chr(179) => 'o', chr(195).chr(180) => 'o',
+    chr(195).chr(181) => 'o', chr(195).chr(182) => 'o',
+    chr(195).chr(182) => 'o', chr(195).chr(185) => 'u',
+    chr(195).chr(186) => 'u', chr(195).chr(187) => 'u',
+    chr(195).chr(188) => 'u', chr(195).chr(189) => 'y',
+    chr(195).chr(191) => 'y',
+    // Decompositions for Latin Extended-A
+    chr(196).chr(128) => 'A', chr(196).chr(129) => 'a',
+    chr(196).chr(130) => 'A', chr(196).chr(131) => 'a',
+    chr(196).chr(132) => 'A', chr(196).chr(133) => 'a',
+    chr(196).chr(134) => 'C', chr(196).chr(135) => 'c',
+    chr(196).chr(136) => 'C', chr(196).chr(137) => 'c',
+    chr(196).chr(138) => 'C', chr(196).chr(139) => 'c',
+    chr(196).chr(140) => 'C', chr(196).chr(141) => 'c',
+    chr(196).chr(142) => 'D', chr(196).chr(143) => 'd',
+    chr(196).chr(144) => 'D', chr(196).chr(145) => 'd',
+    chr(196).chr(146) => 'E', chr(196).chr(147) => 'e',
+    chr(196).chr(148) => 'E', chr(196).chr(149) => 'e',
+    chr(196).chr(150) => 'E', chr(196).chr(151) => 'e',
+    chr(196).chr(152) => 'E', chr(196).chr(153) => 'e',
+    chr(196).chr(154) => 'E', chr(196).chr(155) => 'e',
+    chr(196).chr(156) => 'G', chr(196).chr(157) => 'g',
+    chr(196).chr(158) => 'G', chr(196).chr(159) => 'g',
+    chr(196).chr(160) => 'G', chr(196).chr(161) => 'g',
+    chr(196).chr(162) => 'G', chr(196).chr(163) => 'g',
+    chr(196).chr(164) => 'H', chr(196).chr(165) => 'h',
+    chr(196).chr(166) => 'H', chr(196).chr(167) => 'h',
+    chr(196).chr(168) => 'I', chr(196).chr(169) => 'i',
+    chr(196).chr(170) => 'I', chr(196).chr(171) => 'i',
+    chr(196).chr(172) => 'I', chr(196).chr(173) => 'i',
+    chr(196).chr(174) => 'I', chr(196).chr(175) => 'i',
+    chr(196).chr(176) => 'I', chr(196).chr(177) => 'i',
+    chr(196).chr(178) => 'IJ',chr(196).chr(179) => 'ij',
+    chr(196).chr(180) => 'J', chr(196).chr(181) => 'j',
+    chr(196).chr(182) => 'K', chr(196).chr(183) => 'k',
+    chr(196).chr(184) => 'k', chr(196).chr(185) => 'L',
+    chr(196).chr(186) => 'l', chr(196).chr(187) => 'L',
+    chr(196).chr(188) => 'l', chr(196).chr(189) => 'L',
+    chr(196).chr(190) => 'l', chr(196).chr(191) => 'L',
+    chr(197).chr(128) => 'l', chr(197).chr(129) => 'L',
+    chr(197).chr(130) => 'l', chr(197).chr(131) => 'N',
+    chr(197).chr(132) => 'n', chr(197).chr(133) => 'N',
+    chr(197).chr(134) => 'n', chr(197).chr(135) => 'N',
+    chr(197).chr(136) => 'n', chr(197).chr(137) => 'N',
+    chr(197).chr(138) => 'n', chr(197).chr(139) => 'N',
+    chr(197).chr(140) => 'O', chr(197).chr(141) => 'o',
+    chr(197).chr(142) => 'O', chr(197).chr(143) => 'o',
+    chr(197).chr(144) => 'O', chr(197).chr(145) => 'o',
+    chr(197).chr(146) => 'OE',chr(197).chr(147) => 'oe',
+    chr(197).chr(148) => 'R',chr(197).chr(149) => 'r',
+    chr(197).chr(150) => 'R',chr(197).chr(151) => 'r',
+    chr(197).chr(152) => 'R',chr(197).chr(153) => 'r',
+    chr(197).chr(154) => 'S',chr(197).chr(155) => 's',
+    chr(197).chr(156) => 'S',chr(197).chr(157) => 's',
+    chr(197).chr(158) => 'S',chr(197).chr(159) => 's',
+    chr(197).chr(160) => 'S', chr(197).chr(161) => 's',
+    chr(197).chr(162) => 'T', chr(197).chr(163) => 't',
+    chr(197).chr(164) => 'T', chr(197).chr(165) => 't',
+    chr(197).chr(166) => 'T', chr(197).chr(167) => 't',
+    chr(197).chr(168) => 'U', chr(197).chr(169) => 'u',
+    chr(197).chr(170) => 'U', chr(197).chr(171) => 'u',
+    chr(197).chr(172) => 'U', chr(197).chr(173) => 'u',
+    chr(197).chr(174) => 'U', chr(197).chr(175) => 'u',
+    chr(197).chr(176) => 'U', chr(197).chr(177) => 'u',
+    chr(197).chr(178) => 'U', chr(197).chr(179) => 'u',
+    chr(197).chr(180) => 'W', chr(197).chr(181) => 'w',
+    chr(197).chr(182) => 'Y', chr(197).chr(183) => 'y',
+    chr(197).chr(184) => 'Y', chr(197).chr(185) => 'Z',
+    chr(197).chr(186) => 'z', chr(197).chr(187) => 'Z',
+    chr(197).chr(188) => 'z', chr(197).chr(189) => 'Z',
+    chr(197).chr(190) => 'z', chr(197).chr(191) => 's',
+    // Euro Sign
+    chr(226).chr(130).chr(172) => 'E',
+    // GBP (Pound) Sign
+    chr(194).chr(163) => '');
+
+    $string = strtr($string, $chars);
+  } else {
+    // Assume ISO-8859-1 if not UTF-8
+    $chars['in'] = chr(128).chr(131).chr(138).chr(142).chr(154).chr(158)
+      .chr(159).chr(162).chr(165).chr(181).chr(192).chr(193).chr(194)
+      .chr(195).chr(196).chr(197).chr(199).chr(200).chr(201).chr(202)
+      .chr(203).chr(204).chr(205).chr(206).chr(207).chr(209).chr(210)
+      .chr(211).chr(212).chr(213).chr(214).chr(216).chr(217).chr(218)
+      .chr(219).chr(220).chr(221).chr(224).chr(225).chr(226).chr(227)
+      .chr(228).chr(229).chr(231).chr(232).chr(233).chr(234).chr(235)
+      .chr(236).chr(237).chr(238).chr(239).chr(241).chr(242).chr(243)
+      .chr(244).chr(245).chr(246).chr(248).chr(249).chr(250).chr(251)
+      .chr(252).chr(253).chr(255);
+
+    $chars['out'] = "EfSZszYcYuAAAAAACEEEEIIIINOOOOOOUUUUYaaaaaaceeeeiiiinoooooouuuuyy";
+
+    $string = strtr($string, $chars['in'], $chars['out']);
+    $double_chars['in'] = array(chr(140), chr(156), chr(198), chr(208), chr(222), chr(223), chr(230), chr(240), chr(254));
+    $double_chars['out'] = array('OE', 'oe', 'AE', 'DH', 'TH', 'ss', 'ae', 'dh', 'th');
+    $string = str_replace($double_chars['in'], $double_chars['out'], $string);
+  }
+
+  return $string;
+}
+
+/**
+ * simplify a string to insert it into an URL
+ *
+ * @param string
+ * @return string
+ */
+function str2url($str)
+{
+  $str = remove_accents($str);
+  $str = preg_replace('/[^a-z0-9_\s\'\:\/\[\],-]/','',strtolower($str));
+  $str = preg_replace('/[\s\'\:\/\[\],-]+/',' ',trim($str));
+  $res = str_replace(' ','_',$str);
+
+  return $res;
+}
+
+//-------------------------------------------- Piwigo specific functions
+
+/**
+ * returns an array with a list of {language_code => language_name}
+ *
+ * @returns array
+ */
+function get_languages($target_charset = null)
+{
+  if ( empty($target_charset) )
+  {
+    $target_charset = get_pwg_charset();
+  }
+  $target_charset = strtolower($target_charset);
+
+  $dir = opendir(PHPWG_ROOT_PATH.'language');
+  $languages = array();
+
+  while ($file = readdir($dir))
+  {
+    $path = PHPWG_ROOT_PATH.'language/'.$file;
+    if (!is_link($path) and file_exists($path.'/iso.txt'))
+    {
+      list($language_name) = @file($path.'/iso.txt');
+
+      $langdef = explode('.',$file);
+      if (count($langdef)>1) // (langCode,encoding)
+      {
+        $langdef[1] = strtolower($langdef[1]);
+
+        if (
+          $target_charset==$langdef[1]
+         or
+          ($target_charset=='utf-8' and $langdef[1]=='iso-8859-1')
+         or
+          ($target_charset=='iso-8859-1' and
+          in_array( substr($langdef[0],2), array('en','fr','de','es','it','nl')))
+        )
+        {
+          $language_name = convert_charset($language_name,
+              $langdef[1], $target_charset);
+          $languages[ $langdef[0] ] = $language_name;
+        }
+        else
+          continue; // the language encoding is not compatible with our charset
+      }
+      else
+      { // UTF-8
+        $language_name = convert_charset($language_name,
+              'utf-8', $target_charset);
+        $languages[$file] = $language_name;
+      }
+    }
+  }
+  closedir($dir);
+  @asort($languages);
+
+  return $languages;
+}
+
+function pwg_log($image_id = null, $image_type = null)
+{
+  global $conf, $user, $page;
+
+  $do_log = $conf['log'];
+  if (is_admin())
+  {
+    $do_log = $conf['history_admin'];
+  }
+  if (is_a_guest())
+  {
+    $do_log = $conf['history_guest'];
+  }
+
+  $do_log = trigger_event('pwg_log_allowed', $do_log, $image_id, $image_type);
+
+  if (!$do_log)
+  {
+    return false;
+  }
+
+  $tags_string = null;
+  if ('tags'==@$page['section'])
+  {
+    $tags_string = implode(',', $page['tag_ids']);
+  }
+
+  $query = '
+INSERT INTO '.HISTORY_TABLE.'
+  (
+    date,
+    time,
+    user_id,
+    IP,
+    section,
+    category_id,
+    image_id,
+    image_type,
+    tag_ids
+  )
+  VALUES
+  (
+    CURDATE(),
+    CURTIME(),
+    '.$user['id'].',
+    \''.$_SERVER['REMOTE_ADDR'].'\',
+    '.(isset($page['section']) ? "'".$page['section']."'" : 'NULL').',
+    '.(isset($page['category']['id']) ? $page['category']['id'] : 'NULL').',
+    '.(isset($image_id) ? $image_id : 'NULL').',
+    '.(isset($image_type) ? "'".$image_type."'" : 'NULL').',
+    '.(isset($tags_string) ? "'".$tags_string."'" : 'NULL').'
+  )
+;';
+  pwg_query($query);
+
+  return true;
+}
+
+// format_date returns a formatted date for display. The date given in
+// argument must be an american format (2003-09-15). By option, you can show the time.
+// The output is internationalized.
+//
+// format_date( "2003-09-15", true ) -> "Monday 15 September 2003 21:52"
+function format_date($date, $show_time = false)
+{
+  global $lang;
+
+  $ymdhms = array();
+  $tok = strtok( $date, '- :');
+  while ($tok !== false)
+  {
+    $ymdhms[] = $tok;
+    $tok = strtok('- :');
+  }
+
+  if ( count($ymdhms)<3 )
+  {
+    return false;
+  }
+
+  $formated_date = '';
+  // before 1970, Microsoft Windows can't mktime
+  if ($ymdhms[0] >= 1970)
+  {
+    // we ask midday because Windows think it's prior to midnight with a
+    // zero and refuse to work
+    $formated_date.= $lang['day'][date('w', mktime(12,0,0,$ymdhms[1],$ymdhms[2],$ymdhms[0]))];
+  }
+  $formated_date.= ' '.$ymdhms[2];
+  $formated_date.= ' '.$lang['month'][(int)$ymdhms[1]];
+  $formated_date.= ' '.$ymdhms[0];
+  if ($show_time and count($ymdhms)>=5 )
+  {
+    $formated_date.= ' '.$ymdhms[3].':'.$ymdhms[4];
+  }
+  return $formated_date;
+}
+
+function pwg_query($query)
+{
+  global $conf,$page,$debug,$t2;
+
+  $start = get_moment();
+  ($result = mysql_query($query)) or my_error($query, $conf['die_on_sql_error']);
+
+  $time = get_moment() - $start;
+
+  if (!isset($page['count_queries']))
+  {
+    $page['count_queries'] = 0;
+    $page['queries_time'] = 0;
+  }
+
+  $page['count_queries']++;
+  $page['queries_time']+= $time;
+
+  if ($conf['show_queries'])
+  {
+    $output = '';
+    $output.= '<pre>['.$page['count_queries'].'] ';
+    $output.= "\n".$query;
+    $output.= "\n".'(this query time : ';
+    $output.= '<b>'.number_format($time, 3, '.', ' ').' s)</b>';
+    $output.= "\n".'(total SQL time  : ';
+    $output.= number_format($page['queries_time'], 3, '.', ' ').' s)';
+    $output.= "\n".'(total time      : ';
+    $output.= number_format( ($time+$start-$t2), 3, '.', ' ').' s)';
+    if ( $result!=null and preg_match('/\s*SELECT\s+/i',$query) )
+    {
+      $output.= "\n".'(num rows        : ';
+      $output.= mysql_num_rows($result).' )';
+    }
+    elseif ( $result!=null
+      and preg_match('/\s*INSERT|UPDATE|REPLACE|DELETE\s+/i',$query) )
+    {
+      $output.= "\n".'(affected rows   : ';
+      $output.= mysql_affected_rows().' )';
+    }
+    $output.= "</pre>\n";
+
+    $debug .= $output;
+  }
+
+  return $result;
+}
+
+function pwg_debug( $string )
+{
+  global $debug,$t2,$page;
+
+  $now = explode( ' ', microtime() );
+  $now2 = explode( '.', $now[0] );
+  $now2 = $now[1].'.'.$now2[1];
+  $time = number_format( $now2 - $t2, 3, '.', ' ').' s';
+  $debug .= '<p>';
+  $debug.= '['.$time.', ';
+  $debug.= $page['count_queries'].' queries] : '.$string;
+  $debug.= "</p>\n";
+}
+
+/**
+ * Redirects to the given URL (HTTP method)
+ *
+ * Note : once this function called, the execution doesn't go further
+ * (presence of an exit() instruction.
+ *
+ * @param string $url
+ * @return void
+ */
+function redirect_http( $url )
+{
+  if (ob_get_length () !== FALSE)
+  {
+    ob_clean();
+  }
+  // default url is on html format
+  $url = html_entity_decode($url);
+  header('Request-URI: '.$url);
+  header('Content-Location: '.$url);
+  header('Location: '.$url);
+  exit();
+}
+
+/**
+ * Redirects to the given URL (HTML method)
+ *
+ * Note : once this function called, the execution doesn't go further
+ * (presence of an exit() instruction.
+ *
+ * @param string $url
+ * @param string $title_msg
+ * @param integer $refreh_time
+ * @return void
+ */
+function redirect_html( $url , $msg = '', $refresh_time = 0)
+{
+  global $user, $template, $lang_info, $conf, $lang, $t2, $page, $debug;
+
+  if (!isset($lang_info))
+  {
+    $user = build_user( $conf['guest_id'], true);
+    load_language('common.lang');
+    trigger_action('loading_lang');
+    load_language('local.lang', '', array('no_fallback'=>true) );
+    list($tmpl, $thm) = explode('/', get_default_template());
+    $template = new Template(PHPWG_ROOT_PATH.'template/'.$tmpl, $thm);
+  }
+  else
+  {
+    $template = new Template(PHPWG_ROOT_PATH.'template/'.$user['template'], $user['theme']);
+  }
+
+  if (empty($msg))
+  {
+    $msg = nl2br(l10n('redirect_msg'));
+  }
+
+  $refresh = $refresh_time;
+  $url_link = $url;
+  $title = 'redirection';
+
+  $template->set_filenames( array( 'redirect' => 'redirect.tpl' ) );
+
+  include( PHPWG_ROOT_PATH.'include/page_header.php' );
+
+  $template->set_filenames( array( 'redirect' => 'redirect.tpl' ) );
+  $template->assign('REDIRECT_MSG', $msg);
+
+  $template->parse('redirect');
+
+  include( PHPWG_ROOT_PATH.'include/page_tail.php' );
+
+  exit();
+}
+
+/**
+ * Redirects to the given URL (Switch to HTTP method or HTML method)
+ *
+ * Note : once this function called, the execution doesn't go further
+ * (presence of an exit() instruction.
+ *
+ * @param string $url
+ * @param string $title_msg
+ * @param integer $refreh_time
+ * @return void
+ */
+function redirect( $url , $msg = '', $refresh_time = 0)
+{
+  global $conf;
+
+  // with RefeshTime <> 0, only html must be used
+  if ($conf['default_redirect_method']=='http'
+      and $refresh_time==0
+      and !headers_sent()
+    )
+  {
+    redirect_http($url);
+  }
+  else
+  {
+    redirect_html($url, $msg, $refresh_time);
+  }
+}
+
+/**
+ * returns $_SERVER['QUERY_STRING'] whitout keys given in parameters
+ *
+ * @param array $rejects
+ * @param boolean $escape - if true escape & to &amp; (for html)
+ * @returns string
+ */
+function get_query_string_diff($rejects=array(), $escape=true)
+{
+  $query_string = '';
+
+  $str = $_SERVER['QUERY_STRING'];
+  parse_str($str, $vars);
+
+  $is_first = true;
+  foreach ($vars as $key => $value)
+  {
+    if (!in_array($key, $rejects))
+    {
+      $query_string.= $is_first ? '?' : ($escape ? '&amp;' : '&' );
+      $is_first = false;
+      $query_string.= $key.'='.$value;
+    }
+  }
+
+  return $query_string;
+}
+
+function url_is_remote($url)
+{
+  if ( strncmp($url, 'http://', 7)==0
+    or strncmp($url, 'https://', 8)==0 )
+  {
+    return true;
+  }
+  return false;
+}
+
+/**
+ * returns available template/theme
+ */
+function get_pwg_themes()
+{
+  global $conf;
+  $themes = array();
+
+  $template_dir = PHPWG_ROOT_PATH.'template';
+
+  foreach (get_dirs($template_dir) as $template)
+  {
+    foreach (get_dirs($template_dir.'/'.$template.'/theme') as $theme)
+    {
+      if ( ($template.'/'.$theme) != $conf['admin_layout'] )
+      array_push($themes, $template.'/'.$theme);
+    }
+  }
+
+  return $themes;
+}
+
+/* Returns the PATH to the thumbnail to be displayed. If the element does not
+ * have a thumbnail, the default mime image path is returned. The PATH can be
+ * used in the php script, but not sent to the browser.
+ * @param array element_info assoc array containing element info from db
+ * at least 'path', 'tn_ext' and 'id' should be present
+ */
+function get_thumbnail_path($element_info)
+{
+  $path = get_thumbnail_location($element_info);
+  if ( !url_is_remote($path) )
+  {
+    $path = PHPWG_ROOT_PATH.$path;
+  }
+  return $path;
+}
+
+/* Returns the URL of the thumbnail to be displayed. If the element does not
+ * have a thumbnail, the default mime image url is returned. The URL can be
+ * sent to the browser, but not used in the php script.
+ * @param array element_info assoc array containing element info from db
+ * at least 'path', 'tn_ext' and 'id' should be present
+ */
+function get_thumbnail_url($element_info)
+{
+  $path = get_thumbnail_location($element_info);
+  if ( !url_is_remote($path) )
+  {
+    $path = embellish_url(get_root_url().$path);
+  }
+
+  // plugins want another url ?
+  $path = trigger_event('get_thumbnail_url', $path, $element_info);
+  return $path;
+}
+
+/* returns the relative path of the thumnail with regards to to the root
+of piwigo (not the current page!).This function is not intended to be
+called directly from code.*/
+function get_thumbnail_location($element_info)
+{
+  global $conf;
+  if ( !empty( $element_info['tn_ext'] ) )
+  {
+    $path = substr_replace(
+      get_filename_wo_extension($element_info['path']),
+      '/thumbnail/'.$conf['prefix_thumbnail'],
+      strrpos($element_info['path'],'/'),
+      1
+      );
+    $path.= '.'.$element_info['tn_ext'];
+  }
+  else
+  {
+    $path = get_themeconf('mime_icon_dir')
+        .strtolower(get_extension($element_info['path'])).'.png';
+  }
+
+  // plugins want another location ?
+  $path = trigger_event( 'get_thumbnail_location', $path, $element_info);
+  return $path;
+}
+
+/* returns the title of the thumnail */
+function get_thumbnail_title($element_info)
+{
+  // message in title for the thumbnail
+  if (isset($element_info['file']))
+  {
+    $thumbnail_title = $element_info['file'];
+  }
+  else
+  {
+    $thumbnail_title = '';
+  }
+
+  if (!empty($element_info['filesize']))
+  {
+    $thumbnail_title .= ' : '.sprintf(l10n('%d Kb'), $element_info['filesize']);
+  }
+
+  return $thumbnail_title;
+}
+
+// my_error returns (or send to standard output) the message concerning the
+// error occured for the last mysql query.
+function my_error($header, $die)
+{
+  $error = "[mysql error ".mysql_errno().'] '.mysql_error()."\n";
+  $error .= $header;
+
+  if ($die)
+  {
+    fatal_error($error);
+  }
+  echo("<pre>");
+  trigger_error($error, E_USER_WARNING);
+  echo("</pre>");
+}
+
+
+/**
+ * creates an array based on a query, this function is a very common pattern
+ * used here
+ *
+ * @param string $query
+ * @param string $fieldname
+ * @return array
+ */
+function array_from_query($query, $fieldname)
+{
+  $array = array();
+
+  $result = pwg_query($query);
+  while ($row = mysql_fetch_array($result))
+  {
+    array_push($array, $row[$fieldname]);
+  }
+
+  return $array;
+}
+
+/**
+ * fill the current user caddie with given elements, if not already in
+ * caddie
+ *
+ * @param array elements_id
+ */
+function fill_caddie($elements_id)
+{
+  global $user;
+
+  include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+
+  $query = '
+SELECT element_id
+  FROM '.CADDIE_TABLE.'
+  WHERE user_id = '.$user['id'].'
+;';
+  $in_caddie = array_from_query($query, 'element_id');
+
+  $caddiables = array_diff($elements_id, $in_caddie);
+
+  $datas = array();
+
+  foreach ($caddiables as $caddiable)
+  {
+    array_push($datas, array('element_id' => $caddiable,
+                             'user_id' => $user['id']));
+  }
+
+  if (count($caddiables) > 0)
+  {
+    mass_inserts(CADDIE_TABLE, array('element_id','user_id'), $datas);
+  }
+}
+
+/**
+ * returns the element name from its filename
+ *
+ * @param string filename
+ * @return string name
+ */
+function get_name_from_file($filename)
+{
+  return str_replace('_',' ',get_filename_wo_extension($filename));
+}
+
+/**
+ * returns the corresponding value from $lang if existing. Else, the key is
+ * returned
+ *
+ * @param string key
+ * @return string
+ */
+function l10n($key)
+{
+  global $lang, $conf;
+
+  if ($conf['debug_l10n'] and !isset($lang[$key]) and !empty($key))
+  {
+    trigger_error('[l10n] language key "'.$key.'" is not defined', E_USER_WARNING);
+  }
+
+  return isset($lang[$key]) ? $lang[$key] : $key;
+}
+
+/**
+ * returns the prinft value for strings including %d
+ * return is concorded with decimal value (singular, plural)
+ *
+ * @param singular string key
+ * @param plural string key
+ * @param decimal value
+ * @return string
+ */
+function l10n_dec($singular_fmt_key, $plural_fmt_key, $decimal)
+{
+  global $lang_info;
+
+  return
+    sprintf(
+      l10n((
+        (($decimal > 1) or ($decimal == 0 and $lang_info['zero_plural']))
+          ? $plural_fmt_key
+          : $singular_fmt_key
+        )), $decimal);
+}
+/*
+ * returns a single element to use with l10n_args
+ *
+ * @param string key: translation key
+ * @param array/string/../number args:
+ *   arguments to use on sprintf($key, args)
+ *   if args is a array, each values are used on sprintf
+ * @return string
+ */
+function get_l10n_args($key, $args)
+{
+  if (is_array($args))
+  {
+    $key_arg = array_merge(array($key), $args);
+  }
+  else
+  {
+    $key_arg = array($key,  $args);
+  }
+  return array('key_args' => $key_arg);
+}
+
+/*
+ * returns a string with formated with l10n_args elements
+ *
+ * @param element/array $key_args: element or array of l10n_args elements
+ * @param $sep: if $key_args is array,
+ *   separator is used when translated l10n_args elements are concated
+ * @return string
+ */
+function l10n_args($key_args, $sep = "\n")
+{
+  if (is_array($key_args))
+  {
+    foreach ($key_args as $key => $element)
+    {
+      if (isset($result))
+      {
+        $result .= $sep;
+      }
+      else
+      {
+        $result = '';
+      }
+
+      if ($key === 'key_args')
+      {
+        array_unshift($element, l10n(array_shift($element)));
+        $result .= call_user_func_array('sprintf', $element);
+      }
+      else
+      {
+        $result .= l10n_args($element, $sep);
+      }
+    }
+  }
+  else
+  {
+    fatal_error('l10n_args: Invalid arguments');
+  }
+
+  return $result;
+}
+
+/**
+ * returns the corresponding value from $themeconf if existing. Else, the
+ * key is returned
+ *
+ * @param string key
+ * @return string
+ */
+function get_themeconf($key)
+{
+  global $template;
+
+  return $template->get_themeconf($key);
+}
+
+/**
+ * Returns webmaster mail address depending on $conf['webmaster_id']
+ *
+ * @return string
+ */
+function get_webmaster_mail_address()
+{
+  global $conf;
+
+  $query = '
+SELECT '.$conf['user_fields']['email'].'
+  FROM '.USERS_TABLE.'
+  WHERE '.$conf['user_fields']['id'].' = '.$conf['webmaster_id'].'
+;';
+  list($email) = mysql_fetch_array(pwg_query($query));
+
+  return $email;
+}
+
+/**
+ * Add configuration parameters from database to global $conf array
+ *
+ * @return void
+ */
+function load_conf_from_db($condition = '')
+{
+  global $conf;
+
+  $query = '
+SELECT param, value
+ FROM '.CONFIG_TABLE.'
+ '.(!empty($condition) ? 'WHERE '.$condition : '').'
+;';
+  $result = pwg_query($query);
+
+  if ((mysql_num_rows($result) == 0) and !empty($condition))
+  {
+    fatal_error('No configuration data');
+  }
+
+  while ($row = mysql_fetch_array($result))
+  {
+    $conf[ $row['param'] ] = isset($row['value']) ? $row['value'] : '';
+
+    // If the field is true or false, the variable is transformed into a
+    // boolean value.
+    if ($conf[$row['param']] == 'true' or $conf[$row['param']] == 'false')
+    {
+      $conf[ $row['param'] ] = get_boolean($conf[ $row['param'] ]);
+    }
+  }
+}
+
+/**
+ * Prepends and appends a string at each value of the given array.
+ *
+ * @param array
+ * @param string prefix to each array values
+ * @param string suffix to each array values
+ */
+function prepend_append_array_items($array, $prepend_str, $append_str)
+{
+  array_walk(
+    $array,
+    create_function('&$s', '$s = "'.$prepend_str.'".$s."'.$append_str.'";')
+    );
+
+  return $array;
+}
+
+/**
+ * creates an hashed based on a query, this function is a very common
+ * pattern used here. Among the selected columns fetched, choose one to be
+ * the key, another one to be the value.
+ *
+ * @param string $query
+ * @param string $keyname
+ * @param string $valuename
+ * @return array
+ */
+function simple_hash_from_query($query, $keyname, $valuename)
+{
+  $array = array();
+
+  $result = pwg_query($query);
+  while ($row = mysql_fetch_array($result))
+  {
+    $array[ $row[$keyname] ] = $row[$valuename];
+  }
+
+  return $array;
+}
+
+/**
+ * creates an hashed based on a query, this function is a very common
+ * pattern used here. The key is given as parameter, the value is an associative
+ * array.
+ *
+ * @param string $query
+ * @param string $keyname
+ * @return array
+ */
+function hash_from_query($query, $keyname)
+{
+  $array = array();
+  $result = pwg_query($query);
+  while ($row = mysql_fetch_assoc($result))
+  {
+    $array[ $row[$keyname] ] = $row;
+  }
+  return $array;
+}
+
+/**
+ * Return basename of the current script
+ * Lower case convertion is applied on return value
+ * Return value is without file extention ".php"
+ *
+ * @param void
+ *
+ * @return script basename
+ */
+function script_basename()
+{
+  global $conf;
+
+  foreach (array('SCRIPT_NAME', 'SCRIPT_FILENAME', 'PHP_SELF') as $value)
+  {
+    if (!empty($_SERVER[$value]))
+    {
+      $filename = strtolower($_SERVER[$value]);
+      if ($conf['php_extension_in_urls'] and get_extension($filename)!=='php')
+        continue;
+      $basename = basename($filename, '.php');
+      if (!empty($basename))
+      {
+        return $basename;
+      }
+    }
+  }
+  return '';
+}
+
+/**
+ * Return value for the current page define on $conf['filter_pages']
+ * Îf value is not defined, default value are returned
+ *
+ * @param value name
+ *
+ * @return filter page value
+ */
+function get_filter_page_value($value_name)
+{
+  global $conf;
+
+  $page_name = script_basename();
+
+  if (isset($conf['filter_pages'][$page_name][$value_name]))
+  {
+    return $conf['filter_pages'][$page_name][$value_name];
+  }
+  else if (isset($conf['filter_pages']['default'][$value_name]))
+  {
+    return $conf['filter_pages']['default'][$value_name];
+  }
+  else
+  {
+    return null;
+  }
+}
+
+/**
+ * returns the character set of data sent to browsers / received from forms
+ */
+function get_pwg_charset()
+{
+  defined('PWG_CHARSET') or fatal_error('PWG_CHARSET undefined');
+  return PWG_CHARSET;
+}
+
+/**
+ * includes a language file or returns the content of a language file
+ * availability of the file
+ *
+ * in descending order of preference:
+ *   param language, user language, default language
+ * Piwigo default language.
+ *
+ * @param string filename
+ * @param string dirname
+ * @param mixed options can contain
+ *     language - language to load (if empty uses user language)
+ *     return - if true the file content is returned otherwise the file is evaluated as php
+ *     target_charset -
+ *     no_fallback - the language must be respected
+ * @return boolean success status or a string if options['return'] is true
+ */
+function load_language($filename, $dirname = '',
+    $options = array() )
+{
+  global $user;
+
+  if (! @$options['return'] )
+  {
+    $filename .= '.php'; //MAYBE to do .. load .po and .mo localization files
+  }
+  if (empty($dirname))
+  {
+    $dirname = PHPWG_ROOT_PATH;
+  }
+  $dirname .= 'language/';
+
+  $languages = array();
+  if ( !empty($options['language']) )
+  {
+    $languages[] = $options['language'];
+  }
+  if ( !empty($user['language']) )
+  {
+    $languages[] = $user['language'];
+  }
+  if ( ! @$options['no_fallback'] )
+  {
+    if ( defined('PHPWG_INSTALLED') )
+    {
+      $languages[] = get_default_language();
+    }
+    $languages[] = PHPWG_DEFAULT_LANGUAGE;
+  }
+
+  $languages = array_unique($languages);
+
+  if ( empty($options['target_charset']) )
+  {
+    $target_charset = get_pwg_charset();
+  }
+  else
+  {
+    $target_charset = $options['target_charset'];
+  }
+  $target_charset = strtolower($target_charset);
+  $source_charset = '';
+  $source_file    = '';
+  foreach ($languages as $language)
+  {
+    $dir = $dirname.$language;
+
+    if ($target_charset!='utf-8')
+    {
+      // exact charset match - no conversion required
+      $f = $dir.'.'.$target_charset.'/'.$filename;
+      if (file_exists($f))
+      {
+        $source_file = $f;
+        break;
+      }
+    }
+
+    // UTF-8 ?
+    $f = $dir.'/'.$filename;
+    if (file_exists($f))
+    {
+      $source_charset = 'utf-8';
+      $source_file = $f;
+      break;
+    }
+  }
+
+  if ( !empty($source_file) )
+  {
+    if (! @$options['return'] )
+    {
+      @include($source_file);
+      $load_lang = @$lang;
+      $load_lang_info = @$lang_info;
+
+      global $lang, $lang_info;
+      if ( !isset($lang) ) $lang=array();
+      if ( !isset($lang_info) ) $lang_info=array();
+
+      if ( !empty($source_charset) and $source_charset!=$target_charset)
+      {
+        if ( is_array($load_lang) )
+        {
+          foreach ($load_lang as $k => $v)
+          {
+            if ( is_array($v) )
+            {
+              $func = create_function('$v', 'return convert_charset($v, "'.$source_charset.'","'.$target_charset.'");' );
+              $lang[$k] = array_map($func, $v);
+            }
+            else
+              $lang[$k] = convert_charset($v, $source_charset, $target_charset);
+          }
+        }
+        if ( is_array($load_lang_info) )
+        {
+          foreach ($load_lang_info as $k => $v)
+          {
+            $lang_info[$k] = convert_charset($v, $source_charset, $target_charset);
+          }
+        }
+      }
+      else
+      {
+        $lang = array_merge( $lang, (array)$load_lang );
+        $lang_info = array_merge( $lang_info, (array)$load_lang_info );
+      }
+      return true;
+    }
+    else
+    {
+      $content = @file_get_contents($source_file);
+      if ( !empty($source_charset) and $source_charset!=$target_charset)
+      {
+        $content = convert_charset($content, $source_charset, $target_charset);
+      }
+      return $content;
+    }
+  }
+  return false;
+}
+
+/**
+ * converts a string from a character set to another character set
+ * @param string str the string to be converted
+ * @param string source_charset the character set in which the string is encoded
+ * @param string dest_charset the destination character set
+ */
+function convert_charset($str, $source_charset, $dest_charset)
+{
+  if ($source_charset==$dest_charset)
+    return $str;
+  if ($source_charset=='iso-8859-1' and $dest_charset=='utf-8')
+  {
+    return utf8_encode($str);
+  }
+  if ($source_charset=='utf-8' and $dest_charset=='iso-8859-1')
+  {
+    return utf8_decode($str);
+  }
+  if (function_exists('iconv'))
+  {
+    return iconv($source_charset, $dest_charset, $str);
+  }
+  if (function_exists('mb_convert_encoding'))
+  {
+    return mb_convert_encoding( $str, $dest_charset, $source_charset );
+  }
+  return $str; //???
+}
+
+/**
+ * makes sure a index.htm protects the directory from browser file listing
+ *
+ * @param string dir directory
+ */
+function secure_directory($dir)
+{
+  $file = $dir.'/index.htm';
+  if (!file_exists($file))
+  {
+    @file_put_contents($file, 'Not allowed!');
+  }
+}
+
+/**
+ * returns a "secret key" that is to be sent back when a user enters a comment
+ *
+ * @param int image_id
+ */
+function get_comment_post_key($image_id)
+{
+  global $conf;
+
+  $time = time();
+
+  return sprintf(
+    '%s:%s',
+    $time,
+    hash_hmac(
+      'md5',
+      $time.':'.$image_id,
+      $conf['secret_key']
+      )
+    );
+}
+?>
Index: /tags/2.0.2/include/functions_calendar.inc.php
===================================================================
--- /tags/2.0.2/include/functions_calendar.inc.php	(revision 3278)
+++ /tags/2.0.2/include/functions_calendar.inc.php	(revision 3278)
@@ -0,0 +1,292 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+define('CAL_VIEW_LIST',     'list');
+define('CAL_VIEW_CALENDAR', 'calendar');
+
+function initialize_calendar()
+{
+  global $page, $conf, $user, $template, $filter;
+
+//------------------ initialize the condition on items to take into account ---
+  $inner_sql = ' FROM ' . IMAGES_TABLE;
+
+  if ($page['section']=='categories')
+  { // we will regenerate the items by including subcats elements
+    $page['items'] = array();
+    $inner_sql .= '
+INNER JOIN '.IMAGE_CATEGORY_TABLE.' ON id = image_id';
+
+    if ( isset($page['category']) )
+    {
+      $sub_ids = array_diff(
+        get_subcat_ids(array($page['category']['id'])),
+        explode(',', $user['forbidden_categories'])
+        );
+
+      if (empty($sub_ids))
+      {
+        return; // nothing to do
+      }
+      $inner_sql .= '
+WHERE category_id IN ('.implode(',',$sub_ids).')';
+      $inner_sql .= '
+    '.get_sql_condition_FandF
+      (
+        array
+          (
+            'visible_images' => 'id'
+          ),
+        'AND', false
+      );
+    }
+    else
+    {
+      $inner_sql .= '
+    '.get_sql_condition_FandF
+      (
+        array
+          (
+            'forbidden_categories' => 'category_id',
+            'visible_categories' => 'category_id',
+            'visible_images' => 'id'
+          ),
+        'WHERE', true
+      );
+    }
+  }
+  else
+  {
+    if ( empty($page['items']) )
+    {
+      return; // nothing to do
+    }
+    $inner_sql .= '
+WHERE id IN (' . implode(',',$page['items']) .')';
+  }
+
+//-------------------------------------- initialize the calendar parameters ---
+  pwg_debug('start initialize_calendar');
+
+  $fields = array(
+    // Created
+    'created' => array(
+      'label'          => l10n('Creation date'),
+      ),
+    // Posted
+    'posted' => array(
+      'label'          => l10n('Post date'),
+      ),
+    );
+
+  $styles = array(
+    // Monthly style
+    'monthly' => array(
+      'include'        => 'calendar_monthly.class.php',
+      'view_calendar'  => true,
+      ),
+    // Weekly style
+    'weekly' => array(
+      'include'        => 'calendar_weekly.class.php',
+      'view_calendar'  => false,
+      ),
+    );
+
+  $views = array(CAL_VIEW_LIST,CAL_VIEW_CALENDAR);
+
+  // Retrieve calendar field
+  isset( $fields[ $page['chronology_field'] ] ) or fatal_error('bad chronology field');
+
+  // Retrieve style
+  if ( !isset( $styles[ $page['chronology_style'] ] ) )
+  {
+    $page['chronology_style'] = 'monthly';
+  }
+  $cal_style = $page['chronology_style'];
+  include(PHPWG_ROOT_PATH.'include/'. $styles[$cal_style]['include']);
+  $calendar = new Calendar();
+
+  // Retrieve view
+
+  if ( !isset($page['chronology_view']) or
+       !in_array( $page['chronology_view'], $views ) )
+  {
+    $page['chronology_view'] = CAL_VIEW_LIST;
+  }
+
+  if ( CAL_VIEW_CALENDAR==$page['chronology_view'] and
+        !$styles[$cal_style]['view_calendar'] )
+  {
+
+    $page['chronology_view'] = CAL_VIEW_LIST;
+  }
+
+  // perform a sanity check on $requested
+  if (!isset($page['chronology_date']))
+  {
+    $page['chronology_date'] = array();
+  }
+  while ( count($page['chronology_date']) > 3)
+  {
+    array_pop($page['chronology_date']);
+  }
+
+  $any_count = 0;
+  for ($i = 0; $i < count($page['chronology_date']); $i++)
+  {
+    if ($page['chronology_date'][$i] == 'any')
+    {
+      if ($page['chronology_view'] == CAL_VIEW_CALENDAR)
+      {// we dont allow any in calendar view
+        while ($i < count($page['chronology_date']))
+        {
+          array_pop($page['chronology_date']);
+        }
+        break;
+      }
+      $any_count++;
+    }
+    elseif ($page['chronology_date'][$i] == '')
+    {
+      while ($i < count($page['chronology_date']))
+      {
+        array_pop($page['chronology_date']);
+      }
+    }
+    else
+    {
+      $page['chronology_date'][$i] = (int)$page['chronology_date'][$i];
+    }
+  }
+  if ($any_count == 3)
+  {
+    array_pop($page['chronology_date']);
+  }
+
+  $calendar->initialize($inner_sql);
+
+  //echo ('<pre>'. var_export($calendar, true) . '</pre>');
+
+  $must_show_list = true; // true until calendar generates its own display
+  if (script_basename() != 'picture') // basename without file extention
+  {
+    if ($calendar->generate_category_content())
+    {
+      $page['items'] = array();
+      $must_show_list = false;
+    }
+
+    $page['comment'] = '';
+    $template->assign('FILE_CHRONOLOGY_VIEW', 'month_calendar.tpl');
+
+    foreach ($styles as $style => $style_data)
+    {
+      foreach ($views as $view)
+      {
+        if ( $style_data['view_calendar'] or $view != CAL_VIEW_CALENDAR)
+        {
+          $selected = false;
+
+          if ($style!=$cal_style)
+          {
+            $chronology_date = array();
+            if ( isset($page['chronology_date'][0]) )
+            {
+              array_push($chronology_date, $page['chronology_date'][0]);
+            }
+          }
+          else
+          {
+            $chronology_date = $page['chronology_date'];
+          }
+          $url = duplicate_index_url(
+              array(
+                'chronology_style' => $style,
+                'chronology_view' => $view,
+                'chronology_date' => $chronology_date,
+                )
+             );
+
+          if ($style==$cal_style and $view==$page['chronology_view'] )
+          {
+            $selected = true;
+          }
+
+          $template->append(
+            'chronology_views',
+            array(
+              'VALUE' => $url,
+              'CONTENT' => l10n('chronology_'.$style.'_'.$view),
+              'SELECTED' => $selected,
+              )
+            );
+        }
+      }
+    }
+    $url = duplicate_index_url(
+              array(), array('start', 'chronology_date')
+            );
+    $calendar_title = '<a href="'.$url.'">'
+        .$fields[$page['chronology_field']]['label'].'</a>';
+    $calendar_title.= $calendar->get_display_name();
+    $template->assign('chronology',
+        array(
+          'TITLE' => $calendar_title
+        )
+      );
+  } // end category calling
+
+  if ($must_show_list)
+  {
+    $query = 'SELECT DISTINCT(id)';
+    $query .= $calendar->inner_sql.'
+  '.$calendar->get_date_where();
+    if ( isset($page['super_order_by']) )
+    {
+      $query .= '
+  '.$conf['order_by'];
+    }
+    else
+    {
+      if ( count($page['chronology_date'])==0
+           or in_array('any', $page['chronology_date']) )
+      {// selected period is very big so we show newest first
+        $order = ' DESC, ';
+      }
+      else
+      {// selected period is small (month,week) so we show oldest first
+        $order = ' ASC, ';
+      }
+      $order_by = str_replace(
+        'ORDER BY ',
+        'ORDER BY '.$calendar->date_field.$order, $conf['order_by']
+        );
+      $query .= '
+  '.$order_by;
+    }
+    $page['items']              = array_from_query($query, 'id');
+  }
+  pwg_debug('end initialize_calendar');
+}
+
+?>
Index: /tags/2.0.2/include/functions_category.inc.php
===================================================================
--- /tags/2.0.2/include/functions_category.inc.php	(revision 3278)
+++ /tags/2.0.2/include/functions_category.inc.php	(revision 3278)
@@ -0,0 +1,526 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+/**
+ * Provides functions to handle categories.
+ *
+ *
+ */
+
+/**
+ * Is the category accessible to the connected user ?
+ *
+ * Note : if the user is not authorized to see this category, page creation
+ * ends (exit command in this function)
+ *
+ * @param int category id to verify
+ * @return void
+ */
+function check_restrictions($category_id)
+{
+  global $user;
+
+  // $filter['visible_categories'] and $filter['visible_images']
+  // are not used because it's not necessary (filter <> restriction)
+  if (in_array($category_id, explode(',', $user['forbidden_categories'])))
+  {
+    access_denied();
+  }
+}
+
+function get_categories_menu()
+{
+  global $page, $user, $filter;
+
+  $query = '
+SELECT ';
+  // From CATEGORIES_TABLE
+  $query.= '
+  id, name, permalink, nb_images, global_rank,';
+  // From USER_CACHE_CATEGORIES_TABLE
+  $query.= '
+  date_last, max_date_last, count_images, count_categories';
+
+  // $user['forbidden_categories'] including with USER_CACHE_CATEGORIES_TABLE
+  $query.= '
+FROM '.CATEGORIES_TABLE.' INNER JOIN '.USER_CACHE_CATEGORIES_TABLE.'
+  ON id = cat_id and user_id = '.$user['id'];
+
+  // Always expand when filter is activated
+  if (!$user['expand'] and !$filter['enabled'])
+  {
+    $where = '
+(id_uppercat is NULL';
+    if (isset($page['category']))
+    {
+      $where .= ' OR id_uppercat IN ('.$page['category']['uppercats'].')';
+    }
+    $where .= ')';
+  }
+  else
+  {
+    $where = '
+  '.get_sql_condition_FandF
+    (
+      array
+        (
+          'visible_categories' => 'id',
+        ),
+      null,
+      true
+    );
+  }
+
+  $where = trigger_event('get_categories_menu_sql_where',
+    $where, $user['expand'], $filter['enabled'] );
+
+  $query.= '
+WHERE '.$where.'
+;';
+
+  $result = pwg_query($query);
+  $cats = array();
+  while ($row = mysql_fetch_assoc($result))
+  {
+    array_push($cats, $row);
+    if ($row['id']==@$page['category']['id']) //save the number of subcats for later optim
+      $page['category']['count_categories'] = $row['count_categories'];
+  }
+  usort($cats, 'global_rank_compare');
+
+  // Update filtered data
+  if (function_exists('update_cats_with_filtered_data'))
+  {
+    update_cats_with_filtered_data($cats);
+  }
+
+  return get_html_menu_category($cats, @$page['category'] );
+}
+
+
+/**
+ * Retrieve informations about a category in the database
+ *
+ * Returns an array with following keys :
+ *
+ *  - comment
+ *  - dir : directory, might be empty for virtual categories
+ *  - name : an array with indexes from 0 (lowest cat name) to n (most
+ *           uppercat name findable)
+ *  - nb_images
+ *  - id_uppercat
+ *  - site_id
+ *  -
+ *
+ * @param int category id
+ * @return array
+ */
+function get_cat_info( $id )
+{
+  $query = '
+SELECT *
+  FROM '.CATEGORIES_TABLE.'
+  WHERE id = '.$id.'
+;';
+  $cat = mysql_fetch_assoc(pwg_query($query));
+  if (empty($cat))
+    return null;
+
+  foreach ($cat as $k => $v)
+  {
+    // If the field is true or false, the variable is transformed into a
+    // boolean value.
+    if ($cat[$k] == 'true' or $cat[$k] == 'false')
+    {
+      $cat[$k] = get_boolean( $cat[$k] );
+    }
+  }
+
+  $upper_ids = explode(',', $cat['uppercats']);
+  if ( count($upper_ids)==1 )
+  {// no need to make a query for level 1
+    $cat['upper_names'] = array(
+        array(
+          'id' => $cat['id'],
+          'name' => $cat['name'],
+          'permalink' => $cat['permalink'],
+          )
+      );
+  }
+  else
+  {
+    $names = array();
+    $query = '
+  SELECT id, name, permalink
+    FROM '.CATEGORIES_TABLE.'
+    WHERE id IN ('.$cat['uppercats'].')
+  ;';
+    $names = hash_from_query($query, 'id');
+
+    // category names must be in the same order than uppercats list
+    $cat['upper_names'] = array();
+    foreach ($upper_ids as $cat_id)
+    {
+      array_push( $cat['upper_names'], $names[$cat_id]);
+    }
+  }
+  return $cat;
+}
+
+// get_complete_dir returns the concatenation of get_site_url and
+// get_local_dir
+// Example : "pets > rex > 1_year_old" is on the the same site as the
+// Piwigo files and this category has 22 for identifier
+// get_complete_dir(22) returns "./galleries/pets/rex/1_year_old/"
+function get_complete_dir( $category_id )
+{
+  return get_site_url($category_id).get_local_dir($category_id);
+}
+
+// get_local_dir returns an array with complete path without the site url
+// Example : "pets > rex > 1_year_old" is on the the same site as the
+// Piwigo files and this category has 22 for identifier
+// get_local_dir(22) returns "pets/rex/1_year_old/"
+function get_local_dir( $category_id )
+{
+  global $page;
+
+  $uppercats = '';
+  $local_dir = '';
+
+  if ( isset( $page['plain_structure'][$category_id]['uppercats'] ) )
+  {
+    $uppercats = $page['plain_structure'][$category_id]['uppercats'];
+  }
+  else
+  {
+    $query = 'SELECT uppercats';
+    $query.= ' FROM '.CATEGORIES_TABLE.' WHERE id = '.$category_id;
+    $query.= ';';
+    $row = mysql_fetch_array( pwg_query( $query ) );
+    $uppercats = $row['uppercats'];
+  }
+
+  $upper_array = explode( ',', $uppercats );
+
+  $database_dirs = array();
+  $query = 'SELECT id,dir';
+  $query.= ' FROM '.CATEGORIES_TABLE.' WHERE id IN ('.$uppercats.')';
+  $query.= ';';
+  $result = pwg_query( $query );
+  while( $row = mysql_fetch_array( $result ) )
+  {
+    $database_dirs[$row['id']] = $row['dir'];
+  }
+  foreach ($upper_array as $id)
+  {
+    $local_dir.= $database_dirs[$id].'/';
+  }
+
+  return $local_dir;
+}
+
+// retrieving the site url : "http://domain.com/gallery/" or
+// simply "./galleries/"
+function get_site_url($category_id)
+{
+  global $page;
+
+  $query = '
+SELECT galleries_url
+  FROM '.SITES_TABLE.' AS s,'.CATEGORIES_TABLE.' AS c
+  WHERE s.id = c.site_id
+    AND c.id = '.$category_id.'
+;';
+  $row = mysql_fetch_array(pwg_query($query));
+  return $row['galleries_url'];
+}
+
+// returns an array of image orders available for users/visitors
+function get_category_preferred_image_orders()
+{
+  global $conf, $page;
+
+  return trigger_event('get_category_preferred_image_orders',
+    array(
+    array(l10n('default_sort'), '', true),
+    array(l10n('Average rate'), 'average_rate DESC', $conf['rate']),
+    array(l10n('most_visited_cat'), 'hit DESC', true),
+    array(l10n('Creation date'), 'date_creation DESC', true),
+    array(l10n('Post date'), 'date_available DESC', true),
+    array(l10n('File name'), 'file ASC', true),
+    array(
+      l10n('Rank'),
+      'rank ASC',
+      ('categories' == @$page['section'] and !isset($page['flat']) and !isset($page['chronology_field']) )
+      ),
+    array( l10n('permissions'), 'level DESC', is_admin() )
+    ));
+}
+
+function display_select_categories($categories,
+                                   $selecteds,
+                                   $blockname,
+                                   $fullname = true)
+{
+  global $template;
+
+  $tpl_cats = array();
+  foreach ($categories as $category)
+  {
+    if ($fullname)
+    {
+      $option = get_cat_display_name_cache($category['uppercats'],
+                                           null,
+                                           false);
+    }
+    else
+    {
+      $option = str_repeat('&nbsp;',
+                           (3 * substr_count($category['global_rank'], '.')));
+      $option.= '- ';
+      $option.= strip_tags(
+        trigger_event(
+          'render_category_name',
+          $category['name'],
+          'display_select_categories'
+          )
+        );
+    }
+    $tpl_cats[ $category['id'] ] = $option;
+  }
+
+  $template->assign( $blockname, $tpl_cats);
+  $template->assign( $blockname.'_selected', $selecteds);
+}
+
+function display_select_cat_wrapper($query, $selecteds, $blockname,
+                                    $fullname = true)
+{
+  $result = pwg_query($query);
+  $categories = array();
+  if (!empty($result))
+  {
+    while ($row = mysql_fetch_assoc($result))
+    {
+      array_push($categories, $row);
+    }
+  }
+  usort($categories, 'global_rank_compare');
+  display_select_categories($categories, $selecteds, $blockname, $fullname);
+}
+
+/**
+ * returns all subcategory identifiers of given category ids
+ *
+ * @param array ids
+ * @return array
+ */
+function get_subcat_ids($ids)
+{
+  $query = '
+SELECT DISTINCT(id)
+  FROM '.CATEGORIES_TABLE.'
+  WHERE ';
+  foreach ($ids as $num => $category_id)
+  {
+    is_numeric($category_id)
+      or trigger_error(
+        'get_subcat_ids expecting numeric, not '.gettype($category_id),
+        E_USER_WARNING
+      );
+    if ($num > 0)
+    {
+      $query.= '
+    OR ';
+    }
+    $query.= 'uppercats REGEXP \'(^|,)'.$category_id.'(,|$)\'';
+  }
+  $query.= '
+;';
+  $result = pwg_query($query);
+
+  $subcats = array();
+  while ($row = mysql_fetch_array($result))
+  {
+    array_push($subcats, $row['id']);
+  }
+  return $subcats;
+}
+
+/** finds a matching category id from a potential list of permalinks
+ * @param array permalinks example: holiday holiday/france holiday/france/paris
+ * @param int idx - output of the index in $permalinks that matches
+ * return category id or null if no match
+ */
+function get_cat_id_from_permalinks( $permalinks, &$idx )
+{
+  $in = '';
+  foreach($permalinks as $permalink)
+  {
+    if ( !empty($in) ) $in.=', ';
+    $in .= '"'.$permalink.'"';
+  }
+  $query ='
+SELECT cat_id AS id, permalink, 1 AS is_old
+  FROM '.OLD_PERMALINKS_TABLE.'
+  WHERE permalink IN ('.$in.')
+UNION
+SELECT id, permalink, 0 AS is_old
+  FROM '.CATEGORIES_TABLE.'
+  WHERE permalink IN ('.$in.')
+;';
+  $perma_hash = hash_from_query($query, 'permalink');
+
+  if ( empty($perma_hash) )
+    return null;
+  for ($i=count($permalinks)-1; $i>=0; $i--)
+  {
+    if ( isset( $perma_hash[ $permalinks[$i] ] ) )
+    {
+      $idx = $i;
+      $cat_id = $perma_hash[ $permalinks[$i] ]['id'];
+      if ($perma_hash[ $permalinks[$i] ]['is_old'])
+      {
+        $query='
+UPDATE '.OLD_PERMALINKS_TABLE.' SET last_hit=NOW(), hit=hit+1
+  WHERE permalink="'.$permalinks[$i].'" AND cat_id='.$cat_id.'
+  LIMIT 1';
+        pwg_query($query);
+      }
+      return $cat_id;
+    }
+  }
+  return null;
+}
+
+function global_rank_compare($a, $b)
+{
+  return strnatcasecmp($a['global_rank'], $b['global_rank']);
+}
+
+function rank_compare($a, $b)
+{
+  if ($a['rank'] == $b['rank'])
+  {
+    return 0;
+  }
+
+  return ($a['rank'] < $b['rank']) ? -1 : 1;
+}
+
+/**
+ * returns display text for information images of category
+ *
+ * @param array categories
+ * @return string
+ */
+function get_display_images_count($cat_nb_images, $cat_count_images, $cat_count_categories, $short_message = true, $Separator = '\n')
+{
+  $display_text = '';
+
+  if ($cat_count_images > 0)
+  {
+    if ($cat_nb_images > 0 and $cat_nb_images < $cat_count_images)
+    {
+      $display_text.= get_display_images_count($cat_nb_images, $cat_nb_images, 0, $short_message, $Separator).$Separator;
+      $cat_count_images-= $cat_nb_images;
+      $cat_nb_images = 0;
+    }
+
+    //at least one image direct or indirect
+    $display_text.= l10n_dec('%d element', '%d elements', $cat_count_images);
+
+    if ($cat_count_categories == 0 or $cat_nb_images == $cat_count_images)
+    {
+      //no descendant categories or descendants do not contain images
+      if (! $short_message)
+      {
+        $display_text.= ' '.l10n('images_available_cpl');
+      }
+    }
+    else
+    {
+      $display_text.= ' '.l10n_dec('images_available_cat', 'images_available_cats', $cat_count_categories);
+    }
+  }
+
+  return $display_text;
+}
+
+/**
+ * returns the link of upload menu
+ *
+ * @param null
+ * @return string or null
+ */
+function get_upload_menu_link()
+{
+  global $conf, $page, $user;
+
+  $show_link = false;
+  $arg_link = null;
+
+  if (is_autorize_status($conf['upload_user_access']))
+  {
+    if (isset($page['category']) and $page['category']['uploadable'] )
+    {
+      // upload a picture in the category
+      $show_link = true;
+      $arg_link = 'cat='.$page['category']['id'];
+    }
+    else
+    if ($conf['upload_link_everytime'])
+    {
+      // upload a picture in the category
+      $query = '
+SELECT
+  1
+FROM '.CATEGORIES_TABLE.' INNER JOIN '.USER_CACHE_CATEGORIES_TABLE.'
+  ON id = cat_id and user_id = '.$user['id'].'
+WHERE
+  uploadable = \'true\'
+  '.get_sql_condition_FandF
+    (
+      array
+        (
+          'visible_categories' => 'id',
+        ),
+      'AND'
+    ).'
+LIMIT 1';
+
+      $show_link = mysql_num_rows(pwg_query($query)) <> 0;
+    }
+  }
+  if ($show_link)
+  {
+    return get_root_url().'upload.php'.(empty($arg_link) ? '' : '?'.$arg_link);
+  }
+  else
+  {
+    return;
+  }
+}
+
+?>
Index: /tags/2.0.2/include/functions_comment.inc.php
===================================================================
--- /tags/2.0.2/include/functions_comment.inc.php	(revision 3278)
+++ /tags/2.0.2/include/functions_comment.inc.php	(revision 3278)
@@ -0,0 +1,208 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+//returns string action to perform on a new comment: validate, moderate, reject
+function user_comment_check($action, $comment)
+{
+  global $conf,$user;
+
+  if ($action=='reject')
+    return $action;
+
+  $my_action = $conf['comment_spam_reject'] ? 'reject':'moderate';
+
+  if ($action==$my_action)
+    return $action;
+
+  // we do here only BASIC spam check (plugins can do more)
+  if ( !is_a_guest() )
+    return $action;
+
+  $link_count = preg_match_all( '/https?:\/\//',
+    $comment['content'], $matches);
+
+  if ( strpos($comment['author'], 'http://')!==false )
+  {
+    $link_count++;
+  }
+
+  if ( $link_count>$conf['comment_spam_max_links'] )
+    return $my_action;
+
+  return $action;
+}
+
+
+add_event_handler('user_comment_check', 'user_comment_check',
+  EVENT_HANDLER_PRIORITY_NEUTRAL, 2);
+
+/**
+ * Tries to insert a user comment in the database and returns one of :
+ * validate, moderate, reject
+ * @param array comm contains author, content, image_id
+ * @param string key secret key sent back to the browser
+ * @param array infos out array of messages
+ */
+function insert_user_comment( &$comm, $key, &$infos )
+{
+  global $conf, $user;
+
+  $comm = array_merge( $comm,
+    array(
+      'ip' => $_SERVER['REMOTE_ADDR'],
+      'agent' => $_SERVER['HTTP_USER_AGENT']
+    )
+   );
+
+  $infos = array();
+  if (!$conf['comments_validation'] or is_admin())
+  {
+    $comment_action='validate'; //one of validate, moderate, reject
+  }
+  else
+  {
+    $comment_action='moderate'; //one of validate, moderate, reject
+  }
+
+  // display author field if the user status is guest or generic
+  if (!is_classic_user())
+  {
+    if ( empty($comm['author']) )
+    {
+      $comm['author'] = 'guest';
+    }
+    // if a guest try to use the name of an already existing user, he must be
+    // rejected
+    if ( $comm['author'] != 'guest' )
+    {
+      $query = '
+SELECT COUNT(*) AS user_exists
+  FROM '.USERS_TABLE.'
+  WHERE '.$conf['user_fields']['username']." = '".addslashes($comm['author'])."'";
+      $row = mysql_fetch_assoc( pwg_query( $query ) );
+      if ( $row['user_exists'] == 1 )
+      {
+        array_push($infos, l10n('comment_user_exists') );
+        $comment_action='reject';
+      }
+    }
+  }
+  else
+  {
+    $comm['author'] = $user['username'];
+  }
+  if ( empty($comm['content']) )
+  { // empty comment content
+    $comment_action='reject';
+  }
+
+  $key = explode( ':', @$key );
+  if ( count($key)!=2
+        or $key[0]>time()-2 // page must have been retrieved more than 2 sec ago
+        or $key[0]<time()-3600 // 60 minutes expiration
+        or hash_hmac(
+              'md5', $key[0].':'.$comm['image_id'], $conf['secret_key']
+            ) != $key[1]
+      )
+  {
+    $comment_action='reject';
+  }
+
+  if ($comment_action!='reject' and $conf['anti-flood_time']>0 )
+  { // anti-flood system
+    $reference_date = time() - $conf['anti-flood_time'];
+    $query = '
+SELECT id FROM '.COMMENTS_TABLE.'
+  WHERE date > FROM_UNIXTIME('.$reference_date.')
+    AND author = "'.addslashes($comm['author']).'"';
+    if ( mysql_num_rows( pwg_query( $query ) ) > 0 )
+    {
+      array_push( $infos, l10n('comment_anti-flood') );
+      $comment_action='reject';
+    }
+  }
+
+  // perform more spam check
+  $comment_action = trigger_event('user_comment_check',
+      $comment_action, $comm
+    );
+
+  if ( $comment_action!='reject' )
+  {
+    $query = '
+INSERT INTO '.COMMENTS_TABLE.'
+  (author, content, date, validated, validation_date, image_id)
+  VALUES (
+    "'.addslashes($comm['author']).'",
+    "'.addslashes($comm['content']).'",
+    NOW(),
+    "'.($comment_action=='validate' ? 'true':'false').'",
+    '.($comment_action=='validate' ? 'NOW()':'NULL').',
+    '.$comm['image_id'].'
+  )
+';
+
+    pwg_query($query);
+
+    $comm['id'] = mysql_insert_id();
+
+    if
+      (
+        ($comment_action=='validate' and $conf['email_admin_on_comment'])
+        or
+        ($comment_action!='validate' and $conf['email_admin_on_comment_validation'])
+      )
+    {
+      include_once(PHPWG_ROOT_PATH.'include/functions_mail.inc.php');
+
+      $del_url =
+          get_absolute_root_url().'comments.php?delete='.$comm['id'];
+
+      $keyargs_content = array
+      (
+        get_l10n_args('Author: %s', $comm['author']),
+        get_l10n_args('Comment: %s', $comm['content']),
+        get_l10n_args('', ''),
+        get_l10n_args('Delete: %s', $del_url)
+      );
+
+      if ($comment_action!='validate')
+      {
+        $keyargs_content[] =
+          get_l10n_args('', '');
+        $keyargs_content[] =
+          get_l10n_args('Validate: %s',
+            get_absolute_root_url().'comments.php?validate='.$comm['id']);
+      }
+
+      pwg_mail_notification_admins
+      (
+        get_l10n_args('Comment by %s', $comm['author']),
+        $keyargs_content
+      );
+    }
+  }
+  return $comment_action;
+}
+
+?>
Index: /tags/2.0.2/include/functions_cookie.inc.php
===================================================================
--- /tags/2.0.2/include/functions_cookie.inc.php	(revision 3278)
+++ /tags/2.0.2/include/functions_cookie.inc.php	(revision 3278)
@@ -0,0 +1,123 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// cookie_path returns the path to use for the Piwigo cookie.
+// If Piwigo is installed on :
+// http://domain.org/meeting/gallery/category.php
+// cookie_path will return : "/meeting/gallery"
+function cookie_path()
+{
+  if ( isset($_SERVER['REDIRECT_SCRIPT_NAME']) and
+       !empty($_SERVER['REDIRECT_SCRIPT_NAME']) )
+  {
+    $scr = $_SERVER['REDIRECT_SCRIPT_NAME'];
+  }
+  else if ( isset($_SERVER['REDIRECT_URL']) )
+  {
+    // mod_rewrite is activated for upper level directories. we must set the
+    // cookie to the path shown in the browser otherwise it will be discarded.
+    if
+      (
+        isset($_SERVER['PATH_INFO']) and !empty($_SERVER['PATH_INFO']) and
+        ($_SERVER['REDIRECT_URL'] !== $_SERVER['PATH_INFO']) and
+        (substr($_SERVER['REDIRECT_URL'],-strlen($_SERVER['PATH_INFO']))
+            == $_SERVER['PATH_INFO'])
+      )
+    {
+      $scr = substr($_SERVER['REDIRECT_URL'], 0,
+        strlen($_SERVER['REDIRECT_URL'])-strlen($_SERVER['PATH_INFO']));
+    }
+    else
+    {
+      $scr = $_SERVER['REDIRECT_URL'];
+    }
+  }
+  else
+  {
+    $scr = $_SERVER['SCRIPT_NAME'];
+  }
+
+  $scr = substr($scr,0,strrpos( $scr,'/'));
+
+  // add a trailing '/' if needed
+  if ((strlen($scr) == 0) or ($scr{strlen($scr)-1} !== '/'))
+  {
+    $scr .= '/';
+  }
+
+  if ( substr(PHPWG_ROOT_PATH,0,3)=='../')
+  { // this is maybe a plugin inside pwg directory
+    // TODO - what if it is an external script outside PWG ?
+    $scr = $scr.PHPWG_ROOT_PATH;
+    while (1)
+    {
+      $new = preg_replace('#[^/]+/\.\.(/|$)#', '', $scr);
+      if ($new==$scr)
+      {
+        break;
+      }
+      $scr=$new;
+    }
+  }
+  return $scr;
+}
+
+/**
+ * persistently stores a variable in pwg cookie
+ * @return boolean true on success
+ * @see pwg_get_cookie_var
+ */
+function pwg_set_cookie_var($var, $value, $expire=null)
+{
+  if ($value==null or $expire===0)
+  {
+    unset($_COOKIE['pwg_'.$var]);
+    return setcookie('pwg_'.$var, false, 0, cookie_path());
+
+  }
+  else
+  {
+    $_COOKIE['pwg_'.$var] = $value;
+    $expire = is_numeric($expire) ? $expire : strtotime('+10 years');
+    return setcookie('pwg_'.$var, $value, $expire, cookie_path());
+  }
+}
+
+/**
+ * retrieves the value of a persistent variable in pwg cookie
+ * @return mixed
+ * @see pwg_set_cookie_var
+ */
+function pwg_get_cookie_var($var, $default = null)
+{
+  if (isset($_COOKIE['pwg_'.$var]))
+  {
+    return $_COOKIE['pwg_'.$var];
+  }
+  else
+  {
+    return $default;
+  }
+}
+
+?>
Index: /tags/2.0.2/include/functions_filter.inc.php
===================================================================
--- /tags/2.0.2/include/functions_filter.inc.php	(revision 3278)
+++ /tags/2.0.2/include/functions_filter.inc.php	(revision 3278)
@@ -0,0 +1,50 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+
+
+/**
+ * update data of categories with filtered values
+ *
+ * @param array list of categories
+ * @return null
+ */
+function update_cats_with_filtered_data(&$cats)
+{
+  global $filter;
+
+  if ($filter['enabled'])
+  {
+    $upd_fields = array('date_last', 'max_date_last', 'count_images', 'count_categories', 'nb_images');
+
+    foreach ($cats as $cat_id => $category)
+    {
+      foreach ($upd_fields as $upd_field)
+      {
+        $cats[$cat_id][$upd_field] = $filter['categories'][$category['id']][$upd_field];
+      }
+    }
+  }
+}
+
+?>
Index: /tags/2.0.2/include/functions_html.inc.php
===================================================================
--- /tags/2.0.2/include/functions_html.inc.php	(revision 3278)
+++ /tags/2.0.2/include/functions_html.inc.php	(revision 3278)
@@ -0,0 +1,817 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+function get_icon($date, $is_child_date = false)
+{
+  global $cache, $user;
+
+  if (empty($date))
+  {
+    return '';
+  }
+
+  if (isset($cache['get_icon'][$date]))
+  {
+    if (! $cache['get_icon'][$date] )
+      return '';
+    return $cache['get_icon']['_icons_'][$is_child_date];
+  }
+
+  if (!isset($cache['get_icon']['sql_recent_date']))
+  {
+    // Use MySql date in order to standardize all recent "actions/queries"
+    list($cache['get_icon']['sql_recent_date']) =
+      mysql_fetch_array(pwg_query('select SUBDATE(
+      CURRENT_DATE,INTERVAL '.$user['recent_period'].' DAY)'));
+  }
+
+  $cache['get_icon'][$date] = false;
+  if ( $date > $cache['get_icon']['sql_recent_date'] )
+  {
+    if ( !isset($cache['get_icon']['_icons_'] ) )
+    {
+      $icons = array(false => 'recent', true => 'recent_by_child' );
+      $title = sprintf(
+        l10n('elements posted during the last %d days'),
+        $user['recent_period']
+        );
+      foreach ($icons as $key => $icon)
+      {
+        $icon_url = get_themeconf('icon_dir').'/'.$icon.'.png';
+        $size = getimagesize( PHPWG_ROOT_PATH.$icon_url );
+        $icon_url = get_root_url().$icon_url;
+        $output = '<img title="'.$title.'" src="'.$icon_url.'" class="icon" style="border:0;';
+        $output.= 'height:'.$size[1].'px;width:'.$size[0].'px" alt="(!)" />';
+        $cache['get_icon']['_icons_'][$key] = $output;
+      }
+    }
+    $cache['get_icon'][$date] = true;
+  }
+
+  if (! $cache['get_icon'][$date] )
+    return '';
+  return $cache['get_icon']['_icons_'][$is_child_date];
+}
+
+function create_navigation_bar(
+  $url, $nb_element, $start, $nb_element_page, $clean_url = false
+  )
+{
+  global $conf;
+
+  $pages_around = $conf['paginate_pages_around'];
+  $start_str = $clean_url ? '/start-' :
+    ( ( strpos($url, '?')===false ? '?':'&amp;') . 'start=' );
+
+  $navbar = '';
+
+  // current page detection
+  if (!isset($start)
+      or !is_numeric($start)
+      or (is_numeric($start) and $start < 0))
+  {
+    $start = 0;
+  }
+
+  // navigation bar useful only if more than one page to display !
+  if ($nb_element > $nb_element_page)
+  {
+    // current page and last page
+    $cur_page = ceil($start / $nb_element_page) + 1;
+    $maximum = ceil($nb_element / $nb_element_page);
+
+    // link to first page ?
+    if ($cur_page != 1)
+    {
+      $navbar.=
+        '<a href="'.$url.'" rel="first">'
+        .l10n('first_page')
+        .'</a>';
+    }
+    else
+    {
+      $navbar.= l10n('first_page');
+    }
+    $navbar.= ' | ';
+    // link on previous page ?
+    if ($start != 0)
+    {
+      $previous = $start - $nb_element_page;
+
+      $navbar.=
+        '<a href="'
+        .$url.($previous > 0 ? $start_str.$previous : '')
+        .'" rel="prev">'
+        .l10n('previous_page')
+        .'</a>';
+    }
+    else
+    {
+      $navbar.= l10n('previous_page');
+    }
+    $navbar.= ' |';
+
+    if ($cur_page > $pages_around + 1)
+    {
+      $navbar.= '&nbsp;<a href="'.$url.'">1</a>';
+
+      if ($cur_page > $pages_around + 2)
+      {
+        $navbar.= ' ...';
+      }
+    }
+
+    // inspired from punbb source code
+    for ($i = $cur_page - $pages_around, $stop = $cur_page + $pages_around + 1;
+         $i < $stop;
+         $i++)
+    {
+      if ($i < 1 or $i > $maximum)
+      {
+        continue;
+      }
+      else if ($i != $cur_page)
+      {
+        $temp_start = ($i - 1) * $nb_element_page;
+
+        $navbar.=
+          '&nbsp;'
+          .'<a href="'.$url
+          .($temp_start > 0 ? $start_str.$temp_start : '')
+          .'">'
+          .$i
+          .'</a>';
+      }
+      else
+      {
+        $navbar.=
+          '&nbsp;'
+          .'<span class="pageNumberSelected">'
+          .$i
+          .'</span>';
+      }
+    }
+
+    if ($cur_page < ($maximum - $pages_around))
+    {
+      $temp_start = ($maximum - 1) * $nb_element_page;
+
+      if ($cur_page < ($maximum - $pages_around - 1))
+      {
+        $navbar.= ' ...';
+      }
+
+      $navbar.= ' <a href="'.$url.$start_str.$temp_start.'">'.$maximum.'</a>';
+    }
+
+    $navbar.= ' | ';
+    // link on next page ?
+    if ($nb_element > $nb_element_page
+        and $start + $nb_element_page < $nb_element)
+    {
+      $next = $start + $nb_element_page;
+
+      $navbar.=
+        '<a href="'.$url.$start_str.$next.'" rel="next">'
+        .l10n('next_page')
+        .'</a>';
+    }
+    else
+    {
+      $navbar.= l10n('next_page');
+    }
+
+    $navbar.= ' | ';
+    // link to last page ?
+    if ($cur_page != $maximum)
+    {
+      $temp_start = ($maximum - 1) * $nb_element_page;
+
+      $navbar.=
+        '<a href="'.$url.$start_str.$temp_start.'" rel="last">'
+        .l10n('last_page')
+        .'</a>';
+    }
+    else
+    {
+      $navbar.= l10n('last_page');
+    }
+  }
+  return $navbar;
+}
+
+/**
+ * returns the list of categories as a HTML string
+ *
+ * categories string returned contains categories as given in the input
+ * array $cat_informations. $cat_informations array must be an array
+ * of array( id=>?, name=>?, permalink=>?). If url input parameter is null,
+ * returns only the categories name without links.
+ *
+ * @param array cat_informations
+ * @param string url
+ * @param boolean replace_space
+ * @return string
+ */
+function get_cat_display_name($cat_informations,
+                              $url = '',
+                              $replace_space = true)
+{
+  global $conf;
+
+  $output = '';
+  $is_first = true;
+  foreach ($cat_informations as $cat)
+  {
+    is_array($cat) or trigger_error(
+        'get_cat_display_name wrong type for category ', E_USER_WARNING
+      );
+
+    $cat['name'] = trigger_event(
+      'render_category_name',
+      $cat['name'],
+      'get_cat_display_name'
+      );
+
+    if ($is_first)
+    {
+      $is_first = false;
+    }
+    else
+    {
+      $output.= $conf['level_separator'];
+    }
+
+    if ( !isset($url) )
+    {
+      $output.= $cat['name'];
+    }
+    elseif ($url == '')
+    {
+      $output.= '<a href="'
+            .make_index_url(
+                array(
+                  'category' => $cat,
+                  )
+              )
+            .'">';
+      $output.= $cat['name'].'</a>';
+    }
+    else
+    {
+      $output.= '<a href="'.PHPWG_ROOT_PATH.$url.$cat['id'].'">';
+      $output.= $cat['name'].'</a>';
+    }
+  }
+  if ($replace_space)
+  {
+    return replace_space($output);
+  }
+  else
+  {
+    return $output;
+  }
+}
+
+/**
+ * returns the list of categories as a HTML string, with cache of names
+ *
+ * categories string returned contains categories as given in the input
+ * array $cat_informations. $uppercats is the list of category ids to
+ * display in the right order. If url input parameter is empty, returns only
+ * the categories name without links.
+ *
+ * @param string uppercats
+ * @param string url
+ * @param boolean replace_space
+ * @return string
+ */
+function get_cat_display_name_cache($uppercats,
+                                    $url = '',
+                                    $replace_space = true)
+{
+  global $cache, $conf;
+
+  if (!isset($cache['cat_names']))
+  {
+    $query = '
+SELECT id, name, permalink
+  FROM '.CATEGORIES_TABLE.'
+;';
+    $cache['cat_names'] = hash_from_query($query, 'id');
+  }
+
+  $output = '';
+  $is_first = true;
+  foreach (explode(',', $uppercats) as $category_id)
+  {
+    $cat = $cache['cat_names'][$category_id];
+
+    $cat['name'] = trigger_event(
+      'render_category_name',
+      $cat['name'],
+      'get_cat_display_name_cache'
+      );
+
+    if ($is_first)
+    {
+      $is_first = false;
+    }
+    else
+    {
+      $output.= $conf['level_separator'];
+    }
+
+    if ( !isset($url) )
+    {
+      $output.= $cat['name'];
+    }
+    elseif ($url == '')
+    {
+      $output.= '
+<a href="'
+      .make_index_url(
+          array(
+            'category' => $cat,
+            )
+        )
+      .'">'.$cat['name'].'</a>';
+    }
+    else
+    {
+      $output.= '
+<a href="'.PHPWG_ROOT_PATH.$url.$category_id.'">'.$cat['name'].'</a>';
+    }
+  }
+  if ($replace_space)
+  {
+    return replace_space($output);
+  }
+  else
+  {
+    return $output;
+  }
+}
+
+/**
+ * returns the HTML code for a category item in the menu (for the main page)
+ *
+ * HTML code generated uses logical list tags ul and each category is an
+ * item li. The paramter given is the category informations as an array,
+ * used keys are : id, name, nb_images, max_date_last, date_last
+ * count_images, count_categories
+ *
+ * @param array categories
+ * @return string
+ */
+function get_html_menu_category($categories, $selected_category)
+{
+  $ref_level = 0;
+  $level = 0;
+
+  $menu = trigger_event('get_html_menu_category', '',
+            $categories, $selected_category);
+  if (strlen($menu))
+  {
+    return $menu;
+  }
+
+  foreach ($categories as $category)
+  {
+    $level = substr_count($category['global_rank'], '.') + 1;
+    if ($level > $ref_level)
+    {
+      $menu.= "\n<ul>";
+    }
+    else if ($level == $ref_level)
+    {
+      $menu.= "\n</li>";
+    }
+    else if ($level < $ref_level)
+    {
+      // we may have to close more than one level at the same time...
+      $menu.= "\n</li>";
+      $menu.= str_repeat("\n</ul></li>",($ref_level-$level));
+    }
+    $ref_level = $level;
+
+    $menu.= "\n\n".'<li';
+    if ($category['id'] == @$selected_category['id'])
+    {
+      $menu.= ' class="selected"';
+    }
+    $menu.= '>';
+
+    $url = make_index_url(
+            array(
+              'category' => $category
+              )
+            );
+
+    $title = get_display_images_count
+                (
+                  $category['nb_images'],
+                  $category['count_images'],
+                  $category['count_categories'],
+                  false,
+                  ' / '
+                );
+
+    $menu.= '<a href="'.$url.'"';
+    if ($selected_category!=null
+        and $category['id'] == $selected_category['id_uppercat'])
+    {
+      $menu.= ' rel="up"';
+    }
+    $menu.= ' title="'.$title.'">';
+    $menu.= trigger_event(
+      'render_category_name',
+      $category['name'],
+      'get_html_menu_category'
+      );
+    $menu.= '</a>';
+
+    if ( $category['count_images']>0 )
+    {// at least one direct or indirect image
+      $menu.= "\n".'<span class="';
+      // at least one image in this category -> class menuInfoCat
+      $menu.= ($category['nb_images'] > 0 ? "menuInfoCat"
+                                          : "menuInfoCatByChild").'"';
+      $menu.= ' title=" '.$title.'">';
+      // show total number of images
+      $menu.= '['.$category['count_images'].']';
+      $menu.= '</span>';
+    }
+    $child_date_last = @$category['max_date_last']> @$category['date_last'];
+    $menu.= get_icon($category['max_date_last'], $child_date_last);
+  }
+
+  $menu.= str_repeat("\n</li></ul>",($level));
+
+  return $menu;
+}
+
+/**
+ * returns HTMLized comment contents retrieved from database
+ *
+ * newlines becomes br tags, _word_ becomes underline, /word/ becomes
+ * italic, *word* becomes bolded
+ *
+ * @param string content
+ * @return string
+ */
+function parse_comment_content($content)
+{
+  $pattern = '/(https?:\/\/\S*)/';
+  $replacement = '<a href="$1" rel="nofollow">$1</a>';
+  $content = preg_replace($pattern, $replacement, $content);
+
+  $content = nl2br($content);
+
+  // replace _word_ by an underlined word
+  $pattern = '/\b_(\S*)_\b/';
+  $replacement = '<span style="text-decoration:underline;">$1</span>';
+  $content = preg_replace($pattern, $replacement, $content);
+
+  // replace *word* by a bolded word
+  $pattern = '/\b\*(\S*)\*\b/';
+  $replacement = '<span style="font-weight:bold;">$1</span>';
+  $content = preg_replace($pattern, $replacement, $content);
+
+  // replace /word/ by an italic word
+  $pattern = "/\/(\S*)\/(\s)/";
+  $replacement = '<span style="font-style:italic;">$1$2</span>';
+  $content = preg_replace($pattern, $replacement, $content);
+
+  $content = '<div>'.$content.'</div>';
+  return $content;
+}
+
+function get_cat_display_name_from_id($cat_id,
+                                      $url = '',
+                                      $replace_space = true)
+{
+  $cat_info = get_cat_info($cat_id);
+  return get_cat_display_name($cat_info['upper_names'], $url, $replace_space);
+}
+
+/**
+ * Returns an HTML list of tags. It can be a multi select field or a list of
+ * checkboxes.
+ *
+ * @param string HTML field name
+ * @param array selected tag ids
+ * @return array
+ */
+function get_html_tag_selection(
+  $tags,
+  $fieldname,
+  $selecteds = array(),
+  $forbidden_categories = null
+  )
+{
+  global $conf;
+
+  if (count ($tags) == 0 )
+  {
+    return '';
+  }
+  $output = '<ul class="tagSelection">';
+  foreach ($tags as $tag)
+  {
+    $output.=
+      '<li>'
+      .'<label>'
+      .'<input type="checkbox" name="'.$fieldname.'[]"'
+      .' value="'.$tag['id'].'"'
+      ;
+
+    if (in_array($tag['id'], $selecteds))
+    {
+      $output.= ' checked="checked"';
+    }
+
+    $output.=
+      ' />'
+      .' '. $tag['name']
+      .'</label>'
+      .'</li>'
+      ."\n"
+      ;
+  }
+  $output.= '</ul>';
+
+  return $output;
+}
+
+function name_compare($a, $b)
+{
+  return strcmp(strtolower($a['name']), strtolower($b['name']));
+}
+
+function tag_alpha_compare($a, $b)
+{
+  return strcmp(strtolower($a['url_name']), strtolower($b['url_name']));
+}
+
+/**
+ * exits the current script (either exit or redirect)
+ */
+function access_denied()
+{
+  global $user;
+
+  $login_url =
+      get_root_url().'identification.php?redirect='
+      .urlencode(urlencode($_SERVER['REQUEST_URI']));
+
+  set_status_header(401);
+  if ( isset($user) and !is_a_guest() )
+  {
+    echo '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">';
+    echo '<div style="text-align:center;">'.l10n('access_forbiden').'<br />';
+    echo '<a href="'.get_root_url().'identification.php">'.l10n('identification').'</a>&nbsp;';
+    echo '<a href="'.make_index_url().'">'.l10n('home').'</a></div>';
+    echo str_repeat( ' ', 512); //IE6 doesn't error output if below a size
+    exit();
+  }
+  else
+  {
+    redirect_html($login_url);
+  }
+}
+
+/**
+ * exits the current script with 403 code
+ * @param string msg a message to display
+ * @param string alternate_url redirect to this url
+ */
+function page_forbidden($msg, $alternate_url=null)
+{
+  set_status_header(403);
+  if ($alternate_url==null)
+    $alternate_url = make_index_url();
+  redirect_html( $alternate_url,
+    '<div style="text-align:left; margin-left:5em;margin-bottom:5em;">
+<h1 style="text-align:left; font-size:36px;">Forbidden</h1><br/>'
+.$msg.'</div>',
+    5 );
+}
+
+/**
+ * exits the current script with 400 code
+ * @param string msg a message to display
+ * @param string alternate_url redirect to this url
+ */
+function bad_request($msg, $alternate_url=null)
+{
+  set_status_header(400);
+  if ($alternate_url==null)
+    $alternate_url = make_index_url();
+  redirect_html( $alternate_url,
+    '<div style="text-align:left; margin-left:5em;margin-bottom:5em;">
+<h1 style="text-align:left; font-size:36px;">Bad request</h1><br/>'
+.$msg.'</div>',
+    5 );
+}
+
+/**
+ * exits the current script with 404 code when a page cannot be found
+ * @param string msg a message to display
+ * @param string alternate_url redirect to this url
+ */
+function page_not_found($msg, $alternate_url=null)
+{
+  set_status_header(404);
+  if ($alternate_url==null)
+    $alternate_url = make_index_url();
+  redirect_html( $alternate_url,
+    '<div style="text-align:left; margin-left:5em;margin-bottom:5em;">
+<h1 style="text-align:left; font-size:36px;">Page not found</h1><br/>'
+.$msg.'</div>',
+    5 );
+}
+
+/**
+ * exits the current script with 500 http code
+ * this method can be called at any time (does not use template/language/user etc...)
+ * @param string msg a message to display
+ */
+function fatal_error($msg)
+{
+  $btrace_msg = '';
+  if (function_exists('debug_backtrace'))
+  {
+    $bt = debug_backtrace();
+    for ($i=1; $i<count($bt); $i++)
+    {
+      $class = isset($bt[$i]['class']) ? (@$bt[$i]['class'].'::') : '';
+      $btrace_msg .= "#$i\t".$class.@$bt[$i]['function'].' '.@$bt[$i]['file']."(".@$bt[$i]['line'].")\n";
+    }
+    $btrace_msg = trim($btrace_msg);
+    $msg .= "\n";
+  }
+
+  $display = "<meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
+<h1>Piwigo encountered a non recoverable error</h1>
+<pre style='font-size:larger;background:white;color:red;padding:1em;margin:0;clear:both;display:block;width:auto;height:auto;overflow:auto'>
+<b>$msg</b>
+$btrace_msg
+</pre>\n";
+
+  @set_status_header(500);
+  echo $display.str_repeat( ' ', 300); //IE6 doesn't error output if below a size
+
+  if ( function_exists('ini_set') )
+  {// if possible turn off error display (we display it)
+    ini_set('display_errors', false);
+  }
+  error_reporting( E_ALL );
+  trigger_error( strip_tags($msg).$btrace_msg, E_USER_ERROR );
+  die(0); // just in case
+}
+
+/* returns the title to be displayed above thumbnails on tag page
+ */
+function get_tags_content_title()
+{
+  global $page;
+  $title = count($page['tags']) > 1 ? l10n('Tags') : l10n('Tag');
+  $title.= ' ';
+
+  for ($i=0; $i<count($page['tags']); $i++)
+  {
+    $title.= $i>0 ? ' + ' : '';
+
+    $title.=
+      '<a href="'
+      .make_index_url(
+        array(
+          'tags' => array( $page['tags'][$i] )
+          )
+        )
+      .'" title="'
+      .l10n('See elements linked to this tag only')
+      .'">'
+      .$page['tags'][$i]['name']
+      .'</a>';
+
+    if ( count($page['tags'])>2 )
+    {
+      $other_tags = $page['tags'];
+      unset ( $other_tags[$i] );
+      $title.=
+        '<a href="'
+        .make_index_url(
+          array(
+            'tags' => $other_tags
+            )
+          )
+        .'" style="border:none;" title="'
+        .l10n('remove this tag')
+        .'"><img src="'
+        .get_root_url().get_themeconf('icon_dir').'/remove_s.png'
+        .'" alt="x" style="vertical-align:bottom;" class="button"/>'
+        .'</a>';
+    }
+
+  }
+  return $title;
+}
+
+/**
+  Sets the http status header (200,401,...)
+ */
+function set_status_header($code, $text='')
+{
+  if (empty($text))
+  {
+    switch ($code)
+    {
+      case 200: $text='OK';break;
+      case 301: $text='Moved permanently';break;
+      case 302: $text='Moved temporarily';break;
+      case 304: $text='Not modified';break;
+      case 400: $text='Bad request';break;
+      case 401: $text='Authorization required';break;
+      case 403: $text='Forbidden';break;
+      case 404: $text='Not found';break;
+      case 500: $text='Server error';break;
+      case 501: $text='Not implemented';break;
+      case 503: $text='Service unavailable';break;
+    }
+  }
+	$protocol = $_SERVER["SERVER_PROTOCOL"];
+	if ( ('HTTP/1.1' != $protocol) && ('HTTP/1.0' != $protocol) )
+		$protocol = 'HTTP/1.0';
+
+	if ( version_compare( phpversion(), '4.3.0', '>=' ) )
+  {
+		header( "$protocol $code $text", true, $code );
+	}
+  else
+  {
+		header( "$protocol $code $text" );
+	}
+  trigger_action('set_status_header', $code, $text);
+}
+
+/** returns the category comment for rendering in html textual mode (subcatify)
+ * this is an event handler. don't call directly
+ */
+function render_category_literal_description($desc)
+{
+  return strip_tags($desc, '<span><p><a><br><b><i><small><big><strong><em>');
+}
+
+/** returns the argument_ids array with new sequenced keys based on related
+ * names. Sequence is not case sensitive.
+ * Warning: By definition, this function breaks original keys
+ */
+function order_by_name($element_ids,$name)
+{
+  $ordered_element_ids = array();
+  foreach ($element_ids as $k_id => $element_id)
+  {
+    $key = strtolower($name[$element_id]) .'-'. $name[$element_id] .'-'. $k_id;
+    $ordered_element_ids[$key] = $element_id;
+  }
+  ksort($ordered_element_ids);
+  return $ordered_element_ids;
+}
+
+/*event handler for menu*/
+function register_default_menubar_blocks( $menu_ref_arr )
+{
+  $menu = & $menu_ref_arr[0];
+  if ($menu->get_id() != 'menubar')
+    return;
+  $menu->register_block( new RegisteredBlock( 'mbLinks', 'Links', 'piwigo'));
+  $menu->register_block( new RegisteredBlock( 'mbCategories', 'Categories', 'piwigo'));
+  $menu->register_block( new RegisteredBlock( 'mbTags', 'Related tags', 'piwigo'));
+  $menu->register_block( new RegisteredBlock( 'mbSpecials', 'special_categories', 'piwigo'));
+  $menu->register_block( new RegisteredBlock( 'mbMenu', 'title_menu', 'piwigo'));
+  $menu->register_block( new RegisteredBlock( 'mbIdentification', 'identification', 'piwigo') );
+}
+
+?>
Index: /tags/2.0.2/include/functions_mail.inc.php
===================================================================
--- /tags/2.0.2/include/functions_mail.inc.php	(revision 3278)
+++ /tags/2.0.2/include/functions_mail.inc.php	(revision 3278)
@@ -0,0 +1,821 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// +-----------------------------------------------------------------------+
+// |                               functions                               |
+// +-----------------------------------------------------------------------+
+
+
+/**
+ * Encodes a string using Q form if required (RFC2045)
+ * mail headers MUST contain only US-ASCII characters
+ */
+function encode_mime_header($str)
+{
+  $x = preg_match_all('/[\000-\010\013\014\016-\037\177-\377]/', $str, $matches);
+  if ($x==0)
+  {
+    return $str;
+  }
+  // Replace every high ascii, control =, ? and _ characters
+  $str = preg_replace('/([\000-\011\013\014\016-\037\075\077\137\177-\377])/e',
+                  "'='.sprintf('%02X', ord('\\1'))", $str);
+
+  // Replace every spaces to _ (more readable than =20)
+  $str = str_replace(" ", "_", $str);
+
+  global $lang_info;
+  return '=?'.get_pwg_charset().'?Q?'.$str.'?=';
+}
+
+/*
+ * Returns the name of the mail sender :
+ *
+ * @return string
+ */
+function get_mail_sender_name()
+{
+  global $conf;
+
+  return (empty($conf['mail_sender_name']) ? $conf['gallery_title'] : $conf['mail_sender_name']);
+}
+
+/*
+ * Returns an array of mail configuration parameters :
+ *
+ * - mail_options: see $conf['mail_options']
+ * - send_bcc_mail_webmaster: see $conf['send_bcc_mail_webmaster']
+ * - email_webmaster: mail corresponding to $conf['webmaster_id']
+ * - formated_email_webmaster: the name of webmaster is $conf['gallery_title']
+ * - text_footer: Piwigo and version
+ *
+ * @return array
+ */
+function get_mail_configuration()
+{
+  global $conf;
+
+  $conf_mail = array(
+    'mail_options' => $conf['mail_options'],
+    'send_bcc_mail_webmaster' => $conf['send_bcc_mail_webmaster'],
+    'default_email_format' => $conf['default_email_format'],
+    'use_smtp' => !empty($conf['smtp_host']),
+    'smtp_host' => $conf['smtp_host'],
+    'smtp_user' => $conf['smtp_user'],
+    'smtp_password' => $conf['smtp_password']
+    );
+
+  // we have webmaster id among user list, what's his email address ?
+  $conf_mail['email_webmaster'] = get_webmaster_mail_address();
+
+  // name of the webmaster is the title of the gallery
+  $conf_mail['formated_email_webmaster'] =
+    format_email(get_mail_sender_name(), $conf_mail['email_webmaster']);
+
+  $conf_mail['boundary_key'] = generate_key(32);
+
+  return $conf_mail;
+}
+
+/**
+ * Returns an email address with an associated real name
+ *
+ * @param string name
+ * @param string email
+ */
+function format_email($name, $email)
+{
+  // Spring cleaning
+  $cvt_email = trim(preg_replace('#[\n\r]+#s', '', $email));
+  $cvt_name = trim(preg_replace('#[\n\r]+#s', '', $name));
+
+  if ($cvt_name!="")
+  {
+    $cvt_name = encode_mime_header(
+              '"'
+              .addcslashes($cvt_name,'"')
+              .'"');
+    $cvt_name .= ' ';
+  }
+
+  if (strpos($cvt_email, '<') === false)
+  {
+    return $cvt_name.'<'.$cvt_email.'>';
+  }
+  else
+  {
+    return $cvt_name.$cvt_email;
+  }
+}
+
+/**
+ * Returns an email address list with minimal email string
+ *
+ * @param string with email list (email separated by comma)
+ */
+function get_strict_email_list($email_list)
+{
+  $result = array();
+  $list = explode(',', $email_list);
+  foreach ($list as $email)
+  {
+    if (strpos($email, '<') !== false)
+    {
+       $email = preg_replace('/.*<(.*)>.*/i', '$1', $email);
+    }
+    $result[] = trim($email);
+  }
+
+  return implode(',', $result);
+}
+
+/**
+ * Returns an completed array template/theme
+ * completed with get_default_template()
+ *
+ * @params:
+ *   - args: incompleted array of template/theme
+ *       o template: template to use [default get_default_template()]
+ *       o theme: template to use [default get_default_template()]
+ */
+function get_array_template_theme($args = array())
+{
+  global $conf;
+
+  $res = array();
+
+  if (empty($args['template']) or empty($args['theme']))
+  {
+    list($res['template'], $res['theme']) = explode('/', get_default_template());
+  }
+
+  if (!empty($args['template']))
+  {
+    $res['template'] = $args['template'];
+  }
+
+  if (!empty($args['theme']))
+  {
+    $res['theme'] = $args['theme'];
+  }
+
+  return $res;
+}
+
+/**
+ * Return an new mail template
+ *
+ * @params:
+ *   - email_format: mail format
+ *   - args: function params of mail function:
+ *       o template: template to use [default get_default_template()]
+ *       o theme: template to use [default get_default_template()]
+ */
+function & get_mail_template($email_format, $args = array())
+{
+  $args = get_array_template_theme($args);
+
+  $mail_template = new Template(PHPWG_ROOT_PATH.'template/'.$args['template'], $args['theme']);
+  $mail_template->set_template_dir(PHPWG_ROOT_PATH.'template/'.$args['template'].'/mail/'.$email_format);
+  return $mail_template;
+}
+
+/**
+ * Return string email format (html or not)
+ *
+ * @param string format
+ */
+function get_str_email_format($is_html)
+{
+  return ($is_html ? 'text/html' : 'text/plain');
+}
+
+/*
+ * Switch language to param language
+ * All entries are push on language stack
+ *
+ * @param string language
+ */
+function switch_lang_to($language)
+{
+  global $switch_lang, $user, $lang, $lang_info;
+
+  if (count($switch_lang['stack']) == 0)
+  {
+    $prev_language = $user['language'];
+  }
+  else
+  {
+    $prev_language = end($switch_lang['stack']);
+  }
+
+  $switch_lang['stack'][] = $language;
+
+  if ($prev_language != $language)
+  {
+    if (!isset($switch_lang['language'][$prev_language]))
+    {
+      $switch_lang[$prev_language]['lang_info'] = $lang_info;
+      $switch_lang[$prev_language]['lang'] = $lang;
+    }
+
+    if (!isset($switch_lang['language'][$language]))
+    {
+      // Re-Init language arrays
+      $lang_info = array();
+      $lang  = array();
+
+      // language files
+      load_language('common.lang', '', array('language'=>$language) );
+      // No test admin because script is checked admin (user selected no)
+      // Translations are in admin file too
+      load_language('admin.lang', '', array('language'=>$language) );
+      trigger_action('loading_lang');
+      load_language('local.lang', '', array('language'=>$language, 'no_fallback'=>true));
+
+      $switch_lang[$language]['lang_info'] = $lang_info;
+      $switch_lang[$language]['lang'] = $lang;
+    }
+    else
+    {
+      $lang_info = $switch_lang[$language]['lang_info'];
+      $lang = $switch_lang[$language]['lang'];
+    }
+
+    $user['language'] = $language;
+  }
+}
+
+/*
+ * Switch back language pushed with switch_lang_to function
+ *
+ * @param: none
+ */
+function switch_lang_back()
+{
+  global $switch_lang, $user, $lang, $lang_info;
+
+  $last_language = array_pop($switch_lang['stack']);
+
+  if (count($switch_lang['stack']) > 0)
+  {
+    $language = end($switch_lang['stack']);
+  }
+  else
+  {
+    $language = $user['language'];
+  }
+
+  if ($last_language != $language)
+  {
+    if (!isset($switch_lang['language'][$language]))
+    {
+      $lang_info = $switch_lang[$language]['lang_info'];
+      $lang = $switch_lang[$language]['lang'];
+    }
+    $user['language'] = $language;
+  }
+}
+
+/**
+ * Returns email of all administrator
+ *
+ * @return string
+ */
+/*
+ * send en notification email to all administrators
+ * if a administrator is doing action,
+ * he's be removed to email list
+ *
+ * @param:
+ *   - keyargs_subject: mail subject on l10n_args format
+ *   - keyargs_content: mail content on l10n_args format
+ *
+ * @return boolean (Ok or not)
+ */
+function pwg_mail_notification_admins($keyargs_subject, $keyargs_content)
+{
+  // Check arguments
+  if
+    (
+      empty($keyargs_subject) or
+      empty($keyargs_content)
+    )
+  {
+    return false;
+  }
+
+  global $conf, $user;
+  $return = true;
+
+  $admins = array();
+
+  $query = '
+select
+  U.'.$conf['user_fields']['username'].' as username,
+  U.'.$conf['user_fields']['email'].' as mail_address
+from
+  '.USERS_TABLE.' as U,
+  '.USER_INFOS_TABLE.' as I
+where
+  I.user_id =  U.'.$conf['user_fields']['id'].' and
+  I.status in (\'webmaster\',  \'admin\') and
+  I.adviser = \'false\' and
+  '.$conf['user_fields']['email'].' is not null and
+  I.user_id <> '.$user['id'].'
+order by
+  username
+';
+
+  $datas = pwg_query($query);
+  if (!empty($datas))
+  {
+    while ($admin = mysql_fetch_array($datas))
+    {
+      if (!empty($admin['mail_address']))
+      {
+        array_push($admins, format_email($admin['username'], $admin['mail_address']));
+      }
+    }
+  }
+
+  if (count($admins) > 0)
+  {
+    $keyargs_content_admin_info = array
+    (
+      get_l10n_args('Connected user: %s', $user['username']),
+      get_l10n_args('IP: %s', $_SERVER['REMOTE_ADDR']),
+      get_l10n_args('Browser: %s', $_SERVER['HTTP_USER_AGENT'])
+    );
+
+    switch_lang_to(get_default_language());
+
+    $return = pwg_mail
+    (
+      '',
+      array
+      (
+        'Bcc' => $admins,
+        'subject' => '['.$conf['gallery_title'].'] '.l10n_args($keyargs_subject),
+        'content' =>
+           l10n_args($keyargs_content)."\n\n"
+          .l10n_args($keyargs_content_admin_info)."\n",
+        'content_format' => 'text/plain'
+      )
+    ) and $return;
+
+    switch_lang_back();
+  }
+
+  return $return;
+}
+
+/*
+ * send en email to user's group
+ *
+ * @param:
+ *   - group_id: mail are sent to group with this Id
+ *   - email_format: mail format
+ *   - keyargs_subject: mail subject on l10n_args format
+ *   - dirname: short name of directory including template
+ *   - tpl_shortname: short template name without extension
+ *   - assign_vars: array used to assign_vars to mail template
+ *   - language_selected: send mail only to user with this selected language
+ *
+ * @return boolean (Ok or not)
+ */
+function pwg_mail_group(
+  $group_id, $email_format, $keyargs_subject,
+  $tpl_shortname,
+  $assign_vars = array(), $language_selected = '')
+{
+  // Check arguments
+  if
+    (
+      empty($group_id) or
+      empty($email_format) or
+      empty($keyargs_subject) or
+      empty($tpl_shortname)
+    )
+  {
+    return false;
+  }
+
+  global $conf;
+  $return = true;
+
+  $query = '
+SELECT
+  distinct language, template
+FROM
+  '.USER_GROUP_TABLE.' as ug
+  INNER JOIN '.USERS_TABLE.' as u  ON '.$conf['user_fields']['id'].' = ug.user_id
+  INNER JOIN '.USER_INFOS_TABLE.' as ui  ON ui.user_id = ug.user_id
+WHERE
+        '.$conf['user_fields']['email'].' IS NOT NULL
+    AND group_id = '.$group_id;
+
+  if (!empty($language_selected))
+  {
+    $query .= '
+    AND language = \''.$language_selected.'\'';
+  }
+
+    $query .= '
+;';
+
+  $result = pwg_query($query);
+
+  if (mysql_num_rows($result) > 0)
+  {
+    $list = array();
+    while ($row = mysql_fetch_array($result))
+    {
+      $row['template_theme'] = $row['template'];
+      list($row['template'], $row['theme']) = explode('/', $row['template_theme']);
+      $list[] = $row;
+    }
+
+    foreach ($list as $elem)
+    {
+      $query = '
+SELECT
+  u.'.$conf['user_fields']['username'].' as username,
+  u.'.$conf['user_fields']['email'].' as mail_address
+FROM
+  '.USER_GROUP_TABLE.' as ug
+  INNER JOIN '.USERS_TABLE.' as u  ON '.$conf['user_fields']['id'].' = ug.user_id
+  INNER JOIN '.USER_INFOS_TABLE.' as ui  ON ui.user_id = ug.user_id
+WHERE
+        '.$conf['user_fields']['email'].' IS NOT NULL
+    AND group_id = '.$group_id.'
+    AND language = \''.$elem['language'].'\'
+    AND template = \''.$elem['template_theme'].'\'
+;';
+
+      $result = pwg_query($query);
+
+      if (mysql_num_rows($result) > 0)
+      {
+        $Bcc = array();
+        while ($row = mysql_fetch_array($result))
+        {
+          if (!empty($row['mail_address']))
+          {
+            array_push($Bcc, format_email($row['username'], $row['mail_address']));
+          }
+        }
+
+        if (count($Bcc) > 0)
+        {
+          switch_lang_to($elem['language']);
+
+          $mail_template = get_mail_template($email_format, $elem);
+          $mail_template->set_filename($tpl_shortname, $tpl_shortname.'.tpl');
+
+          $mail_template->assign(
+            trigger_event('mail_group_assign_vars', $assign_vars));
+
+          $return = pwg_mail
+          (
+            '',
+            array
+            (
+              'Bcc' => $Bcc,
+              'subject' => l10n_args($keyargs_subject),
+              'email_format' => $email_format,
+              'content' => $mail_template->parse($tpl_shortname, true),
+              'content_format' => $email_format,
+              'template' => $elem['template'],
+              'theme' => $elem['theme']
+            )
+          ) and $return;
+
+          switch_lang_back();
+        }
+      }
+    }
+  }
+
+  return $return;
+}
+
+/*
+ * sends an email, using Piwigo specific informations
+ *
+ * @param:
+ *   - to: receiver(s) of the mail (list separated by comma).
+ *   - args: function params of mail function:
+ *       o from: sender [default value webmaster email]
+ *       o Cc: array of carbon copy receivers of the mail. [default value empty]
+ *       o Bcc: array of blind carbon copy receivers of the mail. [default value empty]
+ *       o subject  [default value 'Piwigo']
+ *       o content: content of mail    [default value '']
+ *       o content_format: format of mail content  [default value 'text/plain']
+ *       o email_format: global mail format  [default value $conf_mail['default_email_format']]
+ *       o template: template to use [default get_default_template()]
+ *       o theme: template to use [default get_default_template()]
+ *
+ * @return boolean (Ok or not)
+ */
+function pwg_mail($to, $args = array())
+{
+  global $conf, $conf_mail, $lang_info, $page;
+
+  if (empty($to) and empty($args['Cc']) and empty($args['Bcc']))
+  {
+    return true;
+  }
+
+  if (!isset($conf_mail))
+  {
+    $conf_mail = get_mail_configuration();
+  }
+
+  if (empty($args['email_format']))
+  {
+    $args['email_format'] = $conf_mail['default_email_format'];
+  }
+
+  // Compute root_path in order have complete path
+  if ($args['email_format'] == 'text/html')
+  {
+    set_make_full_url();
+  }
+
+  if (empty($args['from']))
+  {
+    $args['from'] = $conf_mail['formated_email_webmaster'];
+  }
+  else
+  {
+    $args['from'] = format_email('', $args['from']);
+  }
+
+  if (empty($args['subject']))
+  {
+    $args['subject'] = 'Piwigo';
+  }
+  // Spring cleaning
+  $cvt_subject = trim(preg_replace('#[\n\r]+#s', '', $args['subject']));
+  // Ascii convertion
+  $cvt_subject = encode_mime_header($cvt_subject);
+
+  if (!isset($args['content']))
+  {
+    $args['content'] = '';
+  }
+
+  if (empty($args['content_format']))
+  {
+    $args['content_format'] = 'text/plain';
+  }
+
+  if ($conf_mail['send_bcc_mail_webmaster'])
+  {
+    $args['Bcc'][] = $conf_mail['formated_email_webmaster'];
+  }
+
+  if (($args['content_format'] == 'text/html') and ($args['email_format'] == 'text/plain'))
+  {
+    // Todo find function to convert html text to plain text
+    return false;
+  }
+
+  $args = array_merge($args, get_array_template_theme($args));
+
+  $headers = 'From: '.$args['from']."\n";
+  $headers.= 'Reply-To: '.$args['from']."\n";
+  if (empty($to))
+  {
+    $headers.= 'To: undisclosed-recipients: ;'."\n";
+  }
+  else
+  {
+    $headers.= 'To: '.$to."\n";
+  }
+
+  if (!empty($args['Cc']))
+  {
+    $headers.= 'Cc: '.implode(',', $args['Cc'])."\n";
+  }
+
+  if (!empty($args['Bcc']))
+  {
+    $headers.= 'Bcc: '.implode(',', $args['Bcc'])."\n";
+  }
+
+  $headers.= 'Content-Type: multipart/alternative;'."\n";
+  $headers.= '  boundary="---='.$conf_mail['boundary_key'].'";'."\n";
+  $headers.= '  reply-type=original'."\n";
+  $headers.= 'MIME-Version: 1.0'."\n";
+  $headers.= 'X-Mailer: Piwigo Mailer'."\n";
+
+  $content = '';
+
+  // key compose of indexes witch allow ti cache mail data
+  $cache_key = $args['email_format'].'-'.$lang_info['code'].'-'.$args['template'].'-'.$args['theme'];
+
+  if (!isset($conf_mail[$cache_key]))
+  {
+    if (!isset($mail_template))
+    {
+      $mail_template = get_mail_template($args['email_format']);
+    }
+
+    $mail_template->set_filename('mail_header', 'header.tpl');
+    $mail_template->set_filename('mail_footer', 'footer.tpl');
+
+    $mail_template->assign(
+      array(
+        //Header
+        'BOUNDARY_KEY' => $conf_mail['boundary_key'],
+        'CONTENT_TYPE' => $args['email_format'],
+        'CONTENT_ENCODING' => get_pwg_charset(),
+
+        // Footer
+        'GALLERY_URL' =>
+          isset($page['gallery_url']) ?
+                $page['gallery_url'] : $conf['gallery_url'],
+        'GALLERY_TITLE' =>
+          isset($page['gallery_title']) ?
+                $page['gallery_title'] : $conf['gallery_title'],
+        'VERSION' => $conf['show_version'] ? PHPWG_VERSION : '',
+        'PHPWG_URL' => PHPWG_URL,
+
+        'TITLE_MAIL' => urlencode(l10n('title_send_mail')),
+        'MAIL' => get_webmaster_mail_address()
+        ));
+
+    if ($args['email_format'] == 'text/html')
+    {
+      if (is_file($mail_template->get_template_dir().'/global-mail-css.tpl'))
+      {
+        $mail_template->set_filename('css', 'global-mail-css.tpl');
+        $mail_template->assign_var_from_handle('GLOBAL_MAIL_CSS', 'css');
+      }
+
+      $root_abs_path = dirname(dirname(__FILE__));
+
+      $file = $root_abs_path.'/template/'.$args['template'].'/theme/'.$args['theme'].'/mail-css.tpl';
+      if (is_file($file))
+      {
+        $mail_template->set_filename('css', $file);
+        $mail_template->assign_var_from_handle('MAIL_CSS', 'css');
+      }
+
+      $file = $root_abs_path.'/template-common/local-mail-css.tpl';
+      if (is_file($file))
+      {
+        $mail_template->set_filename('css', $file);
+        $mail_template->assign_var_from_handle('LOCAL_MAIL_CSS', 'css');
+      }
+    }
+
+    // what are displayed on the header of each mail ?
+    $conf_mail[$cache_key]['header'] =
+      $mail_template->parse('mail_header', true);
+
+    // what are displayed on the footer of each mail ?
+    $conf_mail[$cache_key]['footer'] =
+      $mail_template->parse('mail_footer', true);
+  }
+
+  // Header
+  $content.= $conf_mail[$cache_key]['header'];
+
+  // Content
+  if (($args['content_format'] == 'text/plain') and ($args['email_format'] == 'text/html'))
+  {
+    $content.= '<p>'.
+                nl2br(
+                  preg_replace("/(http:\/\/)([^\s,]*)/i",
+                               "<a href='$1$2' class='thumblnk'>$1$2</a>",
+                               htmlspecialchars($args['content']))).
+                '</p>';
+  }
+  else
+  {
+    $content.= $args['content'];
+  }
+
+  // Footer
+  $content.= $conf_mail[$cache_key]['footer'];
+
+  // Close boundary
+  $content.= "\n".'-----='.$conf_mail['boundary_key'].'--'."\n";
+
+   // Undo Compute root_path in order have complete path
+  if ($args['email_format'] == 'text/html')
+  {
+    unset_make_full_url();
+  }
+
+  return
+    trigger_event('send_mail',
+      false, /* Result */
+      trigger_event('send_mail_to', get_strict_email_list($to)),
+      trigger_event('send_mail_subject', $cvt_subject),
+      trigger_event('send_mail_content', $content),
+      trigger_event('send_mail_headers', $headers),
+      $args
+    );
+}
+
+/*
+ * pwg sendmail
+ *
+ * @param:
+ *   - result of other sendmail
+ *   - to: Receiver or receiver(s) of the mail.
+ *   - subject  [default value 'Piwigo']
+ *   - content: content of mail
+ *   - headers: headers of mail
+ *
+ * @return boolean (Ok or not)
+ */
+function pwg_send_mail($result, $to, $subject, $content, $headers)
+{
+  if (!$result)
+  {
+    global $conf_mail;
+
+    if ($conf_mail['use_smtp'])
+    {
+      include_once( PHPWG_ROOT_PATH.'include/class_smtp_mail.inc.php' );
+      $smtp_mail = new smtp_mail(
+        $conf_mail['smtp_host'], $conf_mail['smtp_user'], $conf_mail['smtp_password'],
+        $conf_mail['email_webmaster']);
+      return $smtp_mail->mail($to, $subject, $content, $headers);
+    }
+    else
+    {
+      if ($conf_mail['mail_options'])
+      {
+        $options = '-f '.$conf_mail['email_webmaster'];
+        return mail($to, $subject, $content, $headers, $options);
+      }
+      else
+      {
+        return mail($to, $subject, $content, $headers);
+      }
+    }
+  }
+  else
+  {
+    return $result;
+  }
+}
+
+/*Testing block*/
+/*function pwg_send_mail_test($result, $to, $subject, $content, $headers, $args)
+{
+    global $conf, $user, $lang_info;
+    $dir = $conf['local_data_dir'].'/tmp';
+    if ( mkgetdir( $dir,  MKGETDIR_DEFAULT&~MKGETDIR_DIE_ON_ERROR) )
+    {
+      $filename = $dir.'/mail.'.$user['username'].'.'.$lang_info['code'].'.'.$args['template'].'.'.$args['theme'];
+      if ($args['content_format'] == 'text/plain')
+      {
+        $filename .= '.txt';
+      }
+      else
+      {
+        $filename .= '.html';
+      }
+      $file = fopen($filename, 'w+');
+      fwrite($file, $to ."\n");
+      fwrite($file, $subject ."\n");
+      fwrite($file, $headers);
+      fwrite($file, $content);
+      fclose($file);
+    }
+    return $result;
+}
+add_event_handler('send_mail', 'pwg_send_mail_test', EVENT_HANDLER_PRIORITY_NEUTRAL+10, 6);*/
+
+
+add_event_handler('send_mail', 'pwg_send_mail', EVENT_HANDLER_PRIORITY_NEUTRAL, 5);
+trigger_action('functions_mail_included');
+
+?>
Index: /tags/2.0.2/include/functions_metadata.inc.php
===================================================================
--- /tags/2.0.2/include/functions_metadata.inc.php	(revision 3278)
+++ /tags/2.0.2/include/functions_metadata.inc.php	(revision 3278)
@@ -0,0 +1,142 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+/**
+ * returns informations from IPTC metadata, mapping is done at the beginning
+ * of the function
+ *
+ * @param string $filename
+ * @return array
+ */
+function get_iptc_data($filename, $map)
+{
+  $result = array();
+
+  $imginfo = array();
+  if (false == @getimagesize($filename, $imginfo) )
+  {
+    return $result;
+  }
+
+  if (isset($imginfo['APP13']))
+  {
+    $iptc = iptcparse($imginfo['APP13']);
+    if (is_array($iptc))
+    {
+      $rmap = array_flip($map);
+      foreach (array_keys($rmap) as $iptc_key)
+      {
+        if (isset($iptc[$iptc_key][0]))
+        {
+          if ($iptc_key == '2#025')
+          {
+            $value = implode(',',
+                             array_map('clean_iptc_value',$iptc[$iptc_key]));
+          }
+          else
+          {
+            $value = clean_iptc_value($iptc[$iptc_key][0]);
+          }
+
+          foreach (array_keys($map, $iptc_key) as $pwg_key)
+          {
+            $result[$pwg_key] = $value;
+          }
+        }
+      }
+    }
+  }
+  return $result;
+}
+
+/**
+ * return a cleaned IPTC value
+ *
+ * @param string value
+ * @return string
+ */
+function clean_iptc_value($value)
+{
+  // strip leading zeros (weird Kodak Scanner software)
+  while ( isset($value[0]) and $value[0] == chr(0))
+  {
+    $value = substr($value, 1);
+  }
+  // remove binary nulls
+  $value = str_replace(chr(0x00), ' ', $value);
+
+  if ( preg_match('/[\x80-\xff]/', $value) )
+  {
+    // apparently mac uses some MacRoman crap encoding. I don't know
+    // how to detect it so a plugin should do the trick.
+    $value = trigger_event('clean_iptc_value', $value);
+    $is_utf8 = seems_utf8($value);
+    $value = convert_charset( $value,
+      $is_utf8 ? 'utf-8' : 'iso-8859-1',
+      get_pwg_charset() );
+  }
+  return $value;
+}
+
+/**
+ * returns informations from EXIF metadata, mapping is done at the beginning
+ * of the function
+ *
+ * @param string $filename
+ * @return array
+ */
+function get_exif_data($filename, $map)
+{
+  $result = array();
+
+  if (!function_exists('read_exif_data'))
+  {
+    die('Exif extension not available, admin should disable exif use');
+  }
+
+  // Read EXIF data
+  if ($exif = @read_exif_data($filename))
+  {
+    foreach ($map as $key => $field)
+    {
+      if (strpos($field, ';') === false)
+      {
+        if (isset($exif[$field]))
+        {
+          $result[$key] = $exif[$field];
+        }
+      }
+      else
+      {
+        $tokens = explode(';', $field);
+        if (isset($exif[$tokens[0]][$tokens[1]]))
+        {
+          $result[$key] = $exif[$tokens[0]][$tokens[1]];
+        }
+      }
+    }
+  }
+
+  return $result;
+}
+?>
Index: /tags/2.0.2/include/functions_notification.inc.php
===================================================================
--- /tags/2.0.2/include/functions_notification.inc.php	(revision 3278)
+++ /tags/2.0.2/include/functions_notification.inc.php	(revision 3278)
@@ -0,0 +1,610 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// +-----------------------------------------------------------------------+
+// |                               functions                               |
+// +-----------------------------------------------------------------------+
+
+/*
+ * get standard sql where in order to
+ * restict an filter caregories and images
+ *
+ * IMAGE_CATEGORY_TABLE muste named ic in the query
+ *
+ * @param none
+ *
+ * @return string sql where
+ */
+function get_std_sql_where_restrict_filter($prefix_condition, $img_field='ic.image_id', $force_one_condition = false)
+{
+  return get_sql_condition_FandF
+          (
+            array
+              (
+                'forbidden_categories' => 'ic.category_id',
+                'visible_categories' => 'ic.category_id',
+                'visible_images' => $img_field
+              ),
+            $prefix_condition,
+            $force_one_condition
+          );
+}
+
+/*
+ * Execute custom notification query
+ *
+ * @param string action ('count' or 'info')
+ * @param string type of query ('new_comments', 'unvalidated_comments', 'new_elements', 'updated_categories', 'new_users', 'waiting_elements')
+ * @param string start (mysql datetime format)
+ * @param string end (mysql datetime format)
+ *
+ * @return integer for action count
+ *         array for info
+ */
+function custom_notification_query($action, $type, $start, $end)
+{
+  global $user;
+
+  switch($type)
+  {
+    case 'new_comments':
+      $query = '
+  FROM '.COMMENTS_TABLE.' AS c
+     , '.IMAGE_CATEGORY_TABLE.' AS ic
+  WHERE c.image_id = ic.image_id
+    AND c.validation_date > \''.$start.'\'
+    AND c.validation_date <= \''.$end.'\'
+      '.get_std_sql_where_restrict_filter('AND').'
+;';
+      break;
+    case 'unvalidated_comments':
+      $query = '
+  FROM '.COMMENTS_TABLE.'
+  WHERE date> \''.$start.'\' AND date <= \''.$end.'\'
+    AND validated = \'false\'
+;';
+      break;
+    case 'new_elements':
+      $query = '
+  FROM '.IMAGES_TABLE.' INNER JOIN '.IMAGE_CATEGORY_TABLE.' AS ic ON image_id = id
+  WHERE date_available > \''.$start.'\'
+    AND date_available <= \''.$end.'\'
+      '.get_std_sql_where_restrict_filter('AND', 'id').'
+;';
+      break;
+    case 'updated_categories':
+      $query = '
+  FROM '.IMAGES_TABLE.' INNER JOIN '.IMAGE_CATEGORY_TABLE.' AS ic ON image_id = id
+  WHERE date_available > \''.$start.'\'
+    AND date_available <= \''.$end.'\'
+      '.get_std_sql_where_restrict_filter('AND', 'id').'
+;';
+      break;
+    case 'new_users':
+      $query = '
+  FROM '.USER_INFOS_TABLE.'
+  WHERE registration_date > \''.$start.'\'
+    AND registration_date <= \''.$end.'\'
+;';
+      break;
+    case 'waiting_elements':
+      $query = '
+  FROM '.WAITING_TABLE.'
+  WHERE validated = \'false\'
+;';
+      break;
+    default:
+      // stop this function and return nothing
+      return;
+      break;
+  }
+
+  switch($action)
+  {
+    case 'count':
+      switch($type)
+      {
+        case 'new_comments':
+          $field_id = 'c.id';
+          break;
+        case 'unvalidated_comments':
+          $field_id = 'id';
+          break;
+        case 'new_elements':
+          $field_id = 'image_id';
+          break;
+        case 'updated_categories':
+          $field_id = 'category_id';
+          break;
+        case 'new_users':
+          $field_id = 'user_id';
+          break;
+        case 'waiting_elements':
+          $field_id = 'id';
+          break;
+    }
+    $query = 'SELECT count(distinct '.$field_id.') as CountId
+'.$query;
+    list($count) = mysql_fetch_array(pwg_query($query));
+    return $count;
+
+    break;
+    case 'info':
+      switch($type)
+      {
+        case 'new_comments':
+          $fields = array('c.id');
+          break;
+        case 'unvalidated_comments':
+          $fields = array('id');
+          break;
+        case 'new_elements':
+          $fields = array('image_id');
+          break;
+        case 'updated_categories':
+          $fields = array('category_id');
+          break;
+        case 'new_users':
+          $fields = array('user_id');
+          break;
+        case 'waiting_elements':
+          $fields = array('id');
+          break;
+      }
+
+    $query = 'SELECT distinct '.implode(', ', $fields).'
+'.$query;
+    $result = pwg_query($query);
+
+    $infos = array();
+
+    while ($row = mysql_fetch_array($result))
+    {
+      array_push($infos, $row);
+    }
+
+    return $infos;
+
+    break;
+  }
+
+  //return is done on previous switch($action)
+}
+
+/**
+ * new comments between two dates, according to authorized categories
+ *
+ * @param string start (mysql datetime format)
+ * @param string end (mysql datetime format)
+ * @param string forbidden categories (comma separated)
+ * @return count comment ids
+ */
+function nb_new_comments($start, $end)
+{
+  return custom_notification_query('count', 'new_comments', $start, $end);
+}
+
+/**
+ * new comments between two dates, according to authorized categories
+ *
+ * @param string start (mysql datetime format)
+ * @param string end (mysql datetime format)
+ * @param string forbidden categories (comma separated)
+ * @return array comment ids
+ */
+function new_comments($start, $end)
+{
+  return custom_notification_query('info', 'new_comments', $start, $end);
+}
+
+/**
+ * unvalidated at a precise date
+ *
+ * Comments that are registered and not validated yet on a precise date
+ *
+ * @param string start (mysql datetime format)
+ * @param string end (mysql datetime format)
+ * @return count comment ids
+ */
+function nb_unvalidated_comments($start, $end)
+{
+  return custom_notification_query('count', 'unvalidated_comments', $start, $end);
+}
+
+
+/**
+ * new elements between two dates, according to authorized categories
+ *
+ * @param string start (mysql datetime format)
+ * @param string end (mysql datetime format)
+ * @param string forbidden categories (comma separated)
+ * @return count element ids
+ */
+function nb_new_elements($start, $end)
+{
+  return custom_notification_query('count', 'new_elements', $start, $end);
+}
+
+/**
+ * new elements between two dates, according to authorized categories
+ *
+ * @param string start (mysql datetime format)
+ * @param string end (mysql datetime format)
+ * @param string forbidden categories (comma separated)
+ * @return array element ids
+ */
+function new_elements($start, $end)
+{
+  return custom_notification_query('info', 'new_elements', $start, $end);
+}
+
+/**
+ * updated categories between two dates, according to authorized categories
+ *
+ * @param string start (mysql datetime format)
+ * @param string end (mysql datetime format)
+ * @param string forbidden categories (comma separated)
+ * @return count element ids
+ */
+function nb_updated_categories($start, $end)
+{
+  return custom_notification_query('count', 'updated_categories', $start, $end);
+}
+
+/**
+ * updated categories between two dates, according to authorized categories
+ *
+ * @param string start (mysql datetime format)
+ * @param string end (mysql datetime format)
+ * @param string forbidden categories (comma separated)
+ * @return array element ids
+ */
+function updated_categories($start, $end)
+{
+  return custom_notification_query('info', 'updated_categories', $start, $end);
+}
+
+/**
+ * new registered users between two dates
+ *
+ * @param string start (mysql datetime format)
+ * @param string end (mysql datetime format)
+ * @return count user ids
+ */
+function nb_new_users($start, $end)
+{
+  return custom_notification_query('count', 'new_users', $start, $end);
+}
+
+/**
+ * new registered users between two dates
+ *
+ * @param string start (mysql datetime format)
+ * @param string end (mysql datetime format)
+ * @return array user ids
+ */
+function new_users($start, $end)
+{
+  return custom_notification_query('info', 'new_users', $start, $end);
+}
+
+/**
+ * currently waiting pictures
+ *
+ * @return count waiting ids
+ */
+function nb_waiting_elements()
+{
+  return custom_notification_query('count', 'waiting_elements', '', '');
+}
+
+/**
+ * currently waiting pictures
+ *
+ * @return array waiting ids
+ */
+function waiting_elements()
+{
+  return custom_notification_query('info', 'waiting_elements', $start, $end);
+}
+
+/**
+ * There are new between two dates ?
+ *
+ * Informations : number of new comments, number of new elements, number of
+ * updated categories. Administrators are also informed about : number of
+ * unvalidated comments, number of new users (TODO : number of unvalidated
+ * elements)
+ *
+ * @param string start date (mysql datetime format)
+ * @param string end date (mysql datetime format)
+ *
+ * @return boolean : true if exist news else false
+ */
+function news_exists($start, $end)
+{
+  return (
+          (nb_new_comments($start, $end) > 0) or
+          (nb_new_elements($start, $end) > 0) or
+          (nb_updated_categories($start, $end) > 0) or
+          ((is_admin()) and (nb_unvalidated_comments($start, $end) > 0)) or
+          ((is_admin()) and (nb_new_users($start, $end) > 0)) or
+          ((is_admin()) and (nb_waiting_elements() > 0))
+        );
+}
+
+/**
+ * Formats a news line and adds it to the array (e.g. '5 new elements')
+ */
+function add_news_line(&$news, $count, $singular_fmt_key, $plural_fmt_key, $url='', $add_url=false)
+{
+  if ($count > 0)
+  {
+    $line = l10n_dec($singular_fmt_key, $plural_fmt_key, $count);
+    if ($add_url and !empty($url) )
+    {
+      $line = '<a href="'.$url.'">'.$line.'</a>';
+    }
+    array_push($news, $line);
+  }
+}
+
+/**
+ * What's new between two dates ?
+ *
+ * Informations : number of new comments, number of new elements, number of
+ * updated categories. Administrators are also informed about : number of
+ * unvalidated comments, number of new users (TODO : number of unvalidated
+ * elements)
+ *
+ * @param string start date (mysql datetime format)
+ * @param string end date (mysql datetime format)
+ * @param bool exclude_img_cats if true, no info about new images/categories
+ * @param bool add_url add html A link around news
+ *
+ * @return array of news
+ */
+function news($start, $end, $exclude_img_cats=false, $add_url=false)
+{
+  $news = array();
+
+  if (!$exclude_img_cats)
+  {
+    add_news_line( $news,
+      nb_new_elements($start, $end), '%d new element', '%d new elements',
+      make_index_url(array('section'=>'recent_pics')), $add_url );
+  }
+
+  if (!$exclude_img_cats)
+  {
+    add_news_line( $news,
+      nb_updated_categories($start, $end), '%d category updated', '%d categories updated',
+      make_index_url(array('section'=>'recent_cats')), $add_url );
+  }
+
+  add_news_line( $news,
+      nb_new_comments($start, $end), '%d new comment', '%d new comments',
+      get_root_url().'comments.php', $add_url );
+
+  if (is_admin())
+  {
+    add_news_line( $news,
+        nb_unvalidated_comments($start, $end), '%d comment to validate', '%d comments to validate',
+        get_root_url().'admin.php?page=comments', $add_url );
+
+    add_news_line( $news,
+        nb_new_users($start, $end), '%d new user', '%d new users',
+        get_root_url().'admin.php?page=user_list', $add_url );
+
+    add_news_line( $news,
+        nb_waiting_elements(), '%d waiting element', '%d waiting elements',
+        get_root_url().'admin.php?page=upload', $add_url );
+  }
+
+  return $news;
+}
+
+/**
+ * returns information about recently published elements grouped by post date
+ * @param int max_dates maximum returned number of recent dates
+ * @param int max_elements maximum returned number of elements per date
+ * @param int max_cats maximum returned number of categories per date
+ */
+function get_recent_post_dates($max_dates, $max_elements, $max_cats)
+{
+  global $conf, $user;
+
+  $where_sql = get_std_sql_where_restrict_filter('WHERE', 'i.id', true);
+
+  $query = '
+SELECT date_available,
+      COUNT(DISTINCT id) nb_elements,
+      COUNT(DISTINCT category_id) nb_cats
+  FROM '.IMAGES_TABLE.' i INNER JOIN '.IMAGE_CATEGORY_TABLE.' AS ic ON id=image_id
+  '.$where_sql.'
+  GROUP BY date_available
+  ORDER BY date_available DESC
+  LIMIT 0,'.$max_dates.'
+;';
+  $result = pwg_query($query);
+  $dates = array();
+  while ($row = mysql_fetch_assoc($result))
+  {
+    array_push($dates, $row);
+  }
+
+  for ($i=0; $i<count($dates); $i++)
+  {
+    if ($max_elements>0)
+    { // get some thumbnails ...
+      $query = '
+SELECT DISTINCT id, path, name, tn_ext, file
+  FROM '.IMAGES_TABLE.' i INNER JOIN '.IMAGE_CATEGORY_TABLE.' AS ic ON id=image_id
+  '.$where_sql.'
+    AND date_available="'.$dates[$i]['date_available'].'"
+    AND tn_ext IS NOT NULL
+  ORDER BY RAND(NOW())
+  LIMIT 0,'.$max_elements.'
+;';
+      $dates[$i]['elements'] = array();
+      $result = pwg_query($query);
+      while ($row = mysql_fetch_assoc($result))
+      {
+        array_push($dates[$i]['elements'], $row);
+      }
+    }
+
+    if ($max_cats>0)
+    {// get some categories ...
+      $query = '
+SELECT DISTINCT c.uppercats, COUNT(DISTINCT i.id) img_count
+  FROM '.IMAGES_TABLE.' i INNER JOIN '.IMAGE_CATEGORY_TABLE.' AS ic ON i.id=image_id
+    INNER JOIN '.CATEGORIES_TABLE.' c ON c.id=category_id
+  '.$where_sql.'
+    AND date_available="'.$dates[$i]['date_available'].'"
+  GROUP BY category_id
+  ORDER BY img_count DESC
+  LIMIT 0,'.$max_cats.'
+;';
+      $dates[$i]['categories'] = array();
+      $result = pwg_query($query);
+      while ($row = mysql_fetch_assoc($result))
+      {
+        array_push($dates[$i]['categories'], $row);
+      }
+    }
+  }
+  return $dates;
+}
+
+/*
+  Call function get_recent_post_dates but
+  the parameters to be passed to the function, as an indexed array.
+
+*/
+function get_recent_post_dates_array($args)
+{
+  return
+    get_recent_post_dates
+    (
+      (empty($args['max_dates']) ? 3 : $args['max_dates']),
+      (empty($args['max_elements']) ? 3 : $args['max_elements']),
+      (empty($args['max_cats']) ? 3 : $args['max_cats'])
+    );
+}
+
+
+/**
+ * returns html description about recently published elements grouped by post date
+ * @param $date_detail: selected date computed by get_recent_post_dates function
+ */
+function get_html_description_recent_post_date($date_detail)
+{
+  global $conf;
+
+  $description = '<ul>';
+
+  $description .=
+        '<li>'
+        .l10n_dec('%d new element', '%d new elements', $date_detail['nb_elements'])
+        .' ('
+        .'<a href="'.make_index_url(array('section'=>'recent_pics')).'">'
+          .l10n('recent_pics_cat').'</a>'
+        .')'
+        .'</li><br/>';
+
+  foreach($date_detail['elements'] as $element)
+  {
+    $tn_src = get_thumbnail_url($element);
+    $description .= '<a href="'.
+                    make_picture_url(array(
+                        'image_id' => $element['id'],
+                        'image_file' => $element['file'],
+                      ))
+                    .'"><img src="'.$tn_src.'"/></a>';
+  }
+  $description .= '...<br/>';
+
+  $description .=
+        '<li>'
+        .l10n_dec('%d category updated', '%d categories updated',
+                  $date_detail['nb_cats'])
+        .'</li>';
+
+  $description .= '<ul>';
+  foreach($date_detail['categories'] as $cat)
+  {
+    $description .=
+          '<li>'
+          .get_cat_display_name_cache($cat['uppercats'])
+          .' ('.
+          l10n_dec('%d new element',
+                   '%d new elements', $cat['img_count']).')'
+          .'</li>';
+  }
+  $description .= '</ul>';
+
+  $description .= '</ul>';
+
+  return $description;
+}
+
+/**
+ * explodes a MySQL datetime format (2005-07-14 23:01:37) in fields "year",
+ * "month", "day", "hour", "minute", "second".
+ *
+ * @param string mysql datetime format
+ * @return array
+ */
+function explode_mysqldt($mysqldt)
+{
+  $date = array();
+  list($date['year'],
+       $date['month'],
+       $date['day'],
+       $date['hour'],
+       $date['minute'],
+       $date['second'])
+    = preg_split('/[-: ]/', $mysqldt);
+
+  return $date;
+}
+
+/**
+ * returns title about recently published elements grouped by post date
+ * @param $date_detail: selected date computed by get_recent_post_dates function
+ */
+function get_title_recent_post_date($date_detail)
+{
+  global $lang;
+
+  $date = $date_detail['date_available'];
+  $exploded_date = explode_mysqldt($date);
+
+  $title = l10n_dec('%d new element', '%d new elements', $date_detail['nb_elements']);
+  $title .= ' ('.$lang['month'][(int)$exploded_date['month']].' '.$exploded_date['day'].')';
+
+  return $title;
+}
+
+?>
Index: /tags/2.0.2/include/functions_picture.inc.php
===================================================================
--- /tags/2.0.2/include/functions_picture.inc.php	(revision 3278)
+++ /tags/2.0.2/include/functions_picture.inc.php	(revision 3278)
@@ -0,0 +1,386 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+/**
+ * @param element_info array containing element information from db;
+ * at least 'id', 'path' should be present
+ */
+function get_element_path($element_info)
+{
+  $path = get_element_location($element_info);
+  if ( !url_is_remote($path) )
+  {
+    $path = PHPWG_ROOT_PATH.$path;
+  }
+  return $path;
+}
+
+/*
+ * @param element_info array containing element information from db;
+ * at least 'id', 'path' should be present
+ */
+function get_element_url($element_info)
+{
+  $url = get_element_location($element_info);
+  if ( !url_is_remote($url) )
+  {
+    $url = embellish_url(get_root_url().$url);
+  }
+  // plugins want another url ?
+  return trigger_event('get_element_url', $url, $element_info);
+}
+
+/**
+ * Returns the relative path of the element with regards to to the root
+ * of PWG (not the current page). This function is not intended to be
+ * called directly from code.
+ * @param element_info array containing element information from db;
+ * at least 'id', 'path' should be present
+ */
+function get_element_location($element_info)
+{
+  // maybe a cached watermark ?
+  return trigger_event('get_element_location',
+    $element_info['path'], $element_info);
+}
+
+
+/**
+ * Returns the PATH to the image to be displayed in the picture page. If the
+ * element is not a picture, then the representative image or the default
+ * mime image. The path can be used in the php script, but not sent to the
+ * browser.
+ * @param element_info array containing element information from db;
+ * at least 'id', 'path', 'representative_ext' should be present
+ */
+function get_image_path($element_info)
+{
+  global $conf;
+  $ext = get_extension($element_info['path']);
+  if (in_array($ext, $conf['picture_ext']))
+  {
+    if (isset($element_info['element_path']) )
+    {
+      return $element_info['element_path'];
+    }
+    return get_element_path($element_info);
+  }
+
+  $path = get_image_location($element_info);
+  if ( !url_is_remote($path) )
+  {
+    $path = PHPWG_ROOT_PATH.$path;
+  }
+  return $path;
+}
+
+/**
+ * Returns the URL of the image to be displayed in the picture page. If the
+ * element is not a picture, then the representative image or the default
+ * mime image. The URL can't be used in the php script, but can be sent to the
+ * browser.
+ * @param element_info array containing element information from db;
+ * at least 'id', 'path', 'representative_ext' should be present
+ */
+function get_image_url($element_info)
+{
+  global $conf;
+  $ext = get_extension($element_info['path']);
+  if (in_array($ext, $conf['picture_ext']))
+  {
+    if (isset($element_info['element_url']) )
+    {
+      return $element_info['element_url'];
+    }
+    return get_element_url($element_info);
+  }
+
+  $url = get_image_location($element_info);
+  if ( !url_is_remote($url) )
+  {
+    $url = embellish_url(get_root_url().$url);
+  }
+  return $url;
+}
+
+/**
+ * Returns the relative path of the image (element/representative/mimetype)
+ * with regards to the root of PWG (not the current page). This function
+ * is not intended to be called directly from code.
+ * @param element_info array containing element information from db;
+ * at least 'id', 'path', 'representative_ext' should be present
+ */
+function get_image_location($element_info)
+{
+    if (isset($element_info['representative_ext'])
+          and $element_info['representative_ext'] != '')
+    {
+      $pi = pathinfo($element_info['path']);
+      $file_wo_ext = get_filename_wo_extension($pi['basename']);
+      $path =
+        $pi['dirname'].'/pwg_representative/'
+        .$file_wo_ext.'.'.$element_info['representative_ext'];
+    }
+    else
+    {
+      $ext = get_extension($element_info['path']);
+      $path = get_themeconf('mime_icon_dir');
+      $path.= strtolower($ext).'.png';
+      if ( !file_exists(PHPWG_ROOT_PATH.$path)
+          and !empty($element_info['tn_ext']) )
+      {
+        $path = get_thumbnail_location($element_info);
+      }
+    }
+
+  // plugins want another location ?
+  return trigger_event( 'get_image_location', $path, $element_info);
+}
+
+
+/*
+ * @param element_info array containing element information from db;
+ * at least 'id', 'path', 'has_high' should be present
+ */
+function get_high_path($element_info)
+{
+  $path = get_high_location($element_info);
+  if (!empty($path) and !url_is_remote($path) )
+  {
+    $path = PHPWG_ROOT_PATH.$path;
+  }
+  return $path;
+}
+
+/**
+ * @param element_info array containing element information from db;
+ * at least 'id', 'path', 'has_high' should be present
+ */
+function get_high_url($element_info)
+{
+  $url = get_high_location($element_info);
+  if (!empty($url) and !url_is_remote($url) )
+  {
+    $url = embellish_url(get_root_url().$url);
+  }
+  // plugins want another url ?
+  return trigger_event('get_high_url', $url, $element_info);
+}
+
+/**
+ * @param element_info array containing element information from db;
+ * at least 'id', 'path', 'has_high' should be present
+ */
+function get_high_location($element_info)
+{
+  $location = '';
+  if ($element_info['has_high'] == 'true')
+  {
+    $pi = pathinfo($element_info['path']);
+    $location=$pi['dirname'].'/pwg_high/'.$pi['basename'];
+  }
+  return trigger_event( 'get_high_location', $location, $element_info);
+}
+
+
+/**
+ * @param what_part string one of 't' (thumbnail), 'e' (element), 'i' (image),
+ *   'h' (high resolution image)
+ * @param element_info array containing element information from db;
+ * at least 'id', 'path' should be present
+ */
+function get_download_url($what_part, $element_info)
+{
+  $url = get_root_url().'action.php';
+  $url = add_url_params($url,
+      array(
+        'id' => $element_info['id'],
+        'part' => $what_part,
+      )
+    );
+  return trigger_event( 'get_download_url', $url, $element_info);
+}
+
+/*
+ * get slideshow default params into array
+ *
+ * @param void
+ *
+ * @return slideshow default values into array
+ */
+function get_default_slideshow_params()
+{
+  global $conf;
+
+  return array(
+    'period' => $conf['slideshow_period'],
+    'repeat' => $conf['slideshow_repeat'],
+    'play' => true,
+    );
+}
+
+/*
+ * check and correct slideshow params from array
+ *
+ * @param array of params
+ *
+ * @return slideshow corrected values into array
+ */
+function correct_slideshow_params($params = array())
+{
+  global $conf;
+
+  if ($params['period'] < $conf['slideshow_period_min'])
+  {
+    $params['period'] = $conf['slideshow_period_min'];
+  }
+  else if ($params['period'] > $conf['slideshow_period_max'])
+  {
+    $params['period'] = $conf['slideshow_period_max'];
+  }
+
+  return $params;
+}
+
+/*
+ * Decode slideshow string params into array
+ *
+ * @param string params like ""
+ *
+ * @return slideshow values into array
+ */
+function decode_slideshow_params($encode_params = null)
+{
+  global $conf;
+
+  $result = get_default_slideshow_params();
+
+  if (is_numeric($encode_params))
+  {
+    $result['period'] = $encode_params;
+  }
+  else
+  {
+    $matches = array();
+    if (preg_match_all('/([a-z]+)-(\d+)/', $encode_params, $matches))
+    {
+      $matchcount = count($matches[1]);
+      for ($i = 0; $i < $matchcount; $i++)
+      {
+        $result[$matches[1][$i]] = $matches[2][$i];
+      }
+    }
+
+    if (preg_match_all('/([a-z]+)-(true|false)/', $encode_params, $matches))
+    {
+      $matchcount = count($matches[1]);
+      for ($i = 0; $i < $matchcount; $i++)
+      {
+        $result[$matches[1][$i]] = get_boolean($matches[2][$i]);
+      }
+    }
+  }
+
+  return correct_slideshow_params($result);
+}
+
+/*
+ * Encode slideshow array params into array
+ *
+ * @param array params
+ *
+ * @return slideshow values into string
+ */
+function encode_slideshow_params($decode_params = array())
+{
+  global $conf;
+
+  $params = array_diff_assoc(correct_slideshow_params($decode_params), get_default_slideshow_params());
+  $result = '';
+
+  foreach ($params as $name => $value)
+  {
+    // boolean_to_string return $value, if it's not a bool
+    $result .= '+'.$name.'-'.boolean_to_string($value);
+  }
+
+  return $result;
+}
+
+// The get_picture_size function return an array containing :
+//      - $picture_size[0] : final width
+//      - $picture_size[1] : final height
+// The final dimensions are calculated thanks to the original dimensions and
+// the maximum dimensions given in parameters.  get_picture_size respects
+// the width/height ratio
+function get_picture_size( $original_width, $original_height,
+                           $max_width, $max_height )
+{
+  $width = $original_width;
+  $height = $original_height;
+  $is_original_size = true;
+
+  if ( $max_width != "" )
+  {
+    if ( $original_width > $max_width )
+    {
+      $width = $max_width;
+      $height = floor( ( $width * $original_height ) / $original_width );
+    }
+  }
+  if ( $max_height != "" )
+  {
+    if ( $original_height > $max_height )
+    {
+      $height = $max_height;
+      $width = floor( ( $height * $original_width ) / $original_height );
+      $is_original_size = false;
+    }
+  }
+  if ( is_numeric( $max_width ) and is_numeric( $max_height )
+       and $max_width != 0 and $max_height != 0 )
+  {
+    $ratioWidth = $original_width / $max_width;
+    $ratioHeight = $original_height / $max_height;
+    if ( ( $ratioWidth > 1 ) or ( $ratioHeight > 1 ) )
+    {
+      if ( $ratioWidth < $ratioHeight )
+      {
+        $width = floor( $original_width / $ratioHeight );
+        $height = $max_height;
+      }
+      else
+      {
+        $width = $max_width;
+        $height = floor( $original_height / $ratioWidth );
+      }
+      $is_original_size = false;
+    }
+  }
+  $picture_size = array();
+  $picture_size[0] = $width;
+  $picture_size[1] = $height;
+  return $picture_size;
+}
+
+?>
Index: /tags/2.0.2/include/functions_plugins.inc.php
===================================================================
--- /tags/2.0.2/include/functions_plugins.inc.php	(revision 3278)
+++ /tags/2.0.2/include/functions_plugins.inc.php	(revision 3278)
@@ -0,0 +1,275 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+/*
+Events and event handlers are the core of Piwigo plugin management.
+Plugins are addons that are found in plugins subdirectory. If activated, PWG
+will include the index.php of each plugin.
+Events are triggered by PWG core code. Plugins (or even PWG itself) can
+register their functions to handle these events. An event is identified by a
+string.
+*/
+
+define('PHPWG_PLUGINS_PATH', PHPWG_ROOT_PATH.'plugins/');
+
+define('EVENT_HANDLER_PRIORITY_NEUTRAL', 50);
+
+/* Register a event handler.
+ * @param string $event the name of the event to listen to
+ * @param mixed $func the function that will handle the event
+ * @param int $priority optional priority (greater priority will
+ * be executed at last)
+*/
+function add_event_handler($event, $func,
+    $priority=EVENT_HANDLER_PRIORITY_NEUTRAL, $accepted_args=1)
+{
+  global $pwg_event_handlers;
+
+  if ( isset($pwg_event_handlers[$event][$priority]) )
+  {
+    foreach($pwg_event_handlers[$event][$priority] as $handler)
+    {
+      if ( $handler['function'] == $func )
+      {
+        return false;
+      }
+    }
+  }
+
+  $pwg_event_handlers[$event][$priority][] =
+    array(
+      'function'=>$func,
+      'accepted_args'=>$accepted_args);
+  ksort( $pwg_event_handlers[$event] );
+  return true;
+}
+
+/* Register a event handler.
+ * @param string $event the name of the event to listen to
+ * @param mixed $func the function that needs removal
+ * @param int $priority optional priority (greater priority will
+ * be executed at last)
+*/
+function remove_event_handler($event, $func,
+   $priority=EVENT_HANDLER_PRIORITY_NEUTRAL)
+{
+  global $pwg_event_handlers;
+
+  if (!isset( $pwg_event_handlers[$event][$priority] ) )
+  {
+    return false;
+  }
+  for ($i=0; $i<count($pwg_event_handlers[$event][$priority]); $i++)
+  {
+    if ($pwg_event_handlers[$event][$priority][$i]['function']==$func)
+    {
+      unset($pwg_event_handlers[$event][$priority][$i]);
+      $pwg_event_handlers[$event][$priority] =
+        array_values($pwg_event_handlers[$event][$priority]);
+
+      if ( empty($pwg_event_handlers[$event][$priority]) )
+      {
+        unset( $pwg_event_handlers[$event][$priority] );
+        if (empty( $pwg_event_handlers[$event] ) )
+        {
+          unset( $pwg_event_handlers[$event] );
+        }
+      }
+      return true;
+    }
+  }
+  return false;
+}
+
+/* Triggers an event and calls all registered event handlers
+ * @param string $event name of the event
+ * @param mixed $data data to pass to handlers
+*/
+function trigger_event($event, $data=null)
+{
+  global $pwg_event_handlers;
+
+  if ( isset($pwg_event_handlers['trigger']) )
+  {// just for debugging
+    trigger_action('trigger',
+        array('type'=>'event', 'event'=>$event, 'data'=>$data) );
+  }
+
+  if ( !isset($pwg_event_handlers[$event]) )
+  {
+    return $data;
+  }
+  $args = array_slice(func_get_args(), 2);
+
+  foreach ($pwg_event_handlers[$event] as $priority => $handlers)
+  {
+    foreach($handlers as $handler)
+    {
+      $all_args = array_merge( array($data), $args);
+      $function_name = $handler['function'];
+      $accepted_args = $handler['accepted_args'];
+
+      if ( $accepted_args == 1 )
+        $the_args = array($data);
+      elseif ( $accepted_args > 1 )
+        $the_args = array_slice($all_args, 0, $accepted_args);
+      elseif ( $accepted_args == 0 )
+        $the_args = NULL;
+      else
+        $the_args = $all_args;
+
+      $data = call_user_func_array($function_name, $the_args);
+    }
+  }
+  trigger_action('trigger',
+       array('type'=>'post_event', 'event'=>$event, 'data'=>$data) );
+  return $data;
+}
+
+function trigger_action($event, $data=null)
+{
+  global $pwg_event_handlers;
+  if ( isset($pwg_event_handlers['trigger']) and $event!='trigger' )
+  {// special case for debugging - avoid recursive calls
+    trigger_action('trigger',
+        array('type'=>'action', 'event'=>$event, 'data'=>$data) );
+  }
+
+  if ( !isset($pwg_event_handlers[$event]) )
+  {
+    return;
+  }
+  $args = array_slice(func_get_args(), 2);
+
+  foreach ($pwg_event_handlers[$event] as $priority => $handlers)
+  {
+    foreach($handlers as $handler)
+    {
+      $all_args = array_merge( array($data), $args);
+      $function_name = $handler['function'];
+      $accepted_args = $handler['accepted_args'];
+
+      if ( $accepted_args == 1 )
+        $the_args = array($data);
+      elseif ( $accepted_args > 1 )
+        $the_args = array_slice($all_args, 0, $accepted_args);
+      elseif ( $accepted_args == 0 )
+        $the_args = NULL;
+      else
+        $the_args = $all_args;
+
+      call_user_func_array($function_name, $the_args);
+    }
+  }
+}
+
+/** Saves some data with the associated plugim id. It can be retrieved later (
+ * during this script lifetime) using get_plugin_data
+ * @param string plugin_id
+ * @param mixed data
+ * returns true on success, false otherwise
+ */
+function set_plugin_data($plugin_id, &$data)
+{
+  global $pwg_loaded_plugins;
+  if ( isset($pwg_loaded_plugins[$plugin_id]) )
+  {
+    $pwg_loaded_plugins[$plugin_id]['plugin_data'] = &$data;
+    return true;
+  }
+  return false;
+}
+
+/** Retrieves plugin data saved previously with set_plugin_data
+ * @param string plugin_id
+ */
+function &get_plugin_data($plugin_id)
+{
+  global $pwg_loaded_plugins;
+  if ( isset($pwg_loaded_plugins[$plugin_id]) )
+  {
+    return $pwg_loaded_plugins[$plugin_id]['plugin_data'];
+  }
+  return null;
+}
+
+/* Returns an array of plugins defined in the database
+ * @param string $state optional filter on this state
+ * @param string $id optional returns only data about given plugin
+*/
+function get_db_plugins($state='', $id='')
+{
+  $query = '
+SELECT * FROM '.PLUGINS_TABLE;
+  $clauses = array();
+  if (!empty($state))
+  {
+    $clauses[] = 'state="'.$state.'"';
+  }
+  if (!empty($id))
+  {
+    $clauses[] = 'id="'.$id.'"';
+  }
+  if (count($clauses))
+  {
+      $query .= '
+  WHERE '. implode(' AND ', $clauses);
+  }
+
+  $result = pwg_query($query);
+  $plugins = array();
+  while ($row = mysql_fetch_array($result))
+  {
+    array_push($plugins, $row);
+  }
+  return $plugins;
+}
+
+
+function load_plugin($plugin)
+{
+  $file_name = PHPWG_PLUGINS_PATH.$plugin['id'].'/main.inc.php';
+  if ( file_exists($file_name) )
+  {
+    global $pwg_loaded_plugins;
+    $pwg_loaded_plugins[ $plugin['id'] ] = $plugin;
+    include_once( $file_name );
+  }
+}
+
+/*loads all the plugins on startup*/
+function load_plugins()
+{
+  global $conf, $pwg_loaded_plugins;
+  $pwg_loaded_plugins = array();
+  if ($conf['enable_plugins'])
+  {
+    $plugins = get_db_plugins('active');
+    foreach( $plugins as $plugin)
+    {// include main from a function to avoid using same function context
+      load_plugin($plugin);
+    }
+    trigger_action('plugins_loaded');
+  }
+}
+?>
Index: /tags/2.0.2/include/functions_rate.inc.php
===================================================================
--- /tags/2.0.2/include/functions_rate.inc.php	(revision 3278)
+++ /tags/2.0.2/include/functions_rate.inc.php	(revision 3278)
@@ -0,0 +1,137 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+/**
+ * rate a picture by a user
+ *
+ * @param int image identifier
+ * @param int rate
+ * @return void
+ */
+function rate_picture($image_id, $rate)
+{
+  global $conf, $user;
+
+  if (!isset($rate)
+      or !$conf['rate']
+      or !in_array($rate, $conf['rate_items']))
+  {
+    return false;
+  }
+
+  $user_anonymous = is_autorize_status(ACCESS_CLASSIC) ? false : true;
+
+  if ($user_anonymous and !$conf['rate_anonymous'])
+  {
+    return false;
+  }
+
+  $ip_components = explode('.', $_SERVER["REMOTE_ADDR"]);
+  if (count($ip_components) > 3)
+  {
+    array_pop($ip_components);
+  }
+  $anonymous_id = implode ('.', $ip_components);
+
+  if ($user_anonymous)
+  {
+    $save_anonymous_id = pwg_get_cookie_var('anonymous_rater', $anonymous_id);
+
+    if ($anonymous_id != $save_anonymous_id)
+    { // client has changed his IP adress or he's trying to fool us
+      $query = '
+SELECT element_id
+  FROM '.RATE_TABLE.'
+  WHERE user_id = '.$user['id'].'
+    AND anonymous_id = \''.$anonymous_id.'\'
+;';
+      $already_there = array_from_query($query, 'element_id');
+
+      if (count($already_there) > 0)
+      {
+        $query = '
+DELETE
+  FROM '.RATE_TABLE.'
+  WHERE user_id = '.$user['id'].'
+    AND anonymous_id = \''.$save_anonymous_id.'\'
+    AND element_id IN ('.implode(',', $already_there).')
+;';
+         pwg_query($query);
+       }
+
+       $query = '
+UPDATE '.RATE_TABLE.'
+  SET anonymous_id = \'' .$anonymous_id.'\'
+  WHERE user_id = '.$user['id'].'
+    AND anonymous_id = \'' . $save_anonymous_id.'\'
+;';
+       pwg_query($query);
+    } // end client changed ip
+
+    pwg_set_cookie_var('anonymous_rater', $anonymous_id);
+  } // end anonymous user
+
+  $query = '
+DELETE
+  FROM '.RATE_TABLE.'
+  WHERE element_id = '.$image_id.'
+    AND user_id = '.$user['id'].'
+';
+  if ($user_anonymous)
+  {
+    $query.= ' AND anonymous_id = \''.$anonymous_id.'\'';
+  }
+  pwg_query($query);
+  $query = '
+INSERT
+  INTO '.RATE_TABLE.'
+  (user_id,anonymous_id,element_id,rate,date)
+  VALUES
+  ('
+    .$user['id'].','
+    .'\''.$anonymous_id.'\','
+    .$image_id.','
+    .$rate
+    .',NOW())
+;';
+  pwg_query($query);
+
+  // update of images.average_rate field
+  $query = '
+SELECT COUNT(rate) AS count
+     , ROUND(AVG(rate),2) AS average
+     , ROUND(STD(rate),2) AS stdev
+  FROM '.RATE_TABLE.'
+  WHERE element_id = '.$image_id.'
+;';
+  $row = mysql_fetch_assoc(pwg_query($query));
+  $query = '
+UPDATE '.IMAGES_TABLE.'
+  SET average_rate = '.$row['average'].'
+  WHERE id = '.$image_id.'
+;';
+  pwg_query($query);
+  return $row;
+}
+
+?>
Index: /tags/2.0.2/include/functions_search.inc.php
===================================================================
--- /tags/2.0.2/include/functions_search.inc.php	(revision 3278)
+++ /tags/2.0.2/include/functions_search.inc.php	(revision 3278)
@@ -0,0 +1,607 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+
+/**
+ * returns search rules stored into a serialized array in "search"
+ * table. Each search rules set is numericaly identified.
+ *
+ * @param int search_id
+ * @return array
+ */
+function get_search_array($search_id)
+{
+  if (!is_numeric($search_id))
+  {
+    die('Search id must be an integer');
+  }
+
+  $query = '
+SELECT rules
+  FROM '.SEARCH_TABLE.'
+  WHERE id = '.$search_id.'
+;';
+  list($serialized_rules) = mysql_fetch_row(pwg_query($query));
+
+  return unserialize($serialized_rules);
+}
+
+/**
+ * returns the SQL clause from a search identifier
+ *
+ * Search rules are stored in search table as a serialized array. This array
+ * need to be transformed into an SQL clause to be used in queries.
+ *
+ * @param array search
+ * @return string
+ */
+function get_sql_search_clause($search)
+{
+  // SQL where clauses are stored in $clauses array during query
+  // construction
+  $clauses = array();
+
+  foreach (array('file','name','comment','author') as $textfield)
+  {
+    if (isset($search['fields'][$textfield]))
+    {
+      $local_clauses = array();
+      foreach ($search['fields'][$textfield]['words'] as $word)
+      {
+        array_push($local_clauses, $textfield." LIKE '%".$word."%'");
+      }
+
+      // adds brackets around where clauses
+      $local_clauses = prepend_append_array_items($local_clauses, '(', ')');
+
+      array_push(
+        $clauses,
+        implode(
+          ' '.$search['fields'][$textfield]['mode'].' ',
+          $local_clauses
+          )
+        );
+    }
+  }
+
+  if (isset($search['fields']['allwords']))
+  {
+    $fields = array('file', 'name', 'comment', 'author');
+    // in the OR mode, request bust be :
+    // ((field1 LIKE '%word1%' OR field2 LIKE '%word1%')
+    // OR (field1 LIKE '%word2%' OR field2 LIKE '%word2%'))
+    //
+    // in the AND mode :
+    // ((field1 LIKE '%word1%' OR field2 LIKE '%word1%')
+    // AND (field1 LIKE '%word2%' OR field2 LIKE '%word2%'))
+    $word_clauses = array();
+    foreach ($search['fields']['allwords']['words'] as $word)
+    {
+      $field_clauses = array();
+      foreach ($fields as $field)
+      {
+        array_push($field_clauses, $field." LIKE '%".$word."%'");
+      }
+      // adds brackets around where clauses
+      array_push(
+        $word_clauses,
+        implode(
+          "\n          OR ",
+          $field_clauses
+          )
+        );
+    }
+
+    array_walk(
+      $word_clauses,
+      create_function('&$s','$s="(".$s.")";')
+      );
+
+    array_push(
+      $clauses,
+      "\n         ".
+      implode(
+        "\n         ".
+              $search['fields']['allwords']['mode'].
+        "\n         ",
+        $word_clauses
+        )
+      );
+  }
+
+  foreach (array('date_available', 'date_creation') as $datefield)
+  {
+    if (isset($search['fields'][$datefield]))
+    {
+      array_push(
+        $clauses,
+        $datefield." = '".$search['fields'][$datefield]['date']."'"
+        );
+    }
+
+    foreach (array('after','before') as $suffix)
+    {
+      $key = $datefield.'-'.$suffix;
+
+      if (isset($search['fields'][$key]))
+      {
+        array_push(
+          $clauses,
+
+          $datefield.
+          ($suffix == 'after'             ? ' >' : ' <').
+          ($search['fields'][$key]['inc'] ? '='  : '').
+          " '".$search['fields'][$key]['date']."'"
+
+          );
+      }
+    }
+  }
+
+  if (isset($search['fields']['cat']))
+  {
+    if ($search['fields']['cat']['sub_inc'])
+    {
+      // searching all the categories id of sub-categories
+      $cat_ids = get_subcat_ids($search['fields']['cat']['words']);
+    }
+    else
+    {
+      $cat_ids = $search['fields']['cat']['words'];
+    }
+
+    $local_clause = 'category_id IN ('.implode(',', $cat_ids).')';
+    array_push($clauses, $local_clause);
+  }
+
+  // adds brackets around where clauses
+  $clauses = prepend_append_array_items($clauses, '(', ')');
+
+  $where_separator =
+    implode(
+      "\n    ".$search['mode'].' ',
+      $clauses
+      );
+
+  $search_clause = $where_separator;
+
+  return $search_clause;
+}
+
+/**
+ * returns the list of items corresponding to the advanced search array
+ *
+ * @param array search
+ * @return array
+ */
+function get_regular_search_results($search, $images_where)
+{
+  global $conf;
+  $forbidden = get_sql_condition_FandF(
+        array
+          (
+            'forbidden_categories' => 'category_id',
+            'visible_categories' => 'category_id',
+            'visible_images' => 'id'
+          ),
+        "\n  AND"
+    );
+
+  $items = array();
+  $tag_items = array();
+
+  if (isset($search['fields']['tags']))
+  {
+    $tag_items = get_image_ids_for_tags(
+      $search['fields']['tags']['words'],
+      $search['fields']['tags']['mode']
+      );
+  }
+
+  $search_clause = get_sql_search_clause($search);
+
+  if (!empty($search_clause))
+  {
+    $query = '
+SELECT DISTINCT(id)
+  FROM '.IMAGES_TABLE.' i
+    INNER JOIN '.IMAGE_CATEGORY_TABLE.' AS ic ON id = ic.image_id
+  WHERE '.$search_clause;
+    if (!empty($images_where))
+    {
+      $query .= "\n  AND ".$images_where;
+    }
+    if (empty($tag_items) or $search['mode']=='AND')
+    { // directly use forbidden and order by
+      $query .= $forbidden.'
+  '.$conf['order_by'];
+    }
+    $items = array_from_query($query, 'id');
+  }
+
+  if ( !empty($tag_items) )
+  {
+    $need_permission_check = false;
+    switch ($search['mode'])
+    {
+      case 'AND':
+        if (empty($search_clause))
+        {
+          $need_permission_check = true;
+          $items = $tag_items;
+        }
+        else
+        {
+          $items = array_intersect($items, $tag_items);
+        }
+        break;
+      case 'OR':
+        $before_count = count($items);
+        $items = array_unique(
+          array_merge(
+            $items,
+            $tag_items
+            )
+          );
+        if ( $before_count < count($items) )
+        {
+          $need_permission_check = true;
+        }
+        break;
+    }
+    if ($need_permission_check and count($items) )
+    {
+      $query = '
+SELECT DISTINCT(id)
+  FROM '.IMAGES_TABLE.' i
+    INNER JOIN '.IMAGE_CATEGORY_TABLE.' AS ic ON id = ic.image_id
+  WHERE id IN ('.implode(',', $items).') '.$forbidden;
+      if (!empty($images_where))
+      {
+        $query .= "\n  AND ".$images_where;
+      }
+      $query .= '
+  '.$conf['order_by'];
+      $items = array_from_query($query, 'id');
+    }
+  }
+
+  return $items;
+}
+
+/**
+ * returns the LIKE sql clause corresponding to the quick search query $q
+ * and the field $field. example q='john bill', field='file' will return
+ * file LIKE '%john%' OR file LIKE '%bill%'. Special characters for MySql full
+ * text search (+,<,>,~) are omitted. The query can contain a phrase:
+ * 'Pierre "New York"' will return LIKE '%Pierre%' OR LIKE '%New York%'.
+ * @param string q
+ * @param string field
+ * @return string
+ */
+function get_qsearch_like_clause($q, $field, $before='%', $after='%')
+{
+  $q = stripslashes($q);
+  $tokens = array();
+  $token_modifiers = array();
+  $crt_token = "";
+  $crt_token_modifier = "";
+  $state = 0;
+
+  for ($i=0; $i<strlen($q); $i++)
+  {
+    $ch = $q[$i];
+    switch ($state)
+    {
+      case 0:
+        if ($ch=='"')
+        {
+          if (strlen($crt_token))
+          {
+            $tokens[] = $crt_token;
+            $token_modifiers[] = $crt_token_modifier;
+            $crt_token = "";
+            $crt_token_modifier = "";
+          }
+          $state=1;
+        }
+        elseif ( $ch=='*' )
+        { // wild card
+          $crt_token .= '%';
+        }
+        elseif ( strcspn($ch, '+-><~')==0 )
+        { //special full text modifier
+          if (strlen($crt_token))
+          {
+            $tokens[] = $crt_token;
+            $token_modifiers[] = $crt_token_modifier;
+            $crt_token = "";
+            $crt_token_modifier = "";
+          }
+          $crt_token_modifier .= $ch;
+        }
+        elseif (preg_match('/[\s,.;!\?]+/', $ch))
+        { // white space
+          if (strlen($crt_token))
+          {
+            $tokens[] = $crt_token;
+            $token_modifiers[] = $crt_token_modifier;
+            $crt_token = "";
+            $crt_token_modifier = "";
+          }
+        }
+        else
+        {
+          if ( strcspn($ch, '%_')==0)
+          {// escape LIKE specials %_
+            $ch = '\\'.$ch;
+          }
+          $crt_token .= $ch;
+        }
+        break;
+      case 1: // qualified with quotes
+        switch ($ch)
+        {
+          case '"':
+            $tokens[] = $crt_token;
+            $token_modifiers[] = $crt_token_modifier;
+            $crt_token = "";
+            $crt_token_modifier = "";
+            $state=0;
+            break;
+          default:
+            if ( strcspn($ch, '%_')==0)
+            {// escape LIKE specials %_
+            	$ch = '\\'.$ch;
+            }
+            $crt_token .= $ch;
+        }
+        break;
+    }
+  }
+  if (strlen($crt_token))
+  {
+    $tokens[] = $crt_token;
+    $token_modifiers[] = $crt_token_modifier;
+  }
+
+  $clauses = array();
+  for ($i=0; $i<count($tokens); $i++)
+  {
+    $tokens[$i] = trim($tokens[$i], '%');
+    if (strstr($token_modifiers[$i], '-')!==false)
+      continue;
+    if ( strlen($tokens[$i])==0)
+      continue;
+    $clauses[] = $field.' LIKE "'.$before.addslashes($tokens[$i]).$after.'"';
+  }
+
+  return count($clauses) ? '('.implode(' OR ', $clauses).')' : null;
+}
+
+
+/**
+ * returns the search results corresponding to a quick/query search.
+ * A quick/query search returns many items (search is not strict), but results
+ * are sorted by relevance unless $super_order_by is true. Returns:
+ * array (
+ * 'items' => array(85,68,79...)
+ * 'qs'    => array(
+ *    'matching_tags' => array of matching tags
+ *    'matching_cats' => array of matching categories
+ *    'matching_cats_no_images' =>array(99) - matching categories without images
+ *      ))
+ *
+ * @param string q
+ * @param bool super_order_by
+ * @param string images_where optional aditional restriction on images table
+ * @return array
+ */
+function get_quick_search_results($q, $super_order_by, $images_where='')
+{
+  $search_results =
+    array(
+      'items' => array(),
+      'qs' => array('q'=>stripslashes($q)),
+    );
+  $q = trim($q);
+  if (empty($q))
+  {
+    return $search_results;
+  }
+  $q_like_field = '@@__db_field__@@'; //something never in a search
+  $q_like_clause = get_qsearch_like_clause($q, $q_like_field );
+
+
+  // Step 1 - first we find matches in #images table ===========================
+  $where_clauses='MATCH(i.name, i.comment) AGAINST( "'.$q.'" IN BOOLEAN MODE)';
+  if (!empty($q_like_clause))
+  {
+    $where_clauses .= '
+    OR '. str_replace($q_like_field, 'file', $q_like_clause);
+    $where_clauses = '('.$where_clauses.')';
+  }
+  $where_clauses = array($where_clauses);
+  if (!empty($images_where))
+  {
+    $where_clauses[]='('.$images_where.')';
+  }
+  $where_clauses[] .= get_sql_condition_FandF
+      (
+        array( 'visible_images' => 'i.id' ), null, true
+      );
+  $query = '
+SELECT i.id,
+    MATCH(i.name, i.comment) AGAINST( "'.$q.'" IN BOOLEAN MODE) AS weight
+  FROM '.IMAGES_TABLE.' i
+  WHERE '.implode("\n AND ", $where_clauses);
+
+  $by_weights=array();
+  $result = pwg_query($query);
+  while ($row = mysql_fetch_array($result))
+  { // weight is important when sorting images by relevance
+    if ($row['weight'])
+    {
+      $by_weights[(int)$row['id']] =  2*$row['weight'];
+    }
+    else
+    {//full text does not match but file name match
+      $by_weights[(int)$row['id']] =  2;
+    }
+  }
+
+
+  // Step 2 - search tags corresponding to the query $q ========================
+  if (!empty($q_like_clause))
+  { // search name and url name (without accents)
+    $query = '
+SELECT id, name, url_name
+  FROM '.TAGS_TABLE.'
+  WHERE ('.str_replace($q_like_field, 'CONVERT(name, CHAR)', $q_like_clause).'
+    OR '.str_replace($q_like_field, 'url_name', $q_like_clause).')';
+    $tags = hash_from_query($query, 'id');
+    if ( !empty($tags) )
+    { // we got some tags; get the images
+      $search_results['qs']['matching_tags']=$tags;
+      $query = '
+SELECT image_id, COUNT(tag_id) AS weight
+  FROM '.IMAGE_TAG_TABLE.'
+  WHERE tag_id IN ('.implode(',',array_keys($tags)).')
+  GROUP BY image_id';
+      $result = pwg_query($query);
+      while ($row = mysql_fetch_assoc($result))
+      { // weight is important when sorting images by relevance
+        $image_id=(int)$row['image_id'];
+        @$by_weights[$image_id] += $row['weight'];
+      }
+    }
+  }
+
+
+  // Step 3 - search categories corresponding to the query $q ==================
+  global $user;
+  $query = '
+SELECT id, name, permalink, nb_images
+  FROM '.CATEGORIES_TABLE.'
+    INNER JOIN '.USER_CACHE_CATEGORIES_TABLE.' ON id=cat_id
+  WHERE user_id='.$user['id'].'
+    AND MATCH(name, comment) AGAINST( "'.$q.'" IN BOOLEAN MODE)'.
+  get_sql_condition_FandF (
+      array( 'visible_categories' => 'cat_id' ), "\n    AND"
+    );
+  $result = pwg_query($query);
+  while ($row = mysql_fetch_assoc($result))
+  { // weight is important when sorting images by relevance
+    if ($row['nb_images']==0)
+    {
+      $search_results['qs']['matching_cats_no_images'][] = $row;
+    }
+    else
+    {
+      $search_results['qs']['matching_cats'][$row['id']] = $row;
+    }
+  }
+
+  if ( empty($by_weights) and empty($search_results['qs']['matching_cats']) )
+  {
+    return $search_results;
+  }
+
+  // Step 4 - now we have $by_weights ( array image id => weight ) that need
+  // permission checks and/or matching categories to get images from
+  $where_clauses = array();
+  if ( !empty($by_weights) )
+  {
+    $where_clauses[]='i.id IN ('
+      . implode(',', array_keys($by_weights)) . ')';
+  }
+  if ( !empty($search_results['qs']['matching_cats']) )
+  {
+    $where_clauses[]='category_id IN ('.
+      implode(',',array_keys($search_results['qs']['matching_cats'])).')';
+  }
+  $where_clauses = array( '('.implode("\n    OR ",$where_clauses).')' );
+  if (!empty($images_where))
+  {
+    $where_clauses[]='('.$images_where.')';
+  }
+  $where_clauses[] = get_sql_condition_FandF(
+      array
+        (
+          'forbidden_categories' => 'category_id',
+          'visible_categories' => 'category_id',
+          'visible_images' => 'i.id'
+        ),
+      null,true
+    );
+
+  global $conf;
+  $query = '
+SELECT DISTINCT(id)
+  FROM '.IMAGES_TABLE.' i
+    INNER JOIN '.IMAGE_CATEGORY_TABLE.' AS ic ON id = ic.image_id
+  WHERE '.implode("\n AND ", $where_clauses)."\n".
+  $conf['order_by'];
+
+  $allowed_images = array_from_query( $query, 'id');
+
+  if ( $super_order_by or empty($by_weights) )
+  {
+    $search_results['items'] = $allowed_images;
+    return $search_results;
+  }
+
+  $allowed_images = array_flip( $allowed_images );
+  $divisor = 5.0 * count($allowed_images);
+  foreach ($allowed_images as $id=>$rank )
+  {
+    $weight = isset($by_weights[$id]) ? $by_weights[$id] : 1;
+    $weight -= $rank/$divisor;
+    $allowed_images[$id] = $weight;
+  }
+  arsort($allowed_images, SORT_NUMERIC);
+  $search_results['items'] = array_keys($allowed_images);
+  return $search_results;
+}
+
+/**
+ * returns an array of 'items' corresponding to the search id
+ *
+ * @param int search id
+ * @param string images_where optional aditional restriction on images table
+ * @return array
+ */
+function get_search_results($search_id, $super_order_by, $images_where='')
+{
+  $search = get_search_array($search_id);
+  if ( !isset($search['q']) )
+  {
+    $result['items'] = get_regular_search_results($search, $images_where);
+    return $result;
+  }
+  else
+  {
+    return get_quick_search_results($search['q'], $super_order_by, $images_where);
+  }
+}
+?>
Index: /tags/2.0.2/include/functions_session.inc.php
===================================================================
--- /tags/2.0.2/include/functions_session.inc.php	(revision 3278)
+++ /tags/2.0.2/include/functions_session.inc.php	(revision 3278)
@@ -0,0 +1,228 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// The function generate_key creates a string with pseudo random characters.
+// the size of the string depends on the $conf['session_id_size'].
+// Characters used are a-z A-Z and numerical values. Examples :
+//                    "Er4Tgh6", "Rrp08P", "54gj"
+// input  : none (using global variable)
+// output : $key
+function generate_key($size)
+{
+  global $conf;
+
+  $md5 = md5(substr(microtime(), 2, 6));
+  $init = '';
+  for ( $i = 0; $i < strlen( $md5 ); $i++ )
+  {
+    if ( is_numeric( $md5[$i] ) ) $init.= $md5[$i];
+  }
+  $init = substr( $init, 0, 8 );
+  mt_srand( $init );
+  $key = '';
+  for ( $i = 0; $i < $size; $i++ )
+  {
+    $c = mt_rand( 0, 2 );
+    if ( $c == 0 )      $key .= chr( mt_rand( 65, 90 ) );
+    else if ( $c == 1 ) $key .= chr( mt_rand( 97, 122 ) );
+    else                $key .= mt_rand( 0, 9 );
+  }
+  return $key;
+}
+
+if (isset($conf['session_save_handler'])
+  and ($conf['session_save_handler'] == 'db')
+  and defined('PHPWG_INSTALLED'))
+{
+  session_set_save_handler('pwg_session_open',
+    'pwg_session_close',
+    'pwg_session_read',
+    'pwg_session_write',
+    'pwg_session_destroy',
+    'pwg_session_gc'
+  );
+  if ( function_exists('ini_set') )
+  {
+    ini_set('session.use_cookies', $conf['session_use_cookies']);
+    ini_set('session.use_only_cookies', $conf['session_use_only_cookies']);
+    ini_set('session.use_trans_sid', intval($conf['session_use_trans_sid']));
+    ini_set('session.cookie_httponly', 1);
+  }
+  session_name($conf['session_name']);
+  session_set_cookie_params(0, cookie_path());
+}
+
+/**
+ * returns true; used when the session_start() function is called
+ *
+ * @params not use but useful for php engine
+ */
+function pwg_session_open($path, $name)
+{
+  return true;
+}
+
+/**
+ * returns true; used when the session is closed (unset($_SESSION))
+ *
+ */
+function pwg_session_close()
+{
+  return true;
+}
+
+function get_remote_addr_session_hash()
+{
+  $separator = (FALSE === strpos($_SERVER['REMOTE_ADDR'],'.'))
+    ? ':'
+    : '.'
+  ;
+
+  return vsprintf(
+    "%02X%02X",
+    explode($separator,$_SERVER['REMOTE_ADDR'])
+  );
+}
+
+/**
+ * this function returns
+ * a string corresponding to the value of the variable save in the session
+ * or an empty string when the variable doesn't exist
+ *
+ * @param string session id
+ */
+function pwg_session_read($session_id)
+{
+  $query = '
+SELECT data
+  FROM '.SESSIONS_TABLE.'
+  WHERE id = \''.get_remote_addr_session_hash().$session_id.'\'
+;';
+  $result = pwg_query($query);
+  if ($result)
+  {
+    $row = mysql_fetch_assoc($result);
+    return $row['data'];
+  }
+  else
+  {
+    return '';
+  }
+}
+
+/**
+ * returns true; writes set a variable in the active session
+ *
+ * @param string session id
+ * @data string value of date to be saved
+ */
+function pwg_session_write($session_id, $data)
+{
+  $query = '
+REPLACE INTO '.SESSIONS_TABLE.'
+  (id,data,expiration)
+  VALUES(\''.get_remote_addr_session_hash().$session_id.'\',\''.$data.'\',now())
+;';
+  pwg_query($query);
+  return true;
+}
+
+/**
+ * returns true; delete the active session
+ *
+ * @param string session id
+ */
+function pwg_session_destroy($session_id)
+{
+  $query = '
+DELETE
+  FROM '.SESSIONS_TABLE.'
+  WHERE id = \''.get_remote_addr_session_hash().$session_id.'\'
+;';
+  pwg_query($query);
+  return true;
+}
+
+/**
+ * returns true; delete expired sessions
+ * called each time a session is closed.
+ */
+function pwg_session_gc()
+{
+  global $conf;
+
+  $query = '
+DELETE
+  FROM '.SESSIONS_TABLE.'
+  WHERE UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(expiration) > '
+  .$conf['session_length'].'
+;';
+  pwg_query($query);
+  return true;
+}
+
+
+/**
+ * persistently stores a variable for the current session
+ * currently we use standard php sessions but it might change
+ * @return boolean true on success
+ * @see pwg_get_session_var, pwg_unset_session_var
+ */
+function pwg_set_session_var($var, $value)
+{
+  if ( !isset($_SESSION) )
+    return false;
+  $_SESSION['pwg_'.$var] = $value;
+  return true;
+}
+
+/**
+ * retrieves the value of a persistent variable for the current session
+ * currently we use standard php sessions but it might change
+ * @return mixed
+ * @see pwg_set_session_var, pwg_unset_session_var
+ */
+function pwg_get_session_var($var, $default = null)
+{
+  if (isset( $_SESSION['pwg_'.$var] ) )
+  {
+    return $_SESSION['pwg_'.$var];
+  }
+  return $default;
+}
+
+/**
+ * deletes a persistent variable for the current session
+ * currently we use standard php sessions but it might change
+ * @return boolean true on success
+ * @see pwg_set_session_var, pwg_get_session_var
+ */
+function pwg_unset_session_var($var)
+{
+  if ( !isset($_SESSION) )
+    return false;
+  unset( $_SESSION['pwg_'.$var] );
+  return true;
+}
+
+?>
Index: /tags/2.0.2/include/functions_tag.inc.php
===================================================================
--- /tags/2.0.2/include/functions_tag.inc.php	(revision 3278)
+++ /tags/2.0.2/include/functions_tag.inc.php	(revision 3278)
@@ -0,0 +1,320 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+
+/**
+ * Tags available. Each return tag is represented as an array with its id,
+ * its name, its weight (count), its url name. Tags are not sorted.
+ *
+ * The returned list can be a subset of all existing tags due to
+ * permissions, only if a list of forbidden categories is provided
+ *
+ * @param array forbidden categories
+ * @return array
+ */
+function get_available_tags()
+{
+  // we can find top fatter tags among reachable images
+  $query = '
+SELECT tag_id, COUNT(DISTINCT(it.image_id)) counter
+  FROM '.IMAGE_CATEGORY_TABLE.' ic
+    INNER JOIN '.IMAGE_TAG_TABLE.' it ON ic.image_id=it.image_id'.get_sql_condition_FandF
+    (
+      array
+        (
+          'forbidden_categories' => 'category_id',
+          'visible_categories' => 'category_id',
+          'visible_images' => 'ic.image_id'
+        ),
+      '
+  WHERE'
+    ).'
+  GROUP BY tag_id
+  ORDER BY NULL';
+  $tag_counters = simple_hash_from_query($query, 'tag_id', 'counter');
+
+  if ( empty($tag_counters) )
+  {
+    return array();
+  }
+
+  $query = '
+SELECT *
+  FROM '.TAGS_TABLE;
+  $result = pwg_query($query);
+  $tags = array();
+  while ($row = mysql_fetch_assoc($result))
+  {
+    $counter = @$tag_counters[ $row['id'] ];
+    if ( $counter )
+    {
+      $row['counter'] = $counter;
+      array_push($tags, $row);
+    }
+  }
+  return $tags;
+}
+
+/**
+ * All tags, even tags associated to no image.
+ *
+ * @return array
+ */
+function get_all_tags()
+{
+  $query = '
+SELECT *
+  FROM '.TAGS_TABLE.'
+;';
+  $result = pwg_query($query);
+  $tags = array();
+  while ($row = mysql_fetch_assoc($result))
+  {
+    array_push($tags, $row);
+  }
+
+  usort($tags, 'tag_alpha_compare');
+
+  return $tags;
+}
+
+/**
+ * Giving a set of tags with a counter for each one, calculate the display
+ * level of each tag.
+ *
+ * The level of each tag depends on the average count of tags. This
+ * calcylation method avoid having very different levels for tags having
+ * nearly the same count when set are small.
+ *
+ * @param array tags
+ * @return array
+ */
+function add_level_to_tags($tags)
+{
+  global $conf;
+
+  if (count($tags) == 0)
+  {
+    return $tags;
+  }
+
+  $total_count = 0;
+
+  foreach ($tags as $tag)
+  {
+    $total_count+= $tag['counter'];
+  }
+
+  // average count of available tags will determine the level of each tag
+  $tag_average_count = $total_count / count($tags);
+
+  // tag levels threshold calculation: a tag with an average rate must have
+  // the middle level.
+  for ($i = 1; $i < $conf['tags_levels']; $i++)
+  {
+    $threshold_of_level[$i] =
+      2 * $i * $tag_average_count / $conf['tags_levels'];
+  }
+
+  // display sorted tags
+  foreach (array_keys($tags) as $k)
+  {
+    $tags[$k]['level'] = 1;
+
+    // based on threshold, determine current tag level
+    for ($i = $conf['tags_levels'] - 1; $i >= 1; $i--)
+    {
+      if ($tags[$k]['counter'] > $threshold_of_level[$i])
+      {
+        $tags[$k]['level'] = $i + 1;
+        break;
+      }
+    }
+  }
+
+  return $tags;
+}
+
+/**
+ * return the list of image ids corresponding to given tags. AND & OR mode
+ * supported.
+ *
+ * @param array tag ids
+ * @param string mode
+ * @return array
+ */
+function get_image_ids_for_tags($tag_ids, $mode = 'AND')
+{
+  switch ($mode)
+  {
+    case 'AND':
+    {
+      // strategy is to list images associated to each tag
+      $tag_images = array();
+
+      foreach ($tag_ids as $tag_id)
+      {
+        $query = '
+SELECT image_id
+  FROM '.IMAGE_TAG_TABLE.'
+  WHERE tag_id = '.$tag_id.'
+;';
+        $tag_images[$tag_id] = array_from_query($query, 'image_id');
+      }
+
+      // then we calculate the intersection, the images that are associated to
+      // every tags
+      $items = array_shift($tag_images);
+      foreach ($tag_images as $images)
+      {
+        $items = array_intersect($items, $images);
+      }
+      return $items;
+      break;
+    }
+    case 'OR':
+    {
+      $query = '
+SELECT DISTINCT image_id
+  FROM '.IMAGE_TAG_TABLE.'
+  WHERE tag_id IN ('.implode(',', $tag_ids).')
+;';
+      return array_from_query($query, 'image_id');
+      break;
+    }
+    default:
+    {
+      die('get_image_ids_for_tags: unknown mode, only AND & OR are supported');
+    }
+  }
+}
+
+/**
+ * return a list of tags corresponding to given items.
+ *
+ * @param array items
+ * @param array max_tags
+ * @param array excluded_tag_ids
+ * @return array
+ */
+function get_common_tags($items, $max_tags, $excluded_tag_ids=null)
+{
+  if (empty($items))
+  {
+    return array();
+  }
+  $query = '
+SELECT t.*, count(*) counter
+  FROM '.IMAGE_TAG_TABLE.'
+    INNER JOIN '.TAGS_TABLE.' t ON tag_id = id
+  WHERE image_id IN ('.implode(',', $items).')';
+  if (!empty($excluded_tag_ids))
+  {
+    $query.='
+    AND tag_id NOT IN ('.implode(',', $excluded_tag_ids).')';
+  }
+  $query .='
+  GROUP BY tag_id';
+  if ($max_tags>0)
+  {
+    $query .= '
+  ORDER BY counter DESC
+  LIMIT 0,'.$max_tags;
+  }
+  else
+  {
+    $query .= '
+  ORDER BY NULL';
+  }
+
+  $result = pwg_query($query);
+  $tags = array();
+  while($row = mysql_fetch_assoc($result))
+  {
+    array_push($tags, $row);
+  }
+  usort($tags, 'tag_alpha_compare');
+  return $tags;
+}
+
+/**
+ * return a list of tags corresponding to any of ids, url_names, names
+ *
+ * @param array ids
+ * @param array url_names
+ * @param array names
+ * @return array
+ */
+function find_tags($ids, $url_names=array(), $names=array() )
+{
+  $where_clauses = array();
+  if ( !empty($ids) )
+  {
+    $where_clauses[] = 'id IN ('.implode(',', $ids).')';
+  }
+  if ( !empty($url_names) )
+  {
+    $where_clauses[] =
+      'url_name IN ('.
+      implode(
+        ',',
+        array_map(
+          create_function('$s', 'return "\'".$s."\'";'),
+          $url_names
+          )
+        )
+      .')';
+  }
+  if ( !empty($names) )
+  {
+    $where_clauses[] =
+      'name IN ('.
+      implode(
+        ',',
+        array_map(
+          create_function('$s', 'return "\'".$s."\'";'),
+          $names
+          )
+        )
+      .')';
+  }
+  if (empty($where_clauses))
+  {
+    return array();
+  }
+
+  $query = '
+SELECT *
+  FROM '.TAGS_TABLE.'
+  WHERE '. implode( '
+    OR ', $where_clauses);
+
+  $result = pwg_query($query);
+  $tags = array();
+  while ($row = mysql_fetch_assoc($result))
+  {
+    array_push($tags, $row);
+  }
+  return $tags;
+}
+?>
Index: /tags/2.0.2/include/functions_url.inc.php
===================================================================
--- /tags/2.0.2/include/functions_url.inc.php	(revision 3278)
+++ /tags/2.0.2/include/functions_url.inc.php	(revision 3278)
@@ -0,0 +1,729 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+
+/**
+ * returns a prefix for each url link on displayed page
+ * and return an empty string for current path
+ * @return string
+ */
+function get_root_url()
+{
+  global $page;
+  if ( isset($page['root_path']) )
+  {
+    $root_url = $page['root_path'];
+  }
+  else
+  {// TODO - add HERE the possibility to call PWG functions from external scripts
+    $root_url = PHPWG_ROOT_PATH;
+  }
+  if ( strncmp($root_url, './', 2) != 0 )
+  {
+    return $root_url;
+  }
+  else
+  {
+    return (string)substr($root_url, 2);
+  }
+}
+
+/**
+ * returns the absolute url to the root of PWG
+ * @param boolean with_scheme if false - does not add http://toto.com
+ */
+function get_absolute_root_url($with_scheme=true)
+{
+  // TODO - add HERE the possibility to call PWG functions from external scripts
+  $url = '';
+  if ($with_scheme)
+  {
+    if (empty($_SERVER['HTTPS']))
+    {
+      $url .= 'http://';
+    }
+    else
+    {
+      $url .= 'https://';
+    }
+    $url .= $_SERVER['HTTP_HOST'];
+    if ($_SERVER['SERVER_PORT'] != 80)
+    {
+      $url_port = ':'.$_SERVER['SERVER_PORT'];
+      if (strrchr($url, ':') != $url_port)
+      {
+        $url .= $url_port;
+      }
+    }
+  }
+  $url .= cookie_path();
+  return $url;
+}
+
+/**
+ * adds one or more _GET style parameters to an url
+ * example: add_url_params('/x', array('a'=>'b')) returns /x?a=b
+ * add_url_params('/x?cat_id=10', array('a'=>'b')) returns /x?cat_id=10&amp;a=b
+ * @param string url
+ * @param array params
+ * @return string
+ */
+function add_url_params($url, $params)
+{
+  if ( !empty($params) )
+  {
+    assert( is_array($params) );
+    $is_first = true;
+    foreach($params as $param=>$val)
+    {
+      if ($is_first)
+      {
+        $is_first = false;
+        $url .= ( strpos($url, '?')===false ) ? '?' :'&amp;';
+      }
+      else
+      {
+        $url .= '&amp;';
+      }
+      $url .= $param;
+      if (isset($val))
+      {
+        $url .= '='.$val;
+      }
+    }
+  }
+  return $url;
+}
+
+/**
+ * build an index URL for a specific section
+ *
+ * @param array
+ * @return string
+ */
+function make_index_url($params = array())
+{
+  global $conf;
+  $url = get_root_url().'index';
+  if ($conf['php_extension_in_urls'])
+  {
+    $url .= '.php';
+  }
+  if ($conf['question_mark_in_urls'])
+  {
+    $url .= '?';
+  }
+  $url.= make_section_in_url($params);
+  $url = add_well_known_params_in_url($url, $params);
+  return $url;
+}
+
+/**
+ * build an index URL with current page parameters, but with redefinitions
+ * and removes.
+ *
+ * duplicate_index_url( array(
+ *   'category' => array('id'=>12, 'name'=>'toto'),
+ *   array('start')
+ * ) will create an index URL on the current section (categories), but on
+ * a redefined category and without the start URL parameter.
+ *
+ * @param array redefined keys
+ * @param array removed keys
+ * @return string
+ */
+function duplicate_index_url($redefined = array(), $removed = array())
+{
+  return make_index_url(
+    params_for_duplication($redefined, $removed)
+    );
+}
+
+/**
+ * returns $page global array with key redefined and key removed
+ *
+ * @param array redefined keys
+ * @param array removed keys
+ * @return array
+ */
+function params_for_duplication($redefined, $removed)
+{
+  global $page;
+
+  $params = $page;
+
+  foreach ($removed as $param_key)
+  {
+    unset($params[$param_key]);
+  }
+
+  foreach ($redefined as $redefined_param => $redefined_value)
+  {
+    $params[$redefined_param] = $redefined_value;
+  }
+
+  return $params;
+}
+
+/**
+ * create a picture URL with current page parameters, but with redefinitions
+ * and removes. See duplicate_index_url.
+ *
+ * @param array redefined keys
+ * @param array removed keys
+ * @return string
+ */
+function duplicate_picture_url($redefined = array(), $removed = array())
+{
+  return make_picture_url(
+    params_for_duplication($redefined, $removed)
+    );
+}
+
+/**
+ * create a picture URL on a specific section for a specific picture
+ *
+ * @param array
+ * @return string
+ */
+function make_picture_url($params)
+{
+  global $conf;
+
+  isset($params['image_id']) or fatal_error('make_picture_url: image_id is a required parameter');
+
+  $url = get_root_url().'picture';
+  if ($conf['php_extension_in_urls'])
+  {
+    $url .= '.php';
+  }
+  if ($conf['question_mark_in_urls'])
+  {
+    $url .= '?';
+  }
+  $url.= '/';
+  switch ( $conf['picture_url_style'] )
+  {
+    case 'id-file':
+      $url .= $params['image_id'];
+      if ( isset($params['image_file']) )
+      {
+        $url .= '-'.get_filename_wo_extension($params['image_file']);
+      }
+      break;
+    case 'file':
+      if ( isset($params['image_file']) )
+      {
+        $fname_wo_ext = get_filename_wo_extension($params['image_file']);
+        if ( ord($fname_wo_ext)>ord('9') or !preg_match('/^\d+(-|$)/', $fname_wo_ext) )
+        {
+          $url .= $fname_wo_ext;
+          break;
+        }
+      }
+    default:
+      $url .= $params['image_id'];
+  }
+  if ( !isset($params['category'] ) )
+  {// make urls shorter ...
+    unset( $params['flat'] );
+  }
+  $url .= make_section_in_url($params);
+  $url = add_well_known_params_in_url($url, $params);
+  return $url;
+}
+
+/**
+ *adds to the url the chronology and start parameters
+*/
+function add_well_known_params_in_url($url, $params)
+{
+  if ( isset($params['chronology_field']) )
+  {
+    $url .= '/'. $params['chronology_field'];
+    $url .= '-'. $params['chronology_style'];
+    if ( isset($params['chronology_view']) )
+    {
+      $url .= '-'. $params['chronology_view'];
+    }
+    if ( !empty($params['chronology_date']) )
+    {
+      $url .= '-'. implode('-', $params['chronology_date'] );
+    }
+  }
+
+  if (isset($params['flat']))
+  {
+    $url.= '/flat';
+  }
+
+  if (isset($params['start']) and $params['start'] > 0)
+  {
+    $url.= '/start-'.$params['start'];
+  }
+  return $url;
+}
+
+/**
+ * return the section token of an index or picture URL.
+ *
+ * Depending on section, other parameters are required (see function code
+ * for details)
+ *
+ * @param array
+ * @return string
+ */
+function make_section_in_url($params)
+{
+  global $conf;
+  $section_string = '';
+
+  $section_of = array(
+    'category' => 'categories',
+    'tags'     => 'tags',
+    'list'     => 'list',
+    'search'   => 'search',
+    );
+
+  foreach ($section_of as $param => $section)
+  {
+    if (isset($params[$param]))
+    {
+      $params['section'] = $section;
+    }
+  }
+
+  if (!isset($params['section']))
+  {
+    $params['section'] = 'none';
+  }
+
+  switch($params['section'])
+  {
+    case 'categories' :
+    {
+      if (!isset($params['category']))
+      {
+        $section_string.= '/categories';
+      }
+      else
+      {
+        is_array($params['category']) or trigger_error(
+            'make_section_in_url wrong type for category', E_USER_WARNING
+            );
+        is_numeric($params['category']['id']) or trigger_error(
+            'make_section_in_url category id not numeric', E_USER_WARNING
+            );
+        isset($params['category']['name']) or trigger_error(
+            'make_section_in_url category name not set', E_USER_WARNING
+            );
+
+        array_key_exists('permalink', $params['category']) or trigger_error(
+            'make_section_in_url category permalink not set', E_USER_WARNING
+            );
+
+        $section_string.= '/category/';
+        if ( empty($params['category']['permalink']) )
+        {
+          $section_string.= $params['category']['id'];
+          if ( $conf['category_url_style']=='id-name' )
+          {
+            $section_string.= '-'.str2url($params['category']['name']);
+          }
+        }
+        else
+        {
+          $section_string.= $params['category']['permalink'];
+        }
+      }
+
+      break;
+    }
+    case 'tags' :
+    {
+      if (!isset($params['tags']) or count($params['tags']) == 0)
+      {
+        fatal_error('make_section_in_url: require at least one tag');
+      }
+
+      $section_string.= '/tags';
+
+      foreach ($params['tags'] as $tag)
+      {
+        switch ( $conf['tag_url_style'] )
+        {
+          case 'id':
+            $section_string.= '/'.$tag['id'];
+            break;
+          case 'tag':
+            if (isset($tag['url_name']) and !is_numeric($tag['url_name']) )
+            {
+              $section_string.= '/'.$tag['url_name'];
+              break;
+            }
+          default:
+            $section_string.= '/'.$tag['id'];
+            if (isset($tag['url_name']))
+            {
+              $section_string.= '-'.$tag['url_name'];
+            }
+        }
+      }
+
+      break;
+    }
+    case 'search' :
+    {
+      isset($params['search']) or fatal_error('make_section_in_url: require a search identifier');
+      $section_string.= '/search/'.$params['search'];
+      break;
+    }
+    case 'list' :
+    {
+      isset($params['list']) or fatal_error('make_section_in_url: require a list of items');
+      $section_string.= '/list/'.implode(',', $params['list']);
+      break;
+    }
+    case 'none' :
+    {
+      break;
+    }
+    default :
+    {
+      $section_string.= '/'.$params['section'];
+    }
+  }
+
+  return $section_string;
+}
+
+/**
+ * the reverse of make_section_in_url
+ * returns the 'section' (categories/tags/...) and the data associated with it
+ *
+ * Depending on section, other parameters are returned (category/tags/list/...)
+ *
+ * @param array of url tokens to parse
+ * @param int the index in the array of url tokens; in/out
+ * @return array
+ */
+function parse_section_url( $tokens, &$next_token)
+{
+  $page=array();
+  if (strncmp(@$tokens[$next_token], 'categor', 7)==0 )
+  {
+    $page['section'] = 'categories';
+    $next_token++;
+
+    if (isset($tokens[$next_token]) )
+    {
+      if (preg_match('/^(\d+)(?:-(.+))?$/', $tokens[$next_token], $matches))
+      {
+        if ( isset($matches[2]) )
+          $page['hit_by']['cat_url_name'] = $matches[2];
+        $page['category'] = $matches[1];
+        $next_token++;
+      }
+      else
+      {// try a permalink
+        $maybe_permalinks = array();
+        $current_token = $next_token;
+        while ( isset($tokens[$current_token])
+            and strpos($tokens[$current_token], 'created-')!==0
+            and strpos($tokens[$current_token], 'posted-')!==0
+            and strpos($tokens[$next_token], 'start-')!==0
+            and $tokens[$current_token] != 'flat')
+        {
+          if (empty($maybe_permalinks))
+          {
+            array_push($maybe_permalinks, $tokens[$current_token]);
+          }
+          else
+          {
+            array_push($maybe_permalinks,
+                $maybe_permalinks[count($maybe_permalinks)-1]
+                . '/' . $tokens[$current_token]
+              );
+          }
+          $current_token++;
+        }
+
+        if ( count($maybe_permalinks) )
+        {
+          $cat_id = get_cat_id_from_permalinks($maybe_permalinks, $perma_index);
+          if ( isset($cat_id) )
+          {
+            $next_token += $perma_index+1;
+            $page['category'] = $cat_id;
+            $page['hit_by']['cat_permalink'] = $maybe_permalinks[$perma_index];
+          }
+          else
+          {
+            page_not_found('Permalink for album not found');
+          }
+        }
+      }
+    }
+
+    if (isset($page['category']))
+    {
+      $result = get_cat_info($page['category']);
+      if (empty($result))
+      {
+        page_not_found('Requested category does not exist' );
+      }
+      $page['category']=$result;
+    }
+  }
+  elseif ( 'tags' == @$tokens[$next_token] )
+  {
+    $page['section'] = 'tags';
+    $page['tags'] = array();
+
+    $next_token++;
+    $i = $next_token;
+
+    $requested_tag_ids = array();
+    $requested_tag_url_names = array();
+
+    while (isset($tokens[$i]))
+    {
+      if (strpos($tokens[$i], 'created-')===0
+           or strpos($tokens[$i], 'posted-')===0
+           or strpos($tokens[$i], 'start-')===0 )
+        break;
+
+      if ( preg_match('/^(\d+)(?:-(.*))?/', $tokens[$i], $matches) )
+      {
+        array_push($requested_tag_ids, $matches[1]);
+      }
+      else
+      {
+        array_push($requested_tag_url_names, $tokens[$i]);
+      }
+      $i++;
+    }
+    $next_token = $i;
+
+    if ( empty($requested_tag_ids) && empty($requested_tag_url_names) )
+    {
+      bad_request('at least one tag required');
+    }
+
+    $page['tags'] = find_tags($requested_tag_ids, $requested_tag_url_names);
+    if ( empty($page['tags']) )
+    {
+      page_not_found('Requested tag does not exist', get_root_url().'tags.php' );
+    }
+  }
+  elseif ( 'favorites' == @$tokens[$next_token] )
+  {
+    $page['section'] = 'favorites';
+    $next_token++;
+  }
+  elseif ('most_visited' == @$tokens[$next_token])
+  {
+    $page['section'] = 'most_visited';
+    $next_token++;
+  }
+  elseif ('best_rated' == @$tokens[$next_token])
+  {
+    $page['section'] = 'best_rated';
+    $next_token++;
+  }
+  elseif ('recent_pics' == @$tokens[$next_token])
+  {
+    $page['section'] = 'recent_pics';
+    $next_token++;
+  }
+  elseif ('recent_cats' == @$tokens[$next_token])
+  {
+    $page['section'] = 'recent_cats';
+    $next_token++;
+  }
+  elseif ('search' == @$tokens[$next_token])
+  {
+    $page['section'] = 'search';
+    $next_token++;
+
+    preg_match('/(\d+)/', @$tokens[$next_token], $matches);
+    if (!isset($matches[1]))
+    {
+      bad_request('search identifier is missing');
+    }
+    $page['search'] = $matches[1];
+    $next_token++;
+  }
+  elseif ('list' == @$tokens[$next_token])
+  {
+    $page['section'] = 'list';
+    $next_token++;
+
+    $page['list'] = array();
+
+    // No pictures
+    if (empty($tokens[$next_token]))
+    {
+      // Add dummy element list
+      array_push($page['list'], -1);
+    }
+    // With pictures list
+    else
+    {
+      if (!preg_match('/^\d+(,\d+)*$/', $tokens[$next_token]))
+      {
+        bad_request('wrong format on list GET parameter');
+      }
+      foreach (explode(',', $tokens[$next_token]) as $image_id)
+      {
+        array_push($page['list'], $image_id);
+      }
+    }
+    $next_token++;
+  }
+  return $page;
+}
+
+/**
+ * the reverse of add_well_known_params_in_url
+ * parses start, flat and chronology from url tokens
+*/
+function parse_well_known_params_url($tokens, &$i)
+{
+  $page = array();
+  while (isset($tokens[$i]))
+  {
+    if ( 'flat' == $tokens[$i] )
+    {
+      // indicate a special list of images
+      $page['flat'] = true;
+    }
+    elseif (strpos($tokens[$i], 'created-')===0 or strpos($tokens[$i], 'posted-')===0)
+    {
+      $chronology_tokens = explode('-', $tokens[$i] );
+
+      $page['chronology_field'] = $chronology_tokens[0];
+
+      array_shift($chronology_tokens);
+      $page['chronology_style'] = $chronology_tokens[0];
+
+      array_shift($chronology_tokens);
+      if ( count($chronology_tokens)>0 )
+      {
+        if ('list'==$chronology_tokens[0] or
+            'calendar'==$chronology_tokens[0])
+        {
+          $page['chronology_view'] = $chronology_tokens[0];
+          array_shift($chronology_tokens);
+        }
+        $page['chronology_date'] = $chronology_tokens;
+      }
+    }
+    elseif (preg_match('/^start-(\d+)/', $tokens[$i], $matches))
+    {
+      $page['start'] = $matches[1];
+    }
+    $i++;
+  }
+  return $page;
+}
+
+/**
+ * Indicate to build url with full path
+ *
+ * @param null
+ * @return null
+ */
+function set_make_full_url()
+{
+  global $page;
+
+  if (!isset($page['save_root_path']))
+  {
+    if (isset($page['root_path']))
+    {
+      $page['save_root_path']['path'] = $page['root_path'];
+    }
+    $page['save_root_path']['count'] = 1;
+    $page['root_path'] = get_absolute_root_url();
+  }
+  else
+  {
+    $page['save_root_path']['count'] += 1;
+  }
+}
+
+/**
+ * Restore old parameter to build url with full path
+ *
+ * @param null
+ * @return null
+ */
+function unset_make_full_url()
+{
+  global $page;
+
+  if (isset($page['save_root_path']))
+  {
+    if ($page['save_root_path']['count'] == 1)
+    {
+      if (isset($page['save_root_path']['path']))
+      {
+        $page['root_path'] = $page['save_root_path']['path'];
+      }
+      else
+      {
+        unset($page['root_path']);
+      }
+      unset($page['save_root_path']);
+    }
+    else
+    {
+      $page['save_root_path']['count'] -= 1;
+    }
+  }
+}
+
+/**
+ * Embellish the url argument
+ *
+ * @param $url
+ * @return $url embellished
+ */
+function embellish_url($url)
+{
+  $url = str_replace('/./', '/', $url);
+  while ( ($dotdot = strpos($url, '/../', 1) ) !== false )
+  {
+    $before = strrpos($url, '/', -(strlen($url)-$dotdot+1) );
+    if ($before !== false)
+    {
+      $url = substr_replace($url, '', $before, $dotdot-$before+3);
+    }
+    else
+      break;
+  }
+  return $url;
+}
+
+?>
Index: /tags/2.0.2/include/functions_user.inc.php
===================================================================
--- /tags/2.0.2/include/functions_user.inc.php	(revision 3278)
+++ /tags/2.0.2/include/functions_user.inc.php	(revision 3278)
@@ -0,0 +1,1325 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// validate_mail_address:
+//   o verifies whether the given mail address has the
+//     right format. ie someone@domain.com "someone" can contain ".", "-" or
+//     even "_". Exactly as "domain". The extension doesn't have to be
+//     "com". The mail address can also be empty.
+//   o check if address could be empty
+//   o check if address is not used by a other user
+// If the mail address doesn't correspond, an error message is returned.
+//
+function validate_mail_address($user_id, $mail_address)
+{
+  global $conf;
+
+  if (empty($mail_address) and
+      !($conf['obligatory_user_mail_address'] and
+      in_array(script_basename(), array('register', 'profile'))))
+  {
+    return '';
+  }
+
+  $atom   = '[-a-z0-9!#$%&\'*+\\/=?^_`{|}~]';   // before  arobase
+  $domain = '([a-z0-9]([-a-z0-9]*[a-z0-9]+)?)'; // domain name
+  $regex = '/^' . $atom . '+' . '(\.' . $atom . '+)*' . '@' . '(' . $domain . '{1,63}\.)+' . $domain . '{2,63}$/i';
+
+  if ( !preg_match( $regex, $mail_address ) )
+  {
+    return l10n('reg_err_mail_address');
+  }
+
+  if (defined("PHPWG_INSTALLED") and !empty($mail_address))
+  {
+    $query = '
+select count(*)
+from '.USERS_TABLE.'
+where upper('.$conf['user_fields']['email'].') = upper(\''.$mail_address.'\')
+'.(is_numeric($user_id) ? 'and '.$conf['user_fields']['id'].' != \''.$user_id.'\'' : '').'
+;';
+    list($count) = mysql_fetch_array(pwg_query($query));
+    if ($count != 0)
+    {
+      return l10n('reg_err_mail_address_dbl');
+    }
+  }
+}
+
+function register_user($login, $password, $mail_address,
+  $with_notification = true, $errors = array())
+{
+  global $conf;
+
+  if ($login == '')
+  {
+    array_push($errors, l10n('reg_err_login1'));
+  }
+  if (ereg("^.* $", $login))
+  {
+    array_push($errors, l10n('reg_err_login2'));
+  }
+  if (ereg("^ .*$", $login))
+  {
+    array_push($errors, l10n('reg_err_login3'));
+  }
+  if (get_userid($login))
+  {
+    array_push($errors, l10n('reg_err_login5'));
+  }
+  $mail_error = validate_mail_address(null, $mail_address);
+  if ('' != $mail_error)
+  {
+    array_push($errors, $mail_error);
+  }
+
+  $errors = trigger_event('register_user_check',
+              $errors,
+              array(
+                'username'=>$login,
+                'password'=>$password,
+                'email'=>$mail_address,
+              )
+            );
+
+  // if no error until here, registration of the user
+  if (count($errors) == 0)
+  {
+    // what will be the inserted id ?
+    $query = '
+SELECT MAX('.$conf['user_fields']['id'].') + 1
+  FROM '.USERS_TABLE.'
+;';
+    list($next_id) = mysql_fetch_array(pwg_query($query));
+
+    $insert =
+      array(
+        $conf['user_fields']['id'] => $next_id,
+        $conf['user_fields']['username'] => mysql_real_escape_string($login),
+        $conf['user_fields']['password'] => $conf['pass_convert']($password),
+        $conf['user_fields']['email'] => $mail_address
+        );
+
+    include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+    mass_inserts(USERS_TABLE, array_keys($insert), array($insert));
+
+    // Assign by default groups
+    {
+      $query = '
+SELECT id
+  FROM '.GROUPS_TABLE.'
+  WHERE is_default = \''.boolean_to_string(true).'\'
+  ORDER BY id ASC
+;';
+      $result = pwg_query($query);
+
+      $inserts = array();
+      while ($row = mysql_fetch_array($result))
+      {
+        array_push
+        (
+          $inserts,
+          array
+          (
+            'user_id' => $next_id,
+            'group_id' => $row['id']
+          )
+        );
+      }
+    }
+
+    if (count($inserts) != 0)
+    {
+      include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+      mass_inserts(USER_GROUP_TABLE, array('user_id', 'group_id'), $inserts);
+    }
+
+    $override = null;
+    if ($with_notification and $conf['browser_language'])
+    {
+      if ( !get_browser_language($override['language']) )
+        $override=null;
+    }
+    create_user_infos($next_id, $override);
+
+    if ($with_notification and $conf['email_admin_on_new_user'])
+    {
+      include_once(PHPWG_ROOT_PATH.'include/functions_mail.inc.php');
+      $admin_url = get_absolute_root_url()
+                   .'admin.php?page=user_list&username='.$login;
+
+      $keyargs_content = array
+      (
+        get_l10n_args('User: %s', $login),
+        get_l10n_args('Email: %s', $_POST['mail_address']),
+        get_l10n_args('', ''),
+        get_l10n_args('Admin: %s', $admin_url)
+      );
+
+      pwg_mail_notification_admins
+      (
+        get_l10n_args('Registration of %s', $login),
+        $keyargs_content
+      );
+    }
+
+    trigger_action('register_user',
+      array(
+        'id'=>$next_id,
+        'username'=>$login,
+        'email'=>$mail_address,
+       )
+      );
+  }
+
+  return $errors;
+}
+
+function build_user( $user_id, $use_cache )
+{
+  global $conf;
+
+  $user['id'] = $user_id;
+  $user = array_merge( $user, getuserdata($user_id, $use_cache) );
+
+  if ($user['id'] == $conf['guest_id'] and $user['status'] <> 'guest')
+  {
+    $user['status'] = 'guest';
+    $user['internal_status']['guest_must_be_guest'] = true;
+  }
+
+  // calculation of the number of picture to display per page
+  $user['nb_image_page'] = $user['nb_image_line'] * $user['nb_line_page'];
+
+  list($user['template'], $user['theme']) = explode('/', $user['template']);
+
+  return $user;
+}
+
+/**
+ * find informations related to the user identifier
+ *
+ * @param int user identifier
+ * @param boolean use_cache
+ * @param array
+ */
+function getuserdata($user_id, $use_cache)
+{
+  global $conf;
+
+  $userdata = array();
+
+  $query = '
+SELECT ';
+  $is_first = true;
+  foreach ($conf['user_fields'] as $pwgfield => $dbfield)
+  {
+    if ($is_first)
+    {
+      $is_first = false;
+    }
+    else
+    {
+      $query.= '
+     , ';
+    }
+    $query.= $dbfield.' AS '.$pwgfield;
+  }
+  $query.= '
+  FROM '.USERS_TABLE.'
+  WHERE '.$conf['user_fields']['id'].' = \''.$user_id.'\'
+;';
+
+  $row = mysql_fetch_array(pwg_query($query));
+
+  while (true)
+  {
+    $query = '
+SELECT ui.*, uc.*
+  FROM '.USER_INFOS_TABLE.' AS ui LEFT JOIN '.USER_CACHE_TABLE.' AS uc
+    ON ui.user_id = uc.user_id
+  WHERE ui.user_id = \''.$user_id.'\'
+;';
+    $result = pwg_query($query);
+    if (mysql_num_rows($result) > 0)
+    {
+      break;
+    }
+    else
+    {
+      create_user_infos($user_id);
+    }
+  }
+
+  $row = array_merge($row, mysql_fetch_array($result));
+
+  foreach ($row as $key => $value)
+  {
+    if (!is_numeric($key))
+    {
+      // If the field is true or false, the variable is transformed into a
+      // boolean value.
+      if ($value == 'true' or $value == 'false')
+      {
+        $userdata[$key] = get_boolean($value);
+      }
+      else
+      {
+        $userdata[$key] = $value;
+      }
+    }
+  }
+
+  if ($use_cache)
+  {
+    if (!isset($userdata['need_update'])
+        or !is_bool($userdata['need_update'])
+        or $userdata['need_update'] == true)
+    {
+      $userdata['cache_update_time'] = time();
+
+      // Set need update are done
+      $userdata['need_update'] = false;
+
+      $userdata['forbidden_categories'] =
+        calculate_permissions($userdata['id'], $userdata['status']);
+
+      /* now we build the list of forbidden images (this list does not contain
+      images that are not in at least an authorized category)*/
+      $query = '
+SELECT DISTINCT(id)
+  FROM '.IMAGES_TABLE.' INNER JOIN '.IMAGE_CATEGORY_TABLE.' ON id=image_id
+  WHERE category_id NOT IN ('.$userdata['forbidden_categories'].')
+    AND level>'.$userdata['level'];
+      $forbidden_ids = array_from_query($query, 'id');
+
+      if ( empty($forbidden_ids) )
+      {
+        array_push( $forbidden_ids, 0 );
+      }
+      $userdata['image_access_type'] = 'NOT IN'; //TODO maybe later
+      $userdata['image_access_list'] = implode(',',$forbidden_ids);
+
+      update_user_cache_categories($userdata);
+
+      $query = '
+SELECT COUNT(DISTINCT(image_id)) as total
+  FROM '.IMAGE_CATEGORY_TABLE.'
+  WHERE category_id NOT IN ('.$userdata['forbidden_categories'].')
+    AND image_id '.$userdata['image_access_type'].' ('.$userdata['image_access_list'].')
+;';
+      list($userdata['nb_total_images']) = mysql_fetch_array(pwg_query($query));
+
+      // update user cache
+      $query = '
+DELETE FROM '.USER_CACHE_TABLE.'
+  WHERE user_id = '.$userdata['id'].'
+;';
+      pwg_query($query);
+
+      $query = '
+INSERT INTO '.USER_CACHE_TABLE.'
+  (user_id, need_update, cache_update_time, forbidden_categories, nb_total_images,
+    image_access_type, image_access_list)
+  VALUES
+  ('.$userdata['id'].',\''.boolean_to_string($userdata['need_update']).'\','
+  .$userdata['cache_update_time'].',\''
+  .$userdata['forbidden_categories'].'\','.$userdata['nb_total_images'].',"'
+  .$userdata['image_access_type'].'","'.$userdata['image_access_list'].'")
+;';
+      pwg_query($query);
+    }
+  }
+
+  return $userdata;
+}
+
+/*
+ * deletes favorites of the current user if he's not allowed to see them
+ *
+ * @return void
+ */
+function check_user_favorites()
+{
+  global $user;
+
+  if ($user['forbidden_categories'] == '')
+  {
+    return;
+  }
+
+  // $filter['visible_categories'] and $filter['visible_images']
+  // must be not used because filter <> restriction
+  // retrieving images allowed : belonging to at least one authorized
+  // category
+  $query = '
+SELECT DISTINCT f.image_id
+  FROM '.FAVORITES_TABLE.' AS f INNER JOIN '.IMAGE_CATEGORY_TABLE.' AS ic
+    ON f.image_id = ic.image_id
+  WHERE f.user_id = '.$user['id'].'
+'.get_sql_condition_FandF
+  (
+    array
+      (
+        'forbidden_categories' => 'ic.category_id',
+      ),
+    'AND'
+  ).'
+;';
+  $result = pwg_query($query);
+  $authorizeds = array();
+  while ($row = mysql_fetch_array($result))
+  {
+    array_push($authorizeds, $row['image_id']);
+  }
+
+  $query = '
+SELECT image_id
+  FROM '.FAVORITES_TABLE.'
+  WHERE user_id = '.$user['id'].'
+;';
+  $result = pwg_query($query);
+  $favorites = array();
+  while ($row = mysql_fetch_array($result))
+  {
+    array_push($favorites, $row['image_id']);
+  }
+
+  $to_deletes = array_diff($favorites, $authorizeds);
+
+  if (count($to_deletes) > 0)
+  {
+    $query = '
+DELETE FROM '.FAVORITES_TABLE.'
+  WHERE image_id IN ('.implode(',', $to_deletes).')
+    AND user_id = '.$user['id'].'
+;';
+    pwg_query($query);
+  }
+}
+
+/**
+ * calculates the list of forbidden categories for a given user
+ *
+ * Calculation is based on private categories minus categories authorized to
+ * the groups the user belongs to minus the categories directly authorized
+ * to the user. The list contains at least -1 to be compliant with queries
+ * such as "WHERE category_id NOT IN ($forbidden_categories)"
+ *
+ * @param int user_id
+ * @param string user_status
+ * @return string forbidden_categories
+ */
+function calculate_permissions($user_id, $user_status)
+{
+  $private_array = array();
+  $authorized_array = array();
+
+  $query = '
+SELECT id
+  FROM '.CATEGORIES_TABLE.'
+  WHERE status = \'private\'
+;';
+  $result = pwg_query($query);
+  while ($row = mysql_fetch_array($result))
+  {
+    array_push($private_array, $row['id']);
+  }
+
+  // retrieve category ids directly authorized to the user
+  $query = '
+SELECT cat_id
+  FROM '.USER_ACCESS_TABLE.'
+  WHERE user_id = '.$user_id.'
+;';
+  $authorized_array = array_from_query($query, 'cat_id');
+
+  // retrieve category ids authorized to the groups the user belongs to
+  $query = '
+SELECT cat_id
+  FROM '.USER_GROUP_TABLE.' AS ug INNER JOIN '.GROUP_ACCESS_TABLE.' AS ga
+    ON ug.group_id = ga.group_id
+  WHERE ug.user_id = '.$user_id.'
+;';
+  $authorized_array =
+    array_merge(
+      $authorized_array,
+      array_from_query($query, 'cat_id')
+      );
+
+  // uniquify ids : some private categories might be authorized for the
+  // groups and for the user
+  $authorized_array = array_unique($authorized_array);
+
+  // only unauthorized private categories are forbidden
+  $forbidden_array = array_diff($private_array, $authorized_array);
+
+  // if user is not an admin, locked categories are forbidden
+  if (!is_admin($user_status))
+  {
+    $query = '
+SELECT id
+  FROM '.CATEGORIES_TABLE.'
+  WHERE visible = \'false\'
+;';
+    $result = pwg_query($query);
+    while ($row = mysql_fetch_array($result))
+    {
+      array_push($forbidden_array, $row['id']);
+    }
+    $forbidden_array = array_unique($forbidden_array);
+  }
+
+  if ( empty($forbidden_array) )
+  {// at least, the list contains 0 value. This category does not exists so
+   // where clauses such as "WHERE category_id NOT IN(0)" will always be
+   // true.
+    array_push($forbidden_array, 0);
+  }
+
+  return implode(',', $forbidden_array);
+}
+
+/**
+ * compute data of categories branches (one branch only)
+ */
+function compute_branch_cat_data(&$cats, &$list_cat_id, &$level, &$ref_level)
+{
+  $date = '';
+  $count_images = 0;
+  $count_categories = 0;
+  do
+  {
+    $cat_id = array_pop($list_cat_id);
+    if (!is_null($cat_id))
+    {
+      // Count images and categories
+      $cats[$cat_id]['count_images'] += $count_images;
+      $cats[$cat_id]['count_categories'] += $count_categories;
+      $count_images = $cats[$cat_id]['count_images'];
+      $count_categories = $cats[$cat_id]['count_categories'] + 1;
+
+      if ((empty($cats[$cat_id]['max_date_last'])) or ($cats[$cat_id]['max_date_last'] < $date))
+      {
+        $cats[$cat_id]['max_date_last'] = $date;
+      }
+      else
+      {
+        $date = $cats[$cat_id]['max_date_last'];
+      }
+      $ref_level = substr_count($cats[$cat_id]['global_rank'], '.') + 1;
+    }
+    else
+    {
+      $ref_level = 0;
+    }
+  } while ($level <= $ref_level);
+
+  // Last cat updating must be added to list for next branch
+  if ($ref_level <> 0)
+  {
+    array_push($list_cat_id, $cat_id);
+  }
+}
+
+/**
+ * compute data of categories branches
+ */
+function compute_categories_data(&$cats)
+{
+  $ref_level = 0;
+  $level = 0;
+  $list_cat_id = array();
+
+  foreach ($cats as $id => $category)
+  {
+    // Compute
+    $level = substr_count($category['global_rank'], '.') + 1;
+    if ($level > $ref_level)
+    {
+      array_push($list_cat_id, $id);
+    }
+    else
+    {
+      compute_branch_cat_data($cats, $list_cat_id, $level, $ref_level);
+      array_push($list_cat_id, $id);
+    }
+    $ref_level = $level;
+  }
+
+  $level = 1;
+  compute_branch_cat_data($cats, $list_cat_id, $level, $ref_level);
+}
+
+/**
+ * get computed array of categories
+ *
+ * @param array userdata
+ * @param int filter_days number of recent days to filter on or null
+ * @return array
+ */
+function get_computed_categories($userdata, $filter_days=null)
+{
+  $query = 'SELECT c.id cat_id, global_rank';
+  // Count by date_available to avoid count null
+  $query .= ',
+  MAX(date_available) date_last, COUNT(date_available) nb_images
+FROM '.CATEGORIES_TABLE.' as c
+  LEFT JOIN '.IMAGE_CATEGORY_TABLE.' AS ic ON ic.category_id = c.id
+  LEFT JOIN '.IMAGES_TABLE.' AS i
+    ON ic.image_id = i.id
+      AND i.level<='.$userdata['level'];
+
+  if ( isset($filter_days) )
+  {
+    $query .= ' AND i.date_available > SUBDATE(CURRENT_DATE,INTERVAL '.$filter_days.' DAY)';
+  }
+
+  if ( !empty($userdata['forbidden_categories']) )
+  {
+    $query.= '
+  WHERE c.id NOT IN ('.$userdata['forbidden_categories'].')';
+  }
+
+  $query.= '
+  GROUP BY c.id';
+
+  $result = pwg_query($query);
+
+  $cats = array();
+  while ($row = mysql_fetch_assoc($result))
+  {
+    $row['user_id'] = $userdata['id'];
+    $row['count_categories'] = 0;
+    $row['count_images'] = (int)$row['nb_images'];
+    $row['max_date_last'] = $row['date_last'];
+
+    $cats += array($row['cat_id'] => $row);
+  }
+  usort($cats, 'global_rank_compare');
+
+  compute_categories_data($cats);
+
+  if ( isset($filter_days) )
+  {
+    $cat_tmp = $cats;
+    $cats = array();
+
+    foreach ($cat_tmp as $category)
+    {
+      if (!empty($category['max_date_last']))
+      {
+        // Re-init counters
+        $category['count_categories'] = 0;
+        $category['count_images'] = (int)$category['nb_images'];
+        // Keep category
+        $cats[$category['cat_id']] = $category;
+      }
+    }
+    // Compute a second time
+    compute_categories_data($cats);
+  }
+  return $cats;
+}
+
+/**
+ * update data of user_cache_categories
+ *
+ * @param array userdata
+ * @return null
+ */
+function update_user_cache_categories($userdata)
+{
+  // delete user cache
+  $query = '
+DELETE FROM '.USER_CACHE_CATEGORIES_TABLE.'
+  WHERE user_id = '.$userdata['id'].'
+;';
+  pwg_query($query);
+
+  $cats = get_computed_categories($userdata, null);
+
+  include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+  mass_inserts
+  (
+    USER_CACHE_CATEGORIES_TABLE,
+    array
+    (
+      'user_id', 'cat_id',
+      'date_last', 'max_date_last', 'nb_images', 'count_images', 'count_categories'
+    ),
+    $cats
+  );
+}
+
+/**
+ * returns user identifier thanks to his name, false if not found
+ *
+ * @param string username
+ * @param int user identifier
+ */
+function get_userid($username)
+{
+  global $conf;
+
+  $username = mysql_real_escape_string($username);
+
+  $query = '
+SELECT '.$conf['user_fields']['id'].'
+  FROM '.USERS_TABLE.'
+  WHERE '.$conf['user_fields']['username'].' = \''.$username.'\'
+;';
+  $result = pwg_query($query);
+
+  if (mysql_num_rows($result) == 0)
+  {
+    return false;
+  }
+  else
+  {
+    list($user_id) = mysql_fetch_row($result);
+    return $user_id;
+  }
+}
+
+/**
+ * search an available feed_id
+ *
+ * @return string feed identifier
+ */
+function find_available_feed_id()
+{
+  while (true)
+  {
+    $key = generate_key(50);
+    $query = '
+SELECT COUNT(*)
+  FROM '.USER_FEED_TABLE.'
+  WHERE id = \''.$key.'\'
+;';
+    list($count) = mysql_fetch_row(pwg_query($query));
+    if (0 == $count)
+    {
+      return $key;
+    }
+  }
+}
+
+/*
+ * Returns a array with default user value
+ *
+ * @param convert_str allows to convert string value if necessary
+ */
+function get_default_user_info($convert_str = true)
+{
+  global $cache, $conf;
+
+  if (!isset($cache['default_user']))
+  {
+    $query = 'SELECT * FROM '.USER_INFOS_TABLE.
+            ' WHERE user_id = '.$conf['default_user_id'].';';
+
+    $result = pwg_query($query);
+    $cache['default_user'] = mysql_fetch_assoc($result);
+
+    if ($cache['default_user'] !== false)
+    {
+      unset($cache['default_user']['user_id']);
+      unset($cache['default_user']['status']);
+      unset($cache['default_user']['registration_date']);
+    }
+  }
+
+  if (is_array($cache['default_user']) and $convert_str)
+  {
+    $default_user = array();
+    foreach ($cache['default_user'] as $name => $value)
+    {
+      // If the field is true or false, the variable is transformed into a
+      // boolean value.
+      if ($value == 'true' or $value == 'false')
+      {
+        $default_user[$name] = get_boolean($value);
+      }
+      else
+      {
+        $default_user[$name] = $value;
+      }
+    }
+    return $default_user;
+  }
+  else
+  {
+    return $cache['default_user'];
+  }
+}
+
+/*
+ * Returns a default user value
+ *
+ * @param value_name: name of value
+ * @param sos_value: value used if don't exist value
+ */
+function get_default_user_value($value_name, $sos_value)
+{
+  $default_user = get_default_user_info(true);
+  if ($default_user === false or !isset($default_user[$value_name]))
+  {
+    return $sos_value;
+  }
+  else
+  {
+   return $default_user[$value_name];
+  }
+}
+
+/*
+ * Returns the default template value
+ *
+ */
+function get_default_template()
+{
+  return get_default_user_value('template', PHPWG_DEFAULT_TEMPLATE);
+}
+
+/*
+ * Returns the default language value
+ *
+ */
+function get_default_language()
+{
+  return get_default_user_value('language', PHPWG_DEFAULT_LANGUAGE);
+}
+
+/**
+  * Returns true if the browser language value is set into param $lang
+  *
+  */
+function get_browser_language(&$lang)
+{
+  $browser_language = substr(@$_SERVER["HTTP_ACCEPT_LANGUAGE"], 0, 2);
+  foreach (get_languages() as $language_code => $language_name)
+  {
+    if (substr($language_code, 0, 2) == $browser_language)
+    {
+      $lang = $language_code;
+      return true;
+    }
+  }
+  return false;
+}
+
+/**
+ * add user informations based on default values
+ *
+ * @param int user_id / array of user_if
+ * @param array of values used to override default user values
+ */
+function create_user_infos($arg_id, $override_values = null)
+{
+  global $conf;
+
+  if (is_array($arg_id))
+  {
+    $user_ids = $arg_id;
+  }
+  else
+  {
+    $user_ids = array();
+    if (is_numeric($arg_id))
+    {
+      $user_ids[] = $arg_id;
+    }
+  }
+
+  if (!empty($user_ids))
+  {
+    $inserts = array();
+    list($dbnow) = mysql_fetch_row(pwg_query('SELECT NOW();'));
+
+    $default_user = get_default_user_info(false);
+    if ($default_user === false)
+    {
+      // Default on structure are used
+      $default_user = array();
+    }
+
+    if (!is_null($override_values))
+    {
+      $default_user = array_merge($default_user, $override_values);
+    }
+
+    foreach ($user_ids as $user_id)
+    {
+      $level= isset($default_user['level']) ? $default_user['level'] : 0;
+      if ($user_id == $conf['webmaster_id'])
+      {
+        $status = 'webmaster';
+        $level = max( $conf['available_permission_levels'] );
+      }
+      else if (($user_id == $conf['guest_id']) or
+               ($user_id == $conf['default_user_id']))
+      {
+        $status = 'guest';
+      }
+      else
+      {
+        $status = 'normal';
+      }
+
+      $insert = array_merge(
+        $default_user,
+        array(
+          'user_id' => $user_id,
+          'status' => $status,
+          'registration_date' => $dbnow,
+          'level' => $level
+          ));
+
+      array_push($inserts, $insert);
+    }
+
+    include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+    mass_inserts(USER_INFOS_TABLE, array_keys($inserts[0]), $inserts);
+
+  }
+}
+
+/**
+ * returns the auto login key or false on error
+ * @param int user_id
+ * @param time_t time
+ * @param string [out] username
+*/
+function calculate_auto_login_key($user_id, $time, &$username)
+{
+  global $conf;
+  $query = '
+SELECT '.$conf['user_fields']['username'].' AS username
+  , '.$conf['user_fields']['password'].' AS password
+FROM '.USERS_TABLE.'
+WHERE '.$conf['user_fields']['id'].' = '.$user_id;
+  $result = pwg_query($query);
+  if (mysql_num_rows($result) > 0)
+  {
+    $row = mysql_fetch_assoc($result);
+    $username = $row['username'];
+    $data = $time.$row['username'].$row['password'];
+    $key = base64_encode(
+      pack('H*', sha1($data))
+      .hash_hmac('md5', $data, $conf['secret_key'],true)
+      );
+    return $key;
+  }
+  return false;
+}
+
+/*
+ * Performs all required actions for user login
+ * @param int user_id
+ * @param bool remember_me
+ * @return void
+*/
+function log_user($user_id, $remember_me)
+{
+  global $conf, $user;
+
+  if ($remember_me and $conf['authorize_remembering'])
+  {
+    $now = time();
+    $key = calculate_auto_login_key($user_id, $now, $username);
+    if ($key!==false)
+    {
+      $cookie = $user_id.'-'.$now.'-'.$key;
+      if (version_compare(PHP_VERSION, '5.2', '>=') )
+      {
+        setcookie($conf['remember_me_name'],
+            $cookie,
+            time()+$conf['remember_me_length'],
+            cookie_path(),ini_get('session.cookie_domain'),ini_get('session.cookie_secure'),
+            ini_get('session.cookie_httponly')
+          );
+      }
+      else
+      {
+        setcookie($conf['remember_me_name'],
+            $cookie,
+            time()+$conf['remember_me_length'],
+            cookie_path(),ini_get('session.cookie_domain'),ini_get('session.cookie_secure')
+          );
+      }
+    }
+  }
+  else
+  { // make sure we clean any remember me ...
+    setcookie($conf['remember_me_name'], '', 0, cookie_path(),ini_get('session.cookie_domain'));
+  }
+  if ( session_id()!="" )
+  { // we regenerate the session for security reasons
+    // see http://www.acros.si/papers/session_fixation.pdf
+    session_regenerate_id();
+  }
+  else
+  {
+    session_start();
+  }
+  $_SESSION['pwg_uid'] = (int)$user_id;
+
+  $user['id'] = $_SESSION['pwg_uid'];
+}
+
+/*
+ * Performs auto-connexion when cookie remember_me exists
+ * @return true/false
+*/
+function auto_login() {
+  global $conf;
+
+  if ( isset( $_COOKIE[$conf['remember_me_name']] ) )
+  {
+    $cookie = explode('-', stripslashes($_COOKIE[$conf['remember_me_name']]));
+    if ( count($cookie)===3
+        and is_numeric(@$cookie[0]) /*user id*/
+        and is_numeric(@$cookie[1]) /*time*/
+        and time()-$conf['remember_me_length']<=@$cookie[1]
+        and time()>=@$cookie[1] /*cookie generated in the past*/ )
+    {
+      $key = calculate_auto_login_key( $cookie[0], $cookie[1], $username );
+      if ($key!==false and $key===$cookie[2])
+      {
+        log_user($cookie[0], true);
+        trigger_action('login_success', $username);
+        return true;
+      }
+    }
+    setcookie($conf['remember_me_name'], '', 0, cookie_path(),ini_get('session.cookie_domain'));
+  }
+  return false;
+}
+
+/**
+ * Tries to login a user given username and password (must be MySql escaped)
+ * return true on success
+ */
+function try_log_user($username, $password, $remember_me)
+{
+  global $conf;
+  // retrieving the encrypted password of the login submitted
+  $query = '
+SELECT '.$conf['user_fields']['id'].' AS id,
+       '.$conf['user_fields']['password'].' AS password
+  FROM '.USERS_TABLE.'
+  WHERE '.$conf['user_fields']['username'].' = \''.$username.'\'
+;';
+  $row = mysql_fetch_assoc(pwg_query($query));
+  if ($row['password'] == $conf['pass_convert']($password))
+  {
+    log_user($row['id'], $remember_me);
+    trigger_action('login_success', $username);
+    return true;
+  }
+  trigger_action('login_failure', $username);
+  return false;
+}
+
+/** Performs all the cleanup on user logout */
+function logout_user()
+{
+  global $conf;
+  $_SESSION = array();
+  session_unset();
+  session_destroy();
+  setcookie(session_name(),'',0,
+      ini_get('session.cookie_path'),
+      ini_get('session.cookie_domain')
+    );
+  setcookie($conf['remember_me_name'], '', 0, cookie_path(),ini_get('session.cookie_domain'));
+}
+
+/*
+ * Return user status used in this library
+ * @return string
+*/
+function get_user_status($user_status)
+{
+  global $user;
+
+  if (empty($user_status))
+  {
+    if (isset($user['status']))
+    {
+      $user_status = $user['status'];
+    }
+    else
+    {
+      // swicth to default value
+      $user_status = '';
+    }
+  }
+  return $user_status;
+}
+
+/*
+ * Return access_type definition of user
+ * Test does with user status
+ * @return bool
+*/
+function get_access_type_status($user_status='')
+{
+  global $conf;
+
+  switch (get_user_status($user_status))
+  {
+    case 'guest':
+    {
+      $access_type_status =
+        ($conf['guest_access'] ? ACCESS_GUEST : ACCESS_FREE);
+      break;
+    }
+    case 'generic':
+    {
+      $access_type_status = ACCESS_GUEST;
+      break;
+    }
+    case 'normal':
+    {
+      $access_type_status = ACCESS_CLASSIC;
+      break;
+    }
+    case 'admin':
+    {
+      $access_type_status = ACCESS_ADMINISTRATOR;
+      break;
+    }
+    case 'webmaster':
+    {
+      $access_type_status = ACCESS_WEBMASTER;
+      break;
+    }
+    default:
+    {
+      $access_type_status = ACCESS_FREE;
+      break;
+    }
+  }
+
+  return $access_type_status;
+}
+
+/*
+ * Return if user have access to access_type definition
+ * Test does with user status
+ * @return bool
+*/
+function is_autorize_status($access_type, $user_status = '')
+{
+  return (get_access_type_status($user_status) >= $access_type);
+}
+
+/*
+ * Check if user have access to access_type definition
+ * Stop action if there are not access
+ * Test does with user status
+ * @return none
+*/
+function check_status($access_type, $user_status = '')
+{
+  if (!is_autorize_status($access_type, $user_status))
+  {
+    access_denied();
+  }
+}
+
+/*
+ * Return if user is generic
+ * @return bool
+*/
+ function is_generic($user_status = '')
+{
+  return get_user_status($user_status) == 'generic';
+}
+
+/*
+ * Return if user is only a guest
+ * @return bool
+*/
+ function is_a_guest($user_status = '')
+{
+  return get_user_status($user_status) == 'guest';
+}
+
+/*
+ * Return if user is, at least, a classic user
+ * @return bool
+*/
+ function is_classic_user($user_status = '')
+{
+  return is_autorize_status(ACCESS_CLASSIC, $user_status);
+}
+
+/*
+ * Return if user is, at least, an administrator
+ * @return bool
+*/
+ function is_admin($user_status = '')
+{
+  return is_autorize_status(ACCESS_ADMINISTRATOR, $user_status);
+}
+
+/*
+ * Return if current user is an adviser
+ * @return bool
+*/
+function is_adviser()
+{
+  global $user;
+
+  return ($user['adviser'] == 'true');
+}
+
+/*
+ * Return mail address as display text
+ * @return string
+*/
+function get_email_address_as_display_text($email_address)
+{
+  global $conf;
+
+  if (!isset($email_address) or (trim($email_address) == ''))
+  {
+    return '';
+  }
+  else
+  {
+    if (defined('IN_ADMIN') and is_adviser())
+    {
+      return 'adviser.mode@'.$_SERVER['SERVER_NAME'];
+    }
+    else
+    {
+      return $email_address;
+    }
+  }
+}
+
+/*
+ * Compute sql where condition with restrict and filter data. "FandF" means
+ * Forbidden and Filters.
+ *
+ * @param array condition_fields: read function body
+ * @param string prefix_condition: prefixes sql if condition is not empty
+ * @param boolean force_one_condition: use at least "1 = 1"
+ *
+ * @return string sql where/conditions
+ */
+function get_sql_condition_FandF(
+  $condition_fields,
+  $prefix_condition = null,
+  $force_one_condition = false
+  )
+{
+  global $user, $filter;
+
+  $sql_list = array();
+
+  foreach ($condition_fields as $condition => $field_name)
+  {
+    switch($condition)
+    {
+      case 'forbidden_categories':
+      {
+        if (!empty($user['forbidden_categories']))
+        {
+          $sql_list[] =
+            $field_name.' NOT IN ('.$user['forbidden_categories'].')';
+        }
+        break;
+      }
+      case 'visible_categories':
+      {
+        if (!empty($filter['visible_categories']))
+        {
+          $sql_list[] =
+            $field_name.' IN ('.$filter['visible_categories'].')';
+        }
+        break;
+      }
+      case 'visible_images':
+        if (!empty($filter['visible_images']))
+        {
+          $sql_list[] =
+            $field_name.' IN ('.$filter['visible_images'].')';
+        }
+        // note there is no break - visible include forbidden
+      case 'forbidden_images':
+        if (
+            !empty($user['image_access_list'])
+            or $user['image_access_type']!='NOT IN'
+            )
+        {
+          $table_prefix=null;
+          if ($field_name=='id')
+          {
+            $table_prefix = '';
+          }
+          elseif ($field_name=='i.id')
+          {
+            $table_prefix = 'i.';
+          }
+          if ( isset($table_prefix) )
+          {
+            $sql_list[]=$table_prefix.'level<='.$user['level'];
+          }
+          else
+          {
+            $sql_list[]=$field_name.' '.$user['image_access_type']
+                .' ('.$user['image_access_list'].')';
+          }
+        }
+        break;
+      default:
+      {
+        die('Unknow condition');
+        break;
+      }
+    }
+  }
+
+  if (count($sql_list) > 0)
+  {
+    $sql = '('.implode(' AND ', $sql_list).')';
+  }
+  else
+  {
+    $sql = $force_one_condition ? '1 = 1' : '';
+  }
+
+  if (isset($prefix_condition) and !empty($sql))
+  {
+    $sql = $prefix_condition.' '.$sql;
+  }
+
+  return $sql;
+}
+
+?>
Index: /tags/2.0.2/include/functions_xml.inc.php
===================================================================
--- /tags/2.0.2/include/functions_xml.inc.php	(revision 3278)
+++ /tags/2.0.2/include/functions_xml.inc.php	(revision 3278)
@@ -0,0 +1,134 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+define( 'ATT_REG', '\w+' );
+define( 'VAL_REG', '[^"]*' );
+
+//------------------------------------------------------------------- functions
+// getContent returns the content of a tag
+//
+// example : getContent( "<name>Joe</name>" ) returns "Joe"
+//
+// It also works with strings containing themself sub-tags :
+// <perso><name>Jean</name><firstname>Billie</fisrtname></perso> ->
+// <name>Jean</name><firstname>Billie</firstname>
+function getContent( $element )
+{
+  // deleting start of the tag
+  $content = preg_replace( '/^<[^>]+>/', '', $element );
+  // deleting end of the tag
+  $content = preg_replace( '/<\/[^>]+>$/', '', $content );
+  // replacing multiple instance of space character
+  $content = preg_replace( '/\s+/', ' ', $content );
+
+  return $content;
+}
+
+// The function get Attribute returns the value corresponding to the
+// attribute $attribute for the tag $element.
+function getAttribute( $element, $attribute )
+{
+//  echo htmlentities($element).'<br /><br />';
+  $regex = '/^<\w+[^>]*\b'.$attribute.'\s*=\s*"('.VAL_REG.')"/i';
+  if ( preg_match( $regex, $element, $out ) ) 
+  {
+    return html_entity_decode($out[1], ENT_QUOTES);
+  }
+  else return '';
+}
+
+// The function encode Attribute returns the xml attribute $attribute="$value" 
+function encodeAttribute( $attribute, $value )
+{
+  return $attribute.'="'.htmlspecialchars($value, ENT_QUOTES).'" ';
+}
+
+// The function getChild returns the first child
+// exemple : getChild( "<table><tr>XXX</tr><tr>YYY</tr></table>", "tr" )
+//           returns "<tr>XXX</tr>"
+function getChild( $document, $node )
+{
+  $regex = '/<'.$node.'(\s+'.ATT_REG.'="'.VAL_REG.'")*';
+  $regex.= '(\s*\/>|>.*<\/'.$node.'>)/U';
+
+  if
+    (
+      preg_match( $regex, $document, $out )
+      or
+      preg_last_error() == PREG_NO_ERROR
+    )
+  {
+    return $out[0];
+  }
+  else
+  {
+    die('getChild: error ['.preg_last_error().'] with preg_match function');
+  }
+}
+
+// getChildren returns a list of the children identified by the $node
+// example : 
+//     getChild( "<table><tr>XXX</tr><tr>YYY</tr></table>", "tr" )
+//     returns an array with :
+//          $array[0] equals "<tr>XXX</tr>"
+//          $array[1] equals "<tr>YYY</tr>"
+function getChildren( $document, $node )
+{
+  $regex = '/<'.$node.'(\s+'.ATT_REG.'="'.VAL_REG.'")*';
+  $regex.= '(\s*\/>|>.*<\/'.$node.'>)/U';
+
+  if
+    (
+      preg_match_all( $regex, $document, $out )
+      or
+      preg_last_error() == PREG_NO_ERROR
+    )
+  {
+    return $out[0];
+  }
+  else
+  {
+    die('getChild: error ['.preg_last_error().'] with preg_match_all function');
+  }
+}
+
+// get_CodeXML places the content of a text file in a PHP variable and
+// return it. If the file can't be opened, returns false.
+function getXmlCode( $filename )
+{
+  if (function_exists('ini_set'))
+  {
+    // limit must be growed with php5 and "big" listing file
+    ini_set("pcre.backtrack_limit", pow(2, 32));
+  }
+
+  if (!fetchRemote($filename, $xml_content))
+  {
+    return false;
+  }
+
+  $xml_content = str_replace( "\n", '', $xml_content );
+  $xml_content = str_replace( "\t", '', $xml_content );
+
+  return $xml_content;
+}
+?>
Index: /tags/2.0.2/include/index.php
===================================================================
--- /tags/2.0.2/include/index.php	(revision 3278)
+++ /tags/2.0.2/include/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/include/menubar.inc.php
===================================================================
--- /tags/2.0.2/include/menubar.inc.php	(revision 3278)
+++ /tags/2.0.2/include/menubar.inc.php	(revision 3278)
@@ -0,0 +1,307 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+/**
+ * This file is included by the main page to show the menu bar
+ *
+ */
+
+include_once(PHPWG_ROOT_PATH.'include/block.class.php');
+
+initialize_menu();
+
+function initialize_menu()
+{
+  global $page, $conf, $user, $template, $filter;
+
+  $menu = new BlockManager("menubar");
+  $menu->load_registered_blocks();
+  $menu->prepare_display();
+
+//--------------------------------------------------------------- external links
+  if ( ($block=$menu->get_block('mbLinks')) and !empty($conf['links']) )
+  {
+    $data = array();
+    foreach ($conf['links'] as $url => $url_data)
+    {
+      if (!is_array($url_data))
+      {
+        $url_data = array('label' => $url_data);
+      }
+
+      if
+        (
+          (!isset($url_data['eval_visible']))
+          or
+          (eval($url_data['eval_visible']))
+        )
+      {
+        $tpl_var = array(
+            'URL' => $url,
+            'LABEL' => $url_data['label']
+          );
+
+        if (!isset($url_data['new_window']) or $url_data['new_window'])
+        {
+          $tpl_var['new_window'] =
+            array(
+              'NAME' => (isset($url_data['nw_name']) ? $url_data['nw_name'] : ''),
+              'FEATURES' => (isset($url_data['nw_features']) ? $url_data['nw_features'] : '')
+            );
+        }
+        $data[] = $tpl_var;
+      }
+    }
+    $block->template = 'menubar_links.tpl';
+    $block->data = $data;
+  }
+
+//-------------------------------------------------------------- categories
+  $block = $menu->get_block('mbCategories');
+//------------------------------------------------------------------------ filter
+  if (!empty($conf['filter_pages']) and get_filter_page_value('used'))
+  {
+    if ($filter['enabled'])
+    {
+      $template->assign(
+        'U_STOP_FILTER',
+        add_url_params(make_index_url(array()), array('filter' => 'stop'))
+        );
+    }
+    else
+    {
+      $template->assign(
+        'U_START_FILTER',
+        add_url_params(make_index_url(array()), array('filter' => 'start-recent-'.$user['recent_period']))
+        );
+    }
+  }
+
+  if ( $block!=null )
+  {
+    $block->data = array(
+      'NB_PICTURE' => $user['nb_total_images'],
+      'MENU_CATEGORIES_CONTENT' => get_categories_menu(),
+      'U_CATEGORIES' => make_index_url(array('section' => 'categories')),
+      'U_UPLOAD' => get_upload_menu_link()
+    );
+    $block->template = 'menubar_categories.tpl';
+  }
+
+//------------------------------------------------------------------------ tags
+  $block = $menu->get_block('mbTags');
+  if ( $block!=null and 'tags'==@$page['section'] and !empty($page['items']) )
+  {
+    $tags = get_common_tags($page['items'],
+          $conf['menubar_tag_cloud_items_number'], $page['tag_ids']);
+    $tags = add_level_to_tags($tags);
+
+    foreach ($tags as $tag)
+    {
+      $block->data[] =
+        array_merge( $tag,
+          array(
+            'URL' => make_index_url(
+              array(
+                'tags' => array($tag)
+                )
+              ),
+            'U_ADD' => make_index_url(
+                  array(
+                    'tags' => array_merge(
+                      $page['tags'],
+                      array($tag)
+                      )
+                    )
+                  ),
+            )
+        );
+    }
+    $block->template = 'menubar_tags.tpl';
+  }
+
+//----------------------------------------------------------- special categories
+  if ( ($block = $menu->get_block('mbSpecials')) != null )
+  {
+    if ( !is_a_guest() )
+    {// favorites
+      $block->data['favorites'] =
+        array(
+          'URL' => make_index_url(array('section' => 'favorites')),
+          'TITLE' => l10n('favorite_cat_hint'),
+          'NAME' => l10n('favorite_cat')
+          );
+    }
+
+    $block->data['most_visited'] =
+      array(
+        'URL' => make_index_url(array('section' => 'most_visited')),
+        'TITLE' => l10n('most_visited_cat_hint'),
+        'NAME' => l10n('most_visited_cat')
+      );
+
+    if ($conf['rate'])
+    {
+       $block->data['best_rated'] =
+        array(
+          'URL' => make_index_url(array('section' => 'best_rated')),
+          'TITLE' => l10n('best_rated_cat_hint'),
+          'NAME' => l10n('best_rated_cat')
+        );
+    }
+
+    $block->data['random'] =
+      array(
+        'URL' => get_root_url().'random.php',
+        'TITLE' => l10n('random_cat_hint'),
+        'NAME' => l10n('random_cat'),
+        'REL'=> 'rel="nofollow"'
+      );
+
+    $block->data['recent_pics'] =
+      array(
+        'URL' => make_index_url(array('section' => 'recent_pics')),
+        'TITLE' => l10n('recent_pics_cat_hint'),
+        'NAME' => l10n('recent_pics_cat'),
+      );
+
+    $block->data['recent_cats'] =
+      array(
+        'URL' => make_index_url(array('section' => 'recent_cats')),
+        'TITLE' => l10n('recent_cats_cat_hint'),
+        'NAME' => l10n('recent_cats_cat'),
+      );
+
+
+    $block->data['calendar'] =
+      array(
+        'URL' =>
+          make_index_url(
+            array(
+              'chronology_field' => ($conf['calendar_datefield']=='date_available'
+                                      ? 'posted' : 'created'),
+               'chronology_style'=> 'monthly',
+               'chronology_view' => 'calendar'
+            )
+          ),
+        'TITLE' => l10n('calendar_hint'),
+        'NAME' => l10n('calendar'),
+        'REL'=> 'rel="nofollow"'
+      );
+    $block->template = 'menubar_specials.tpl';
+  }
+
+
+//---------------------------------------------------------------------- summary
+  if ( ($block=$menu->get_block('mbMenu')) != null )
+  {
+    // quick search block will be displayed only if data['qsearch'] is set
+    // to "yes"
+    $block->data['qsearch']=true;
+
+    // tags link
+    $block->data['tags'] =
+      array(
+        'TITLE' => l10n('See available tags'),
+        'NAME' => l10n('Tags'),
+        'URL'=> get_root_url().'tags.php',
+      );
+
+    // search link
+    $block->data['search'] =
+      array(
+        'TITLE'=>l10n('hint_search'),
+        'NAME'=>l10n('Search'),
+        'URL'=> get_root_url().'search.php',
+        'REL'=> 'rel="search"'
+      );
+
+    // comments link
+    $block->data['comments'] =
+      array(
+        'TITLE'=>l10n('hint_comments'),
+        'NAME'=>l10n('comments'),
+        'URL'=> get_root_url().'comments.php',
+      );
+
+    // about link
+    $block->data['about'] =
+      array(
+        'TITLE'     => l10n('about_page_title'),
+        'NAME'      => l10n('About'),
+        'URL' => get_root_url().'about.php',
+      );
+
+    // notification
+    $block->data['rss'] =
+      array(
+        'TITLE'=>l10n('RSS feed'),
+        'NAME'=>l10n('Notification'),
+        'URL'=> get_root_url().'notification.php',
+        'REL'=> 'rel="nofollow"'
+      );
+    $block->template = 'menubar_menu.tpl';
+  }
+
+
+//--------------------------------------------------------------- identification
+  if (is_a_guest())
+  {
+    $template->assign(
+        array(
+          'U_LOGIN' => get_root_url().'identification.php',
+          'U_LOST_PASSWORD' => get_root_url().'password.php',
+          'AUTHORIZE_REMEMBERING' => $conf['authorize_remembering']
+        )
+      );
+    if ($conf['allow_user_registration'])
+    {
+      $template->assign( 'U_REGISTER', get_root_url().'register.php');
+    }
+  }
+  else
+  {
+    $template->assign('USERNAME', $user['username']);
+    if (is_autorize_status(ACCESS_CLASSIC))
+    {
+      $template->assign('U_PROFILE', get_root_url().'profile.php');
+    }
+
+    // the logout link has no meaning with Apache authentication : it is not
+    // possible to logout with this kind of authentication.
+    if (!$conf['apache_authentication'])
+    {
+      $template->assign('U_LOGOUT', get_root_url().'?act=logout');
+    }
+    if (is_admin())
+    {
+      $template->assign('U_ADMIN', get_root_url().'admin.php');
+    }
+  }
+  if ( ($block=$menu->get_block('mbIdentification')) != null )
+  {
+    $block->template = 'menubar_identification.tpl';
+  }
+  $menu->apply('MENUBAR',  'menubar.tpl' );
+}
+?>
Index: /tags/2.0.2/include/page_header.php
===================================================================
--- /tags/2.0.2/include/page_header.php	(revision 3278)
+++ /tags/2.0.2/include/page_header.php	(revision 3278)
@@ -0,0 +1,102 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+//
+// Start output of page
+//
+$template->set_filenames(array('header'=>'header.tpl'));
+
+trigger_action('loc_begin_page_header');
+
+$template->assign(
+  array(
+    'GALLERY_TITLE' =>
+      isset($page['gallery_title']) ?
+        $page['gallery_title'] : $conf['gallery_title'],
+
+    'PAGE_BANNER' =>
+      trigger_event('render_page_banner',
+        isset($page['page_banner']) ?
+          $page['page_banner'] : $conf['page_banner']),
+
+    'BODY_ID' =>
+      isset($page['body_id']) ?
+        $page['body_id'] : '',
+
+    'REVERSE' =>
+      (isset($conf['reverse_home_title']) and $conf['reverse_home_title']) ?
+        true : false,
+
+    'CONTENT_ENCODING' => get_pwg_charset(),
+    'PAGE_TITLE' => strip_tags($title),
+
+    'U_HOME' => make_index_url(),
+    ));
+
+
+// Header notes
+if ( !empty($header_notes) )
+{
+  $template->assign('header_notes',$header_notes);
+}
+
+// No referencing is required
+if ( !$conf['meta_ref'] ) 
+{
+  $page['meta_robots']['noindex'] = 1;
+  $page['meta_robots']['nofollow'] = 1;
+}
+
+if ( !empty($page['meta_robots']) )
+{
+  $template->append('head_elements',
+        '<meta name="robots" content="'
+        .implode(',', array_keys($page['meta_robots']))
+        .'">'
+    );
+}
+if ( !isset($page['meta_robots']['noindex']) )
+{ 
+  $template->assign('meta_ref',1); 
+}
+
+// refresh
+if ( isset( $refresh ) and intval($refresh) >= 0
+    and isset( $url_link ) )
+{
+  $template->assign(
+    array(
+      'page_refresh' => array(
+            'TIME' => $refresh,
+            'U_REFRESH' => $url_link
+          )
+      ));
+}
+
+trigger_action('loc_end_page_header');
+
+header('Content-Type: text/html; charset='.get_pwg_charset());
+$template->parse('header');
+
+trigger_action('loc_after_page_header');
+?>
Index: /tags/2.0.2/include/page_tail.php
===================================================================
--- /tags/2.0.2/include/page_tail.php	(revision 3278)
+++ /tags/2.0.2/include/page_tail.php	(revision 3278)
@@ -0,0 +1,74 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+$template->set_filenames(array('tail'=>'footer.tpl'));
+
+trigger_action('loc_begin_page_tail');
+
+$template->assign(
+  array(
+    'VERSION' => $conf['show_version'] ? PHPWG_VERSION : '',
+    'PHPWG_URL' => PHPWG_URL,
+    ));
+
+//--------------------------------------------------------------------- contact
+
+if (!is_a_guest())
+{
+  $template->assign(
+    'CONTACT_MAIL', get_webmaster_mail_address()
+    );
+}
+
+//------------------------------------------------------------- generation time
+$debug_vars = array();
+
+if ($conf['show_queries'])
+{
+  $debug_vars = array_merge($debug_vars, array('QUERIES_LIST' => $debug) );
+}
+
+if ($conf['show_gt'])
+{
+  if (!isset($page['count_queries']))
+  {
+    $page['count_queries'] = 0;
+    $page['queries_time'] = 0;
+  }
+  $time = get_elapsed_time($t2, get_moment());
+
+  $debug_vars = array_merge($debug_vars,
+    array('TIME' => $time,
+          'NB_QUERIES' => $page['count_queries'],
+          'SQL_TIME' => number_format($page['queries_time'],3,'.',' ').' s')
+          );
+}
+
+$template->assign('debug', $debug_vars );
+
+trigger_action('loc_end_page_tail');
+//
+// Generate the page
+//
+$template->parse('tail');
+$template->p();
+?>
Index: /tags/2.0.2/include/php_compat/array_intersect_key.php
===================================================================
--- /tags/2.0.2/include/php_compat/array_intersect_key.php	(revision 3278)
+++ /tags/2.0.2/include/php_compat/array_intersect_key.php	(revision 3278)
@@ -0,0 +1,35 @@
+<?php
+// http://www.php.net/manual/en/function.array-intersect-key.php
+// PHP 5 >= 5.1.0RC1
+function array_intersect_key()
+{
+  $args = func_get_args();
+  if (count($args) < 2) {
+      trigger_error('Wrong parameter count for array_intersect_key()', E_USER_WARNING);
+      return;
+  }
+
+  // Check arrays
+  $array_count = count($args);
+  for ($i = 0; $i !== $array_count; $i++) {
+      if (!is_array($args[$i])) {
+          trigger_error('array_intersect_key() Argument #' . ($i + 1) . ' is not an array', E_USER_WARNING);
+          return;
+      }
+  }
+
+  // Compare entries
+  $result = array();
+  foreach ($args[0] as $key1 => $value1) {
+      for ($i = 1; $i !== $array_count; $i++) {
+          foreach ($args[$i] as $key2 => $value2) {
+              if ((string) $key1 === (string) $key2) {
+                  $result[$key1] = $value1;
+              }
+          }
+      }
+  }
+
+  return $result;
+}
+?>
Index: /tags/2.0.2/include/php_compat/file_put_contents.php
===================================================================
--- /tags/2.0.2/include/php_compat/file_put_contents.php	(revision 3278)
+++ /tags/2.0.2/include/php_compat/file_put_contents.php	(revision 3278)
@@ -0,0 +1,14 @@
+<?php
+//php 5
+function file_put_contents($filename, $data)
+{
+  $fp = fopen($filename, 'w');
+  if ($fp)
+  {
+    $ret = fwrite($fp, $data);
+    fclose($fp);
+    return $ret;
+  }
+  return false;
+}
+?>
Index: /tags/2.0.2/include/php_compat/hash_hmac.php
===================================================================
--- /tags/2.0.2/include/php_compat/hash_hmac.php	(revision 3278)
+++ /tags/2.0.2/include/php_compat/hash_hmac.php	(revision 3278)
@@ -0,0 +1,25 @@
+<?php
+//(hash) - enabled by default as of PHP 5.1.2
+function hash_hmac($algo, $data, $key, $raw_output=false)
+{
+  /* md5 and sha1 only */
+  $algo=strtolower($algo);
+  $p=array('md5'=>'H32','sha1'=>'H40');
+  if ( !isset($p[$algo]) or !function_exists($algo) )
+  {
+    $algo = 'md5';
+  }
+  if(strlen($key)>64) $key=pack($p[$algo],$algo($key));
+  if(strlen($key)<64) $key=str_pad($key,64,chr(0));
+
+  $ipad=substr($key,0,64) ^ str_repeat(chr(0x36),64);
+  $opad=substr($key,0,64) ^ str_repeat(chr(0x5C),64);
+
+  $ret = $algo($opad.pack($p[$algo],$algo($ipad.$data)));
+  if ($raw_output)
+  {
+    $ret = pack('H*', $ret);
+  }
+  return $ret;
+}
+?>
Index: /tags/2.0.2/include/php_compat/index.php
===================================================================
--- /tags/2.0.2/include/php_compat/index.php	(revision 3278)
+++ /tags/2.0.2/include/php_compat/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/include/php_compat/preg_last_error.php
===================================================================
--- /tags/2.0.2/include/php_compat/preg_last_error.php	(revision 3278)
+++ /tags/2.0.2/include/php_compat/preg_last_error.php	(revision 3278)
@@ -0,0 +1,41 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// http://www.php.net/manual/fr/function.preg-last-error.php
+// PHP 5 >= 5.2.0
+if (!defined('PREG_NO_ERROR'))
+  define('PREG_NO_ERROR', 0);
+if (!defined('PREG_INTERNAL_ERROR'))
+  define('PREG_INTERNAL_ERROR', 1);
+if (!defined('PREG_BACKTRACK_LIMIT_ERROR'))
+  define('PREG_BACKTRACK_LIMIT_ERROR', 2);
+if (!defined('PREG_RECURSION_LIMIT_ERROR'))
+  define('PREG_RECURSION_LIMIT_ERROR', 3);
+if (!defined('PREG_BAD_UTF8_ERROR'))
+  define('PREG_BAD_UTF8_ERROR', 4);
+
+function preg_last_error()
+{
+  return PREG_NO_ERROR;
+}
+?>
Index: /tags/2.0.2/include/picture_comment.inc.php
===================================================================
--- /tags/2.0.2/include/picture_comment.inc.php	(revision 3278)
+++ /tags/2.0.2/include/picture_comment.inc.php	(revision 3278)
@@ -0,0 +1,179 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+/**
+ * This file is included by the picture page to manage user comments
+ *
+ */
+
+// the picture is commentable if it belongs at least to one category which
+// is commentable
+$page['show_comments'] = false;
+foreach ($related_categories as $category)
+{
+  if ($category['commentable'] == 'true')
+  {
+    $page['show_comments'] = true;
+    break;
+  }
+}
+
+if ( $page['show_comments'] and isset( $_POST['content'] ) )
+{
+  if ( is_a_guest() and !$conf['comments_forall'] )
+  {
+    die ('Session expired');
+  }
+
+  $comm = array(
+    'author' => trim( stripslashes(@$_POST['author']) ),
+    'content' => trim( stripslashes($_POST['content']) ),
+    'image_id' => $page['image_id'],
+   );
+
+  include_once(PHPWG_ROOT_PATH.'include/functions_comment.inc.php');
+
+  $comment_action = insert_user_comment($comm, @$_POST['key'], $infos );
+
+  switch ($comment_action)
+  {
+    case 'moderate':
+      array_push( $infos, l10n('comment_to_validate') );
+    case 'validate':
+      array_push( $infos, l10n('comment_added'));
+      break;
+    case 'reject':
+      set_status_header(403);
+      array_push($infos, l10n('comment_not_added') );
+      break;
+    default:
+      trigger_error('Invalid comment action '.$comment_action, E_USER_WARNING);
+  }
+
+  $template->assign(
+      ($comment_action=='reject') ? 'errors' : 'infos',
+      $infos
+    );
+
+  // allow plugins to notify what's going on
+  trigger_action( 'user_comment_insertion',
+      array_merge($comm, array('action'=>$comment_action) )
+    );
+}
+elseif ( isset($_POST['content']) )
+{
+  set_status_header(403);
+  die('ugly spammer');
+}
+
+if ($page['show_comments'])
+{
+  // number of comments for this picture
+  $query = '
+SELECT COUNT(*) AS nb_comments
+  FROM '.COMMENTS_TABLE.'
+  WHERE image_id='.$page['image_id']." AND validated = 'true'";
+  $row = mysql_fetch_array( pwg_query( $query ) );
+
+  // navigation bar creation
+  if (!isset($page['start']))
+  {
+    $page['start'] = 0;
+  }
+
+  $navigation_bar = create_navigation_bar(
+    duplicate_picture_url(array(), array('start')),
+    $row['nb_comments'],
+    $page['start'],
+    $conf['nb_comment_page'],
+    true // We want a clean URL
+    );
+
+  $template->assign(
+    array(
+      'COMMENT_COUNT' => $row['nb_comments'],
+      'COMMENT_NAV_BAR' => $navigation_bar,
+      )
+    );
+
+  if ($row['nb_comments'] > 0)
+  {
+    $query = '
+SELECT id,author,date,image_id,content
+  FROM '.COMMENTS_TABLE.'
+  WHERE image_id = '.$page['image_id'].'
+    AND validated = \'true\'
+  ORDER BY date ASC
+  LIMIT '.$page['start'].', '.$conf['nb_comment_page'].'
+;';
+    $result = pwg_query( $query );
+
+    while ($row = mysql_fetch_array($result))
+    {
+      $tpl_comment =
+        array(
+          'AUTHOR' => trigger_event('render_comment_author',
+            empty($row['author'])
+            ? l10n('guest')
+            : $row['author']),
+
+          'DATE' => format_date( $row['date'], true),
+
+          'CONTENT' => trigger_event('render_comment_content',$row['content']),
+        );
+
+      if (is_admin())
+      {
+        $tpl_comment['U_DELETE'] =
+            add_url_params(
+                  $url_self,
+                  array(
+                    'action'=>'delete_comment',
+                    'comment_to_delete'=>$row['id']
+                  )
+              );
+      }
+      $template->append('comments', $tpl_comment);
+    }
+  }
+
+  if (!is_a_guest()
+      or (is_a_guest() and $conf['comments_forall']))
+  {
+    $key = get_comment_post_key($page['image_id']);
+    $content = '';
+    if ('reject'===@$comment_action)
+    {
+      $content = htmlspecialchars($comm['content']);
+    }
+    $template->assign('comment_add',
+        array(
+          'F_ACTION' => $url_self,
+          'KEY' => $key,
+          'CONTENT' => $content,
+          'SHOW_AUTHOR' => !is_classic_user()
+        ));
+  }
+}
+
+?>
Index: /tags/2.0.2/include/picture_metadata.inc.php
===================================================================
--- /tags/2.0.2/include/picture_metadata.inc.php	(revision 3278)
+++ /tags/2.0.2/include/picture_metadata.inc.php	(revision 3278)
@@ -0,0 +1,99 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+/**
+ * This file is included by the picture page to manage picture metadata
+ *
+ */
+
+include_once(PHPWG_ROOT_PATH.'/include/functions_metadata.inc.php');
+if (($conf['show_exif']) and (function_exists('read_exif_data')))
+{
+  if ($exif = @read_exif_data($picture['current']['image_path']))
+  {
+    $exif = trigger_event('format_exif_data', $exif, $picture['current'] );
+
+    $tpl_meta = array(
+        'TITLE' => 'EXIF Metadata',
+        'lines' => array(),
+      );
+
+    foreach ($conf['show_exif_fields'] as $field)
+    {
+      if (strpos($field, ';') === false)
+      {
+        if (isset($exif[$field]))
+        {
+          $key = $field;
+          if (isset($lang['exif_field_'.$field]))
+          {
+            $key = $lang['exif_field_'.$field];
+          }
+          $tpl_meta['lines'][$key] = $exif[$field];
+        }
+      }
+      else
+      {
+        $tokens = explode(';', $field);
+        if (isset($exif[$tokens[0]][$tokens[1]]))
+        {
+          $key = $tokens[1];
+          if (isset($lang['exif_field_'.$tokens[1]]))
+          {
+            $key = $lang['exif_field_'.$tokens[1]];
+          }
+          $tpl_meta['lines'][$key] = $exif[$tokens[0]][$tokens[1]];
+        }
+      }
+    }
+    $template->append('metadata', $tpl_meta);
+  }
+}
+
+if ($conf['show_iptc'])
+{
+  $iptc = get_iptc_data($picture['current']['image_path'],
+                        $conf['show_iptc_mapping']);
+
+  if (count($iptc) > 0)
+  {
+    $tpl_meta = array(
+        'TITLE' => 'IPTC Metadata',
+        'lines' => array(),
+      );
+
+    foreach ($iptc as $field => $value)
+    {
+      $key = $field;
+      if (isset($lang[$field]))
+      {
+        $key = $lang[$field];
+      }
+      $tpl_meta['lines'][$key] = $value;
+    }
+    $template->append('metadata', $tpl_meta);
+  }
+}
+
+
+?>
Index: /tags/2.0.2/include/picture_rate.inc.php
===================================================================
--- /tags/2.0.2/include/picture_rate.inc.php	(revision 3278)
+++ /tags/2.0.2/include/picture_rate.inc.php	(revision 3278)
@@ -0,0 +1,91 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+/**
+ * This file is included by the picture page to manage rates
+ *
+ */
+
+if ($conf['rate'])
+{
+  if ( NULL != $picture['current']['average_rate'] )
+  {
+    $query = '
+SELECT COUNT(rate) AS count
+     , ROUND(AVG(rate),2) AS average
+     , ROUND(STD(rate),2) AS std
+  FROM '.RATE_TABLE.'
+  WHERE element_id = '.$picture['current']['id'].'
+;';
+    $row = mysql_fetch_array(pwg_query($query));
+  }
+  else
+  { // avg rate null -> no rate -> no need to query db
+    $row = array( 'count'=>0, 'average'=>NULL, 'std'=>NULL );
+  }
+  $template->assign('rate_summary', $row);
+
+  $user_rate = null;
+  if ($conf['rate_anonymous'] or is_autorize_status(ACCESS_CLASSIC) )
+  {
+    if ($row['count']>0)
+    {
+      $query = 'SELECT rate
+      FROM '.RATE_TABLE.'
+      WHERE element_id = '.$page['image_id'] . '
+      AND user_id = '.$user['id'] ;
+
+      if ( !is_autorize_status(ACCESS_CLASSIC) )
+      {
+        $ip_components = explode('.', $_SERVER['REMOTE_ADDR']);
+        if ( count($ip_components)>3 )
+        {
+          array_pop($ip_components);
+        }
+        $anonymous_id = implode ('.', $ip_components);
+        $query .= ' AND anonymous_id = \''.$anonymous_id . '\'';
+      }
+
+      $result = pwg_query($query);
+      if (mysql_num_rows($result) > 0)
+      {
+        $row = mysql_fetch_array($result);
+        $user_rate = $row['rate'];
+      }
+    }
+
+    $template->assign(
+        'rating',
+        array(
+          'F_ACTION' => add_url_params(
+                        $url_self,
+                        array('action'=>'rate')
+                      ),
+          'USER_RATE'=> $user_rate,
+          'marks'    => $conf['rate_items']
+        )
+      );
+  }
+}
+
+?>
Index: /tags/2.0.2/include/section_init.inc.php
===================================================================
--- /tags/2.0.2/include/section_init.inc.php	(revision 3278)
+++ /tags/2.0.2/include/section_init.inc.php	(revision 3278)
@@ -0,0 +1,604 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+/**
+ * This included page checks section related parameter and provides
+ * following informations:
+ *
+ * - $page['title']
+ *
+ * - $page['items']: ordered list of items to display
+ *
+ */
+
+// "index.php?/category/12-foo/start-24" or
+// "index.php/category/12-foo/start-24"
+// must return :
+//
+// array(
+//   'section'  => 'categories',
+//   'category' => array('id'=>12, ...),
+//   'start'    => 24
+//   );
+
+$page['items'] = array();
+
+// some ISPs set PATH_INFO to empty string or to SCRIPT_FILENAME while in the
+// default apache implementation it is not set
+if ( $conf['question_mark_in_urls']==false and
+     isset($_SERVER["PATH_INFO"]) and !empty($_SERVER["PATH_INFO"]) )
+{
+  $rewritten = $_SERVER["PATH_INFO"];
+  $rewritten = str_replace('//', '/', $rewritten);
+  $path_count = count( explode('/', $rewritten) );
+  $page['root_path'] = PHPWG_ROOT_PATH.str_repeat('../', $path_count-1);
+}
+else
+{
+  $rewritten = '';
+  foreach (array_keys($_GET) as $keynum => $key)
+  {
+    $rewritten = $key;
+    break;
+  }
+  $page['root_path'] = PHPWG_ROOT_PATH;
+}
+
+// deleting first "/" if displayed
+$tokens = explode('/', ltrim($rewritten, '/') );
+// $tokens = array(
+//   0 => category,
+//   1 => 12-foo,
+//   2 => start-24
+//   );
+
+$next_token = 0;
+if (script_basename() == 'picture') // basename without file extention
+{ // the first token must be the identifier for the picture
+  if ( isset($_GET['image_id'])
+       and isset($_GET['cat']) and is_numeric($_GET['cat']) )
+  {// url compatibility with versions below 1.6
+    $url = make_picture_url( array(
+        'section' => 'categories',
+        'category' => get_cat_info($_GET['cat']),
+        'image_id' => $_GET['image_id']
+      ) );
+    redirect($url);
+  }
+  $token = $tokens[$next_token];
+  $next_token++;
+  if ( is_numeric($token) )
+  {
+    $page['image_id'] = $token;
+    if ($page['image_id']==0)
+    {
+      bad_request('invalid picture identifier');
+    }
+  }
+  else
+  {
+    preg_match('/^(\d+-)?(.*)?$/', $token, $matches);
+    if (isset($matches[1]) and is_numeric($matches[1]=rtrim($matches[1],'-')) )
+    {
+      $page['image_id'] = $matches[1];
+      if ( !empty($matches[2]) )
+      {
+        $page['image_file'] = $matches[2];
+      }
+    }
+    else
+    {
+      if ( !empty($matches[2]) )
+      {
+        $page['image_file'] = $matches[2];
+      }
+      else
+      {
+        bad_request('picture identifier is missing');
+      }
+    }
+  }
+}
+
+$page = array_merge( $page, parse_section_url( $tokens, $next_token) );
+if ( !isset($page['section']) )
+{
+  $page['section'] = 'categories';
+
+  switch (script_basename())
+  {
+    case 'picture':
+      break;
+    case 'index':
+    {
+      // No section defined, go to selected url
+      if (!empty($conf['random_index_redirect']) and empty($tokens[$next_token]) )
+      {
+        $random_index_redirect = array();
+        foreach ($conf['random_index_redirect'] as $random_url => $random_url_condition)
+        {
+          if (empty($random_url_condition) or eval($random_url_condition))
+          {
+            $random_index_redirect[] = $random_url;
+          }
+        }
+        if (!empty($random_index_redirect))
+        {
+          redirect($random_index_redirect[mt_rand(0, count($random_index_redirect)-1)]);
+        }
+      }
+      break;
+    }
+    default:
+      trigger_error('script_basename "'.script_basename().'" unknown',
+        E_USER_WARNING);
+  }
+}
+
+
+$page = array_merge( $page, parse_well_known_params_url( $tokens, $next_token) );
+
+
+if ( script_basename()=='picture' and 'categories'==$page['section'] and
+      !isset($page['category']) and !isset($page['chronology_field']) )
+{ //access a picture only by id, file or id-file without given section
+  $page['flat']=true;
+}
+
+// $page['nb_image_page'] is the number of picture to display on this page
+// By default, it is the same as the $user['nb_image_page']
+$page['nb_image_page'] = $user['nb_image_page'];
+
+// if flat mode is active, we must consider the image set as a standard set
+// and not as a category set because we can't use the #image_category.rank :
+// displayed images are not directly linked to the displayed category
+if ('categories' == $page['section'] and !isset($page['flat']))
+{
+  $conf['order_by'] = $conf['order_by_inside_category'];
+}
+
+if (pwg_get_session_var('image_order',0) > 0)
+{
+  $image_order_id = pwg_get_session_var('image_order');
+
+  $orders = get_category_preferred_image_orders();
+
+  // the current session stored image_order might be not compatible with
+  // current image set, for example if the current image_order is the rank
+  // and that we are displaying images related to a tag.
+  //
+  // In case of incompatibility, the session stored image_order is removed.
+  if ($orders[$image_order_id][2])
+  {
+    $conf['order_by'] = str_replace(
+      'ORDER BY ',
+      'ORDER BY '.$orders[$image_order_id][1].',',
+      $conf['order_by']
+    );
+    $page['super_order_by'] = true;
+
+  }
+  else
+  {
+    pwg_unset_session_var('image_order');
+    $page['super_order_by'] = false;
+  }
+}
+
+$forbidden = get_sql_condition_FandF(
+      array
+        (
+          'forbidden_categories' => 'category_id',
+          'visible_categories' => 'category_id',
+          'visible_images' => 'id'
+        ),
+      'AND'
+  );
+
+// +-----------------------------------------------------------------------+
+// |                              category                                 |
+// +-----------------------------------------------------------------------+
+if ('categories' == $page['section'])
+{
+  if (isset($page['category']))
+  {
+    $page = array_merge(
+      $page,
+      array(
+        'comment'           =>
+            trigger_event(
+              'render_category_description',
+              $page['category']['comment'],
+              'main_page_category_description'
+            ),
+        'title'             =>
+          get_cat_display_name($page['category']['upper_names'], '', false),
+        )
+      );
+  }
+  else
+  {
+    $page['title'] = l10n('no_category');
+  }
+
+  if
+    (
+      (!isset($page['chronology_field'])) and
+      (
+        (isset($page['category'])) or
+        (isset($page['flat']))
+      )
+    )
+  {
+    if ( !empty($page['category']['image_order']) and !isset($page['super_order_by']) )
+    {
+      $conf[ 'order_by' ] = ' ORDER BY '.$page['category']['image_order'];
+    }
+
+    if (isset($page['flat']))
+    {// flat categories mode
+      if ( isset($page['category']) )
+      { // get all allowed sub-categories
+        $query = '
+SELECT id
+  FROM '.CATEGORIES_TABLE.'
+  WHERE
+    uppercats LIKE "'.$page['category']['uppercats'].',%" '
+    .get_sql_condition_FandF(
+      array
+        (
+          'forbidden_categories' => 'id',
+          'visible_categories' => 'id',
+        ),
+      "\n  AND"
+          );
+        $subcat_ids = array_from_query($query, 'id');
+        $subcat_ids[] = $page['category']['id'];
+        $where_sql = 'category_id IN ('.implode(',',$subcat_ids).')';
+        // remove categories from forbidden because just checked above
+        $forbidden = get_sql_condition_FandF(
+              array( 'visible_images' => 'id' ),
+              'AND'
+          );
+      }
+      else
+      {
+        $where_sql = '1=1';
+      }
+    }
+    else
+    {// Normal mode
+      $where_sql = 'category_id = '.$page['category']['id'];
+    }
+
+    // Main query
+    $query = '
+SELECT DISTINCT(image_id)
+  FROM '.IMAGE_CATEGORY_TABLE.'
+    INNER JOIN '.IMAGES_TABLE.' ON id = image_id
+  WHERE
+    '.$where_sql.'
+'.$forbidden.'
+  '.$conf['order_by'].'
+;';
+
+    $page['items'] = array_from_query($query, 'image_id');
+  } //otherwise the calendar will requery all subitems
+}
+// special sections
+else
+{
+// +-----------------------------------------------------------------------+
+// |                            tags section                               |
+// +-----------------------------------------------------------------------+
+  if ($page['section'] == 'tags')
+  {
+    $page['tag_ids'] = array();
+    foreach ($page['tags'] as $tag)
+    {
+      array_push($page['tag_ids'], $tag['id']);
+    }
+
+    $items = get_image_ids_for_tags($page['tag_ids']);
+
+    // permissions depends on category, so to only keep images that are
+    // reachable to the connected user, we need to check category
+    // associations
+    if (!empty($items) )
+    {
+      $query = '
+SELECT DISTINCT image_id
+  FROM '.IMAGE_CATEGORY_TABLE.' INNER JOIN '.IMAGES_TABLE.' ON image_id=id
+  WHERE image_id IN ('.implode(',', $items).')
+    '.$forbidden.
+    $conf['order_by'].'
+;';
+      $items =  array_from_query($query, 'image_id');
+    }
+
+    $page = array_merge(
+      $page,
+      array(
+        'title' => get_tags_content_title(),
+        'items' => $items,
+        )
+      );
+  }
+// +-----------------------------------------------------------------------+
+// |                           search section                              |
+// +-----------------------------------------------------------------------+
+  if ($page['section'] == 'search')
+  {
+    include_once( PHPWG_ROOT_PATH .'include/functions_search.inc.php' );
+
+    $search_result = get_search_results($page['search'], @$page['super_order_by'] );
+    if ( isset($search_result['qs']) )
+    {//save the details of the query search
+      $page['qsearch_details'] = $search_result['qs'];
+    }
+
+    $page = array_merge(
+      $page,
+      array(
+        'items' => $search_result['items'],
+        'title' => '<a href="'.duplicate_index_url(array('start'=>0)).'">'
+                  .l10n('search_result').'</a>',
+        )
+      );
+  }
+// +-----------------------------------------------------------------------+
+// |                           favorite section                            |
+// +-----------------------------------------------------------------------+
+  else if ($page['section'] == 'favorites')
+  {
+    check_user_favorites();
+
+    $query = '
+SELECT image_id
+  FROM '.FAVORITES_TABLE.'
+    INNER JOIN '.IMAGES_TABLE.' ON image_id = id
+  WHERE user_id = '.$user['id'].'
+'.get_sql_condition_FandF
+  (
+    array
+      (
+        'visible_images' => 'id'
+      ),
+    'AND'
+  ).'
+  '.$conf['order_by'].'
+;';
+
+    $page = array_merge(
+      $page,
+      array(
+        'title' => l10n('favorites'),
+        'items' => array_from_query($query, 'image_id'),
+        )
+      );
+  }
+// +-----------------------------------------------------------------------+
+// |                       recent pictures section                         |
+// +-----------------------------------------------------------------------+
+  else if ($page['section'] == 'recent_pics')
+  {
+    if ( !isset($page['super_order_by']) )
+    {
+      $conf['order_by'] = str_replace(
+        'ORDER BY ',
+        'ORDER BY date_available DESC,',
+        $conf['order_by']
+        );
+    }
+
+    $query = '
+SELECT DISTINCT(id)
+  FROM '.IMAGES_TABLE.'
+    INNER JOIN '.IMAGE_CATEGORY_TABLE.' AS ic ON id = ic.image_id
+  WHERE
+    date_available >= SUBDATE(
+      CURRENT_DATE,INTERVAL '.$user['recent_period'].' DAY)
+    '.$forbidden.'
+  '.$conf['order_by'].'
+;';
+
+    $page = array_merge(
+      $page,
+      array(
+        'title' => '<a href="'.duplicate_index_url(array('start'=>0)).'">'
+                  .l10n('recent_pics_cat').'</a>',
+        'items' => array_from_query($query, 'id'),
+        )
+      );
+  }
+// +-----------------------------------------------------------------------+
+// |                 recently updated categories section                   |
+// +-----------------------------------------------------------------------+
+  else if ($page['section'] == 'recent_cats')
+  {
+    $page = array_merge(
+      $page,
+      array(
+        'title' => l10n('recent_cats_cat'),
+        )
+      );
+  }
+// +-----------------------------------------------------------------------+
+// |                        most visited section                           |
+// +-----------------------------------------------------------------------+
+  else if ($page['section'] == 'most_visited')
+  {
+    $page['super_order_by'] = true;
+    $conf['order_by'] = ' ORDER BY hit DESC, file ASC';
+    $query = '
+SELECT DISTINCT(id)
+  FROM '.IMAGES_TABLE.'
+    INNER JOIN '.IMAGE_CATEGORY_TABLE.' AS ic ON id = ic.image_id
+  WHERE hit > 0
+    '.$forbidden.'
+    '.$conf['order_by'].'
+  LIMIT 0, '.$conf['top_number'].'
+;';
+
+    $page = array_merge(
+      $page,
+      array(
+        'title' => '<a href="'.duplicate_index_url(array('start'=>0)).'">'
+                  .$conf['top_number'].' '.l10n('most_visited_cat').'</a>',
+        'items' => array_from_query($query, 'id'),
+        )
+      );
+  }
+// +-----------------------------------------------------------------------+
+// |                          best rated section                           |
+// +-----------------------------------------------------------------------+
+  else if ($page['section'] == 'best_rated')
+  {
+    $page['super_order_by'] = true;
+    $conf['order_by'] = ' ORDER BY average_rate DESC, id ASC';
+
+    $query ='
+SELECT DISTINCT(id)
+  FROM '.IMAGES_TABLE.'
+    INNER JOIN '.IMAGE_CATEGORY_TABLE.' AS ic ON id = ic.image_id
+  WHERE average_rate IS NOT NULL
+    '.$forbidden.'
+    '.$conf['order_by'].'
+  LIMIT 0, '.$conf['top_number'].'
+;';
+    $page = array_merge(
+      $page,
+      array(
+        'title' => '<a href="'.duplicate_index_url(array('start'=>0)).'">'
+                  .$conf['top_number'].' '.l10n('best_rated_cat').'</a>',
+        'items' => array_from_query($query, 'id'),
+        )
+      );
+  }
+// +-----------------------------------------------------------------------+
+// |                             list section                              |
+// +-----------------------------------------------------------------------+
+  else if ($page['section'] == 'list')
+  {
+    $query ='
+SELECT DISTINCT(id)
+  FROM '.IMAGES_TABLE.'
+    INNER JOIN '.IMAGE_CATEGORY_TABLE.' AS ic ON id = ic.image_id
+  WHERE image_id IN ('.implode(',', $page['list']).')
+    '.$forbidden.'
+  '.$conf['order_by'].'
+;';
+
+    $page = array_merge(
+      $page,
+      array(
+        'title' => '<a href="'.duplicate_index_url(array('start'=>0)).'">'
+                    .l10n('random_cat').'</a>',
+        'items' => array_from_query($query, 'id'),
+        )
+      );
+  }
+}
+
+// +-----------------------------------------------------------------------+
+// |                             chronology                                |
+// +-----------------------------------------------------------------------+
+
+if (isset($page['chronology_field']))
+{
+  include_once( PHPWG_ROOT_PATH.'include/functions_calendar.inc.php' );
+  initialize_calendar();
+}
+
+if (script_basename() == 'picture'
+    and !isset($page['image_id']) )
+{
+  $page['image_id'] = 0; // more work in picture.php
+}
+
+// add meta robots noindex, nofollow to avoid unnecesary robot crawls
+$page['meta_robots']=array();
+if ( isset($page['chronology_field'])
+      or ( isset($page['flat']) and isset($page['category']) )
+      or 'list'==$page['section'] or 'recent_pics'==$page['section'] )
+{
+  $page['meta_robots']=array('noindex'=>1, 'nofollow'=>1);
+}
+elseif ('tags' == $page['section'])
+{
+  if ( count($page['tag_ids'])>1 )
+  {
+    $page['meta_robots']=array('noindex'=>1, 'nofollow'=>1);
+  }
+}
+elseif ('recent_cats'==$page['section'])
+{
+  $page['meta_robots']['noindex']=1;
+}
+elseif ('search'==$page['section'])
+{
+  $page['meta_robots']['nofollow']=1;
+}
+if ( $filter['enabled'] )
+{
+  $page['meta_robots']['noindex']=1;
+}
+
+// see if we need a redirect because of a permalink
+if ( 'categories'==$page['section'] and isset($page['category']) )
+{
+  $need_redirect=false;
+  if ( empty($page['category']['permalink']) )
+  {
+    if ( $conf['category_url_style'] == 'id-name' and
+        @$page['hit_by']['cat_url_name'] !== str2url($page['category']['name']) )
+    {
+      $need_redirect=true;
+    }
+  }
+  else
+  {
+    if ( $page['category']['permalink'] !== @$page['hit_by']['cat_permalink'] )
+    {
+      $need_redirect=true;
+    }
+  }
+
+  if ($need_redirect)
+  {
+    $redirect_url = ( script_basename()=='picture'
+        ? duplicate_picture_url()
+          : duplicate_index_url()
+      );
+    if (!headers_sent())
+    { // this is a permanent redirection
+      set_status_header(301);
+      redirect_http( $redirect_url );
+    }
+    redirect( $redirect_url );
+  }
+  unset( $need_redirect, $page['hit_by'] );
+}
+
+trigger_action('loc_end_section_init');
+?>
Index: /tags/2.0.2/include/smarty/COPYING.lib
===================================================================
--- /tags/2.0.2/include/smarty/COPYING.lib	(revision 3278)
+++ /tags/2.0.2/include/smarty/COPYING.lib	(revision 3278)
@@ -0,0 +1,466 @@
+		  GNU LESSER GENERAL PUBLIC LICENSE
+		       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+
+		  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+  
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+			    NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
Index: /tags/2.0.2/include/smarty/NEWS
===================================================================
--- /tags/2.0.2/include/smarty/NEWS	(revision 3278)
+++ /tags/2.0.2/include/smarty/NEWS	(revision 3278)
@@ -0,0 +1,1048 @@
+Version 2.6.22 (Dec 17th, 2008)
+-------------------------------
+
+- back out method chaining, bug in some versions of PCRE causes errors (mohrt)
+
+Version 2.6.21 (Dec 2nd, 2008)
+------------------------------
+
+- fix  function injection security hole closed (U.Tews)
+- fix pass expiration time at cache_handler_fuc call in core.write_cache_file.php (U.Tews)
+- Update of compiler.class.php to allow method chaining for PHP4 and PHP5 (U.Tews)
+
+Version 2.6.20 (Feb 15th, 2008)
+-------------------------------
+
+- fix cache tag bug when multiple cache tags on a page (mankyd,
+  mohrt)
+- fix /e tag checking when using arrays with regex_replace
+  (mohrt)
+- fix that function results can be used with condition like "is even" in 
+  {if} tags (U.Tews)
+- fix handling of non-empty <pre>-tags and empty <textarea>- and
+  <script>-tags (Spuerhund, messju)
+
+Version 2.6.19 (Feb 11th, 2008)
+-------------------------------
+
+- fix regex_replace allowing \0 in the search string (c960657,
+  monte)
+- add append feature to {capture} (jablko, monte)
+- fix when (un)registering filters with the same method name but different class
+  name (danilo)
+- fix calling registered objects' methods with an empty argument list
+  (marcello, messju)
+ 
+Version 2.6.18 (Mar 7th, 2007)
+------------------------------
+
+- fix html_select_date separator when parts are missing (hayk,
+  monte)
+- fix broken detection of non-cached blocks introduced in 2.6.17
+  (messju)
+
+Version 2.6.17 (Mar 5th, 2007)
+------------------------------
+
+- fix php handling (monte, boots, danilo)
+- fix handling of plugin tags directly followed by an else tag (Fahr, danilo)
+- fix handling of $etc in the truncate modifier when $etc is longer
+  than $length (Sylvinus, messju)
+- fix handling of %I with mysql timestamps in the date_format modifier
+  (danilo, boots)
+- update smarty_core_write_file() and smarty_modifier_date_format() to better
+  recognize Windows (boots, danilo)
+- emulate %h, %n, %r, %R, %t in the date_format modifier on Windows 
+  (danilo, boots)
+
+Version 2.6.16 (Dec 1st, 2006)
+------------------------------
+
+- fixed replacement bug in trimwhitespace output filter that was introduced
+  in the last release (Spuerhund, boots)
+
+Version 2.6.15 (Nov 30th, 2006)
+-------------------------------
+
+- change file writing semantics in smarty_core_write_file() to unlink() only
+  when rename() fails or a Windows system is detected (c960657, boots) 
+- update debug.tpl to xhtml 1.1 compliance, fix javascript escaping in debug
+  output and apply a Smarty based color scheme (cybot, boots)
+- enhance reporting precision of debug_print_var modifier (cybot, boots) 
+- make html_select_date work consistently with 0000-00-00 00:00:00 and
+  0000-00-00 inputs (cybot, boots)
+- fix wrong handling of insert's name attribute. (messju)
+- fix false replacement of "$t" inside double quotes (checat, messju)
+- added support for column headings and caption element to html_table and
+  updated the output to use thead/tbody elements (boots)
+- fixed ordering of replacements in trimwhitespace output filter (Getty, boots)
+- update mailto function plugin to work around a firefox/thunderbird
+  escaping bug (elijahlofgren, boots)
+- emulate %l in the date_format modifier on windows (boots) 
+- fix handling of apostrophes in capitalize modifier (Alec Smecher, boots)
+
+Version 2.6.14 (May 28th, 2006)
+-------------------------------
+
+- fix compiler bug allowing php tags in secure templates
+  (boots,monte)
+- un-hide hidden xml open tags (boots)
+- fix handling of block-methods of registered objects (El Hombre Gris,
+  messju)
+
+Version 2.6.13 (March 9th, 2006)
+--------------------------------
+
+ - update regex_replace, removing possible use of "e" modifier
+
+Version 2.6.12 (Jan 18th, 2006)
+-------------------------------
+
+ - fix improper use of references in the compiler handling cached
+   attributes and in compiled code handling block plugins (messju)
+ - make Smarty::_read_file() work on latest php (messju)
+ - fixed improper tokenization of certain inline math expressions (boots)
+
+Version 2.6.11 (Dec 14, 2005)
+-----------------------------
+
+ - fixed code generation of non-cacheable blocks to play well with php's
+   "Alternative syntax for control structures" (kihara, messju)
+ - fix handling of multiple identical inserts in one display()-call (messju)
+ - replace {} string access with equivalent substr() to avoid E_STRICT
+   warnings in PHP 5.1 (boots)
+ - return valid reference in get_config_vars() when given var is
+   non-existant (Thomas Schulz, boots)
+ - plugin html_image: fix incorrect secure_dir error when
+   file doesn't exist (monte)
+ - plugin html_image: add path_prefix param (monte)
+ - add char_set parameter to escape modifier (Loading, monte)
+ - fix notice in debug security check (Drakla, monte)
+ - return valid reference in get_template_vars() when given var is
+   non-existant (monte)
+ - add escape type "urlpathinfo" to escape modifier (monte)
+
+Version 2.6.10 (Aug 5, 2005)
+----------------------------
+
+  - allow secure_dir to be a filename, not just
+    a directory name (monte)
+  - set debug.tpl as a secure_dir, not the entire
+    SMARTY_DIR (monte)
+  - fix proper escaping for literal strings in
+    Smarty_Compiler::_parse_var_props() (boots, messju)
+  - remove ambiguity for numeric values passed to smarty_make_timestamp()
+    (and thus the date_format modifier). numeric values are treated as
+    timestamps now. (andreas, messju)
+  - add passthru attribute feature to html_select_date (Sedgar,
+    monte)
+  - add "middle" parameter to truncate (monte)
+  - make form input label ids optional (monte)
+  - add error message for empty if/elseif statements (eykanal,
+    monte)
+  - cast selected value to string for comparison in html_radios
+    (Exeption, monte)
+  - updated html_select_date's year_as_text-feature to be xhtml compliant
+    (Mark West, messju)
+  - fix handling of selected month html_select_date (Yuri Weseman, messju)
+
+Version 2.6.9 (Mar 31, 2005)
+----------------------------
+
+  - disallow variable function calls in {if} statements (messju, monte)
+  - disallow variable function calls in {math} equations (messju, monte)
+
+Version 2.6.8 (Mar 21, 2005)
+----------------------------
+
+  - remove e-modifier from regex_replace modifier (messju)
+  - remove cast of object to array in foreach's from-attribute (messju)
+  - add "null" as a valid token for {if} when security is enabled (messju)
+  - add javascript_charcode encoding option to mailto function
+    (monte)
+  - add ids to html_radios labels (monte, menulis)
+  - fix handling of strip-tags with non-default delimiters (Mark West, messju)
+
+Version 2.6.7 (Feb 3, 2005)
+---------------------------
+
+  - fix handling of hashed opening php-tags inside strip-blocks (messju)
+  - removed border tag from html_image function (monte)
+  - change escape:url use rawurlencode() instead of urlencode() (messju)
+  - make $smarty.const.FOO compile to "FOO", and not to "constant('foo')".
+    this is less code and a little faster execution. note that undefined
+    constants are now displayed as the constant's name. (messju)
+  - make block functions and registered objects' block methods use a
+    local variable for block_content instead of a property of $smarty (messju)
+  - fix escaping in the generated code that calls smarty_core_load_plugins
+    (jes5199, messju)
+  - fix invalid HTML issue with popup (Stefanos Harhalakis,
+    Monte)
+  - fixed {popup} to properly handle inarray and function parameters and added
+    support for mouseoff and followmouse options (boots)
+
+Version 2.6.6 (Oct 13, 2004)
+----------------------------
+
+  - fixed nocache-handling with nested includes (Lars Jankowfsky, messju)
+  - moved /libs/core to /libs/internals (boots)
+  - fixed more parsing problems (messju)
+
+Version 2.6.5 (Sept 13, 2004)
+-----------------------------
+
+  - fixed some parsing problems with object calls introduced
+    in 2.6.4 (Monte)
+  - add $smarty->security_settings['ALLOW_CONSTANTS']. note: this
+    defaults to false which means you have to allow them explicitly
+    in your secured templates from now on! (messju)
+
+Version 2.6.4 (Sept 7, 2004)
+----------------------------
+
+  - add $smarty.ldelim and $smarty.rdelim to smarty special var (Monte)
+  - fall back to old uniqid()-behaviour when tempnam() fails in
+    core.write_file.php (messju)
+  - fix capitalize modifier, don't rely on buggy ucwords (Monte)
+  - make html_select_date work with negative timestamps, also
+    force year range to include given date unless explicitly
+    set (Garo, Monte)
+  - fix bug with {fetch}, passing user/pass in url did not work
+    (Monte)
+  - fix occasional wrong error messages on mismatched tags when
+    {else}, {elseif}, {foreachelse} or {sectionelse} is involved (messju)
+  - fix handling of methods arguments (messju, Manfred Wischin)
+  - remove touch() call that made the compiled-template's timestamp the
+    same as the source-template's one. (messju)
+  - add assign attribute to html_checkboxes and html_radios
+    (pcg, Monte)
+  - remove non-xhtml conformant tag from mailto function
+    (tacker, Monte)
+  - handle date_format codes %e, %T and %D for windows (tip,
+    Monte)
+  - fix unnecessary call to smarty_core_get_include_path() inside
+    Smarty::_get_auto_filename() (c960657, messju)
+  - add error-messages when anything else than an identifier is passed
+    to foreach's key- or item-attribute (messju)
+  - fix handling of digits inside tagnames (messju)
+  - fix escaping of backslashes in Smarty_Compiler::_quote_replace() (messju)
+
+Version 2.6.3 (June 16, 2004)
+-----------------------------
+
+  - added escapement of '</' to '<\/' in escape:javascript
+    modifier (c960657, Monte)
+  - added obfuscation of protocol-string in {mailto} when using hex-
+    encoding (bharat, messju)
+  - enhanced auto-generated filenames for templates_c and cache (messju)
+  - add 'nonstd' to escape modifier for escaping non-std chars,
+    such as ms doc quote (Monte)
+  - adjusted textformat to not output wrap chars after last para
+    (Monte)
+  - use tempnam() instead of unqid() to create better temporary files in
+    smarty_core_write_file() (xces, messju)
+  - add 'mail' to escape modifier for safe display of e-mail
+    addresses (Monte)
+  - add cycle function attribute "reset" to english docs (Monte)
+  - enhanced support of numeric constants as variable-expressions (messju)
+  - add case decentity to smarty_modifier_escape() (Konstantin A. Pelepelin,
+    messju)
+  - make smarty_core_write_compiled_include() php5-aware (messju)
+  - removed unused functionality to load a subset of lines from a file (messju)
+  - fix is_secure() should only check if a file is_readable, not if
+    the directory where it is in is readable (sagi, messju)
+  - fix problem displaying debug console when $default_resource_type
+    is not "file:" (c960657, Monte)
+  - fix permission handling with security and config_load (messju)
+  - removed '.' from the list of default template locations in
+    _parse_resource_name() (messju)
+  - fix avoid warning with template_exists() on an absolute paths (messju)
+  - fix parameters passed to resource's secure()-function (messju)
+  - fix handling of integer values like width and delay im
+    smarty_function_popup() (messju)
+
+Version 2.6.2 (Feb 17, 2004)
+----------------------------
+
+  - fix allow empty years, months and days in html_select_date's
+    time-attribute (messju)
+  - fix YES and NO should not be booleanized inside triple-quotes in a
+    config-file (messju)
+  - fix accidently slurped line following a triple-quoted value in a
+    config-file (messju)
+  - change default for use_sub_dirs to false (messju)
+  - fix quoting of values in smarty_function_popup() (messju)
+  - fix handling of hidden sections in Config_File (messju)
+  - add handling of resources for {config_load} (messju)
+  - fix bug when using arrays with tr_attr and td_attr in {html_table} (messju)
+  - add unit testing to cvs core (Monte)
+
+Version 2.6.1 (Jan 16, 2004)
+----------------------------
+
+  - rename $smarty->tpl_error_reporting to $smarty->error_reporting
+    (messju)
+  - fix interpretation of $smarty->security in {html_image} (messju)
+  - add caching of requested paths to _assemble_plugin_filepath() (messju)
+  - fix handling of comments inside {php}- and {literal}-blocks (messju)
+  - fix bug handling triple-quotes in config-files (BRDude, messju)
+  - change default of request_use_auto_globals to true - $_SERVER is
+    now preferred over $HTTP_SERVER_VARS (messju)
+  - re-add support for $SCRIPT_NAME (messju)
+  - reactivate $smarty->default_modifiers (messju)
+  - add cookie persistance to debug console (Monte)
+  - allow single-digit days and months without smarty_make_timestamp()
+    in html_select_date (messju)
+  - fix headers sent erroneously with cache_modified_check and fetch()
+    (wphilips, messju)
+  - fix config_file path bug (Marc Cabadas, Monte)
+  - fix 'is even by' and 'is odd by' logic (Monte)
+  - add day_empty, month_empty, year_empty and all_empty attributes to
+    html_select_date (messju)
+  - add table of explanation for {if} qualifiers in docs (boots)
+  - fix bug when comparing array-keys to "selected" in html_options
+    and html_checkboxes (messju)
+  - add better checks for correctly nested tags when compiling (messju)
+  - remove {$SCRIPT_NAME}. use {$smarty.server.SCRIPT_NAME} instead (messju)
+  - remove $global_assign. assign global variables explicitly instead (messju)
+  - fix example for count_characters in docs (boots)
+  - add section new basic syntax section "Escaping Smarty Parsing" in docs (boots)
+  - fix error handler call in config_load (boots)
+  - remove warning in debug_print_var on php-resources (messju)
+  - move function.assign.php to compiler.assign.php (messju)
+  - add property $tpl_error_reporting (messju)
+  - remove property $undefined. "null" is used literally instead (messju)
+
+Version 2.6.0 (Nov 19, 2003)
+----------------------------
+
+  - move Smarty::quote_replace() to Smarty_Compiler::_quote_replace() (messju)
+  - remove import of of attributes of {include_php} to php's namespace.
+    use $params[name] instead (messju)
+
+Version 2.6.0-RC3 (Nov 13, 2003)
+--------------------------------
+
+  - fix handling of $var.key inside [] (messju)
+  - fix handling of assign inside {insert}-tags (messju)
+  - fix handling if [...] inside triple-quotes in config-files (messju)
+  - fix handling of simple-math-operators inside modifiers (Dominik, messju)
+  - fix handling of trailing-slashes in open_basedir in
+    smarty_core_create_dir_structure() (packman, messju)
+
+Version 2.6.0-RC2 (Oct 8, 2003)
+-------------------------------
+
+  - apply modifiers only once to section-loop and foreach-from attrs (messju)
+  - remove use of _smarty_cached_paths-files (messju)
+  - remove Smarty::_plugin_implementation_exists() - use is_callable() (messju)
+  - ignore {strip}/{/strip) inside {strip}-blocks (messju)
+  - fixed removal of leading/trailing newlines in {strip}-blocks (messju)
+  - fixed proper escaping of " and ' with escape:javascript (messju)
+  - fixed bug in traversal of $smarty->plugins_dir-array. now the
+    first matching plugin is taken (messju)
+  - moved {strip} back into the compiler (messju)
+  - fixed config_load: handling of section-attribute and use of
+    multiple config-files in one template (atu, messju)
+
+Version 2.6.0-RC1 (August 11, 2003)
+-----------------------------------
+
+  - fixed status-header for cache_modified_check under cgi-sapi (messju)
+  - added optional parameter $cache_attrs to register_function() and
+    register_block(). $cache_attrs is an array containing attribute-
+    names that should be cached on calls to functions that have
+    $cacheable set to false. (messju)
+  - enabled registration of class-methods as callbacks for the register_*-
+    functions (use: array('classname', 'method_name')) as callback) (messju)
+  - added filepath caching (Monte)
+  - added optional assign-attribute to {capture}-tag (messju)
+  - added $cacheable-parameter to register_compiler_function() (messju)
+  - added $cacheable-parameter with default=true to register_function()
+    and register_block() (messju)
+  - add math speedup to core (Dominik, Monte)
+  - fix newlines for tags without template output (Monte)
+  - added config-option "request_use_auto_globals" to make auto-globals be
+    used as request vars instead of HTTP_*_VARS (messju)
+  - speed up config_load, simplify compiling (Monte)
+  - added block-methods for registered objects (Bharat Mediratta, messju)
+  - ignore one char resource names like c:foo.tpl (Monte)
+  - added default_resource_type feature (Monte)
+  - fix bug where config file starts with hidden section (boots, Monte)
+  - add discrete error checking pertaining to $cache_dir
+    and $compile_dir, their existance and writability (Monte)
+  - fixed behaviour of start=... for {counter} (messju)
+  - fixed assign for {counter} (messju)
+  - added params vdir, hdir and inner to html_table to allow looping
+    over the data in various directions (messju)
+  - allow spaces in literal tags (Paul Lockaby, Monte)
+  - speed up compiled templates, hardcode plugin filepaths
+    instead of dynamically calculate at runtime. (Monte)
+  - abstract many core components from Smarty.class.php,
+    speeding up core class instantiation (Monte)
+  - fixed bug in _create_dir_structure() when used with open_basedir-
+    restriction and relative paths (messju)
+  - use DIRECTORY_SEPARATOR exclusively, keep DIR_SEP for BC (Monte)
+  - changed "link" to "href" in html_image. "link" is still working
+    but deprecated (messju)
+  - html_image always renders an alt-tag now (default alt="") (messju)
+  - fixed assign attribute for multiple counters (messju)
+  - added simple math operators to variables (Monte)
+  - enabled array(&$obj. 'source', 'timestamp', 'secure', 'trusted')
+    as callback for register_resource() (messju);
+  - enabled array(&$obj, 'method') as callback for
+    $default_template_handler_func (messju)
+  - remove unnecessary close/open tags from compiled templates
+    (Monte)
+  - fixed errornous creation of '//' in image_path in html_image (messju)
+  - fix escapement of special chars for key vals in debug
+    console (Monte)
+  - fixed debug timing logic for config_load (Tom Sommer, Monte)
+  - all in-code doc comments converted to phpDocumentor format (Greg)
+  - moved strip from smarty core to plugin (Monte)
+  - moved config_load from smarty core to plugin (Monte)
+  - added &$repeat-parameter to block-functions (messju)
+  - enabled hex-constants in function.math.php (messju)
+  - enabled hex-constants (0x...) as function-attributes, inside if-statements
+    and as modifier-parameters (messju)
+  - fixed bug with passing $smarty as reference in Smarty.compiler.class
+    (messju)
+  - corrected output with {strip} and PHP tag newlines (Monte)
+  - added possibility to register function-callbacks as "array(&$obj, 'method)"
+    this affects register_function(), -block, -compiler_function, -modifier,
+    -prefilter, -postfilter, -outputfilter-functions() and $cache_handler_func
+    (messju)
+  - added <labels> to html_checkboxes and html_radios (Philippe, messju)
+  - added "labels"-options to turn off labels in html_checkboxes and _radios
+    (messju)
+
+Version 2.5.0 (April 11, 2003)
+------------------------------
+
+   - fixed bug with default modifier when passing integer 0
+     (Monte)
+   - change backtic syntax from $`foo` to `$foo` (Monte)
+   - recognize $foo[][] syntax inside embedded quotes without
+     backtics (Monte)
+   - name=123 is passed as an integer (not a string) to plugins now (messju)
+   - $length is now propagated to sub-values in debug_print_var (messju)
+
+Version 2.5.0-RC2 (March 26, 2003)
+----------------------------------
+
+    - made clear_cache() ignore compile_id, when clearing cache-groups (this
+      is when no $tpl_file is supplied) (messju)
+    - made onmouseout XHTML-compliant in function.popup.php (messju)
+    - applied local-var-naming-scheme to fetch() (messju)
+    - renamed $localvars to $_localvars in cache-file-handling-functions,
+      added _get_auto_id()-function (messju)
+    - swapped compile_id and cache_id in read_cache_file and write_cache_file
+      (messju)
+    - reverted patch for cache-file-handling (messju)
+    - made html_radios and html_checkboxes accept "selected" instead
+      of "checked" optionally. (messju)
+    - made compile_id ignored in clear_cache, made order of
+      auto_file_name $cache_id.$compile_id again, applied the the new
+      variable-naming-scheme for cache_file_handing functions (messju)
+    - removed notice of undefined var in _rm_auto() (messju)
+    - added warning message when an array is passed as
+      the "checked" value of html_radios (Monte)
+    - fixed errormessage in _compile_smarty_ref() (messju)
+    - updated docs for html_image "name" -> "file" (messju)
+    - fixed bug with html_options-optgroups (Nichlas Löfdahl, messju)
+    - cleaned up calls to readdir() (messju)
+    - fixed bug with passing multiple modifiers to a parameter
+      (Monte)
+    - updated docs for html_checkboxes, html_options and html_radios (messju)
+    - fixed wrong default "name" attribute for html_options (messju)
+    - html_checkboxes now expect the options as attribute "options" instead
+      of "checkboxes. html_radios expect "options" instead of "radios".
+      cleaned up indentiation (messju)
+    - fixed too greedy str_replace in trimwhitespace outputfilter (messju)
+    - html_checkboxes and html_radios passthru all unknown paramters now
+      additionally their output is now XHTML compliant (messju)
+    - html_options passthru all unknown paramters now (messju)
+    - fix link functionality of html_image, also make
+      output XHTML compatible (Hinrich Donner, Monte)
+    - append "@" to default modifier vars/args
+      supress possible warnings (Monte)
+    - fix problem with escaped double quotes (Monte)
+    - fix html_radios to not return an array (Monte)
+    - fixed length in modifier.truncate.php (messju)
+    - fixed handling of '$'-signs in trimwhitespace outputfilter (messju)
+    - fix bug that makes config files recompile every time
+      (Nagger, Monte)
+    - add dpi functionality to html_image, change "name"
+      parameter to "file" (Thomas Shulz, Monte)
+    - fix height/width parameter index in html_image (Gerard,
+      Monte)
+    - get rid of unsetting name and script attributes
+      to insert tag (Thomas Schulz, Monte)
+    - changed argument order of string_format modifier back,
+      was right in the first place (Monte)
+
+Version 2.5.0-RC1 (March 5, 2003)
+---------------------------------
+
+    - fixed notice in popup function (Nagger, Monte)
+    - fix "once" var compiling for include_php (Monte)
+    - added nl2br modifier to distribution (Monte)
+    - added html_image to distribution (Monte)
+    - added cat modifier to distribution (Monte)
+    - added html_table to distribution (Monte)
+    - added << >> <> support to if statments (SMK, Monte)
+    - fix _assign_smarty_interface to not overwrite keys
+      other than 'request' (Jerome Poudevigne, Monte)
+    - added html_checkboxes to distribution (Christopher Kvarme, Monte)
+    - added html_radios to distribution (Christopher Kvarme, Monte)
+    - fixed string_format modifier args (wrong order) (Paul
+      Lockaby, Monte)
+    - use tmp file for file writes, avoid file lock race (Monte)
+    - support syntax "$`smarty.config.foo`.tpl" for embedded
+      vars in quotes, and allow full dollar var syntax (Monte)
+    - add $smarty.config.varname variable for accessing config vars (Paul
+      Lockaby, Monte)
+    - silence PHP warnings in function.fetch.php (Eduardo,
+      Monte)
+    - added get_config_vars(), same basic functionality as
+      get_template_vars() (Monte)
+    - update get_template_vars() to be able to get
+      individual vars (Monte)
+    - fix minor logic in _fetch_template_info (Dennis Gearon,
+      Monte)
+    - fix cache groups with compile_id set (Monte)
+    - add support for merging appended vars (messju, Monte)
+    - allow null as function attribute value
+      (André Rabold, Monte)
+    - support $foo->bar[index] syntax (Monte)
+    - add get_registered_object function (messju, Monte)
+    - treat unrecognized param attribute syntax as string (Monte)
+    - support $smarty.const.$foo syntax (messju, Monte)
+    - remove E_NOTICE warnings from debug.tpl,
+      escape modifier (Kanstantin, Monte)
+    - don't count non-ascii chars in count_words modifier
+      (Kanstantin, Monte)
+    - clean up param calls to _parse_var and _parse_attrs (Monte)
+    - define $template_source var, elude possible warning
+      (Monte)
+    - fix syntax problem with evaluating PHP constants (Monte)
+    - add @ and === as valid if statement tokens (Monte)
+    - enable error messages for config_load errors,
+      use $this->config_class for loading class name (Monte)
+    - fix html_options to not escape already escaped entities (Monte)
+    - send Last-Modified header on cache creation (Monte)
+    - check strict syntax of function attributes (Monte)
+    - dropped support for modifers on object parameters,
+      added support for objects as modifier parameters (Monte)
+    - fixed bug with decimal numbers in if statements (Monte)
+
+Version 2.4.2 (Feb 11, 2003)
+----------------------------
+    - support embedded variables in objects (Monte)
+    - fix bug with objects with no properties (M Mohr, Monte)
+    - support full dollar var syntax in quoted text (Monte)
+    - fixed bug in $smarty.const.FOO introduced in 2.4.1 (M
+      Mohr, Monte)
+
+Version 2.4.1 (Feb 6, 2003)
+---------------------------
+
+    - ignore case in IF statements (Rainer Collet, Monte)
+    - treat undefined constants as null (Ferdinand Beyer, Monte)
+    - fix problem with inserts and nested fetches
+      (Rainer Collet, Monte)
+    - added support for passing params to include_php
+      (Tim Riley, Monte)
+    - added support for math operators in if statements (Monte)
+    - added support for $foo->bar[$x].blah syntax (Monte)
+
+Version 2.4.0 (Feb 2, 2003)
+---------------------------
+
+    - fix known problems with php tag handling in templates
+      (recursion, echoing xml tags) (Monte)
+    - add support for object registration (Monte)
+    - add debug template to secure_dir, add template_dir
+      to secure_dir by default (Ferdinand Beyer, Monte)
+    - added support for assigned object access (Monte)
+    - fixed bug with directories named '0' (Frank Bauer, Monte)
+    - add javascript parameter to escape modifier (Monte)
+    - added calling function line numbers to syntax error
+      messages in compiler (Monte)
+    - added support for modifiers to function calls (Monte)
+    - support return value for custom functions
+      instead of echoing (but echo still works) (Monte)
+    - added direct access to constants
+      via $smarty.const.FOO (Monte)
+    - added support for passing modifiers
+      to static values (Monte)
+    - fix up regex code in compiler, more accurate and
+      maintainable (Monte)
+    - added day_value_format to html_select_date (Marcus
+      Bointon, Monte)
+    - assigned variables are no longer in global
+      namespace, saving extract() calls and speeding
+      up fetch() and display() linearly with no. of
+      assigned variables (Monte)
+    - added trimwhitespace output filter to dist. (Monte)
+    - fix popup function to allow newlines in text (Monte)
+    - escape html entities in html_options (Monte)
+    - fixed bug with label for html_options (Monte)
+    - added config_load API function (Monte)
+    - added caching to config file loading (Monte)
+    - added "extra" parameter to mailto function (Monte,
+      Massimiliano Perantoni)
+    - added mailto plugin to dist.  (Monte)
+
+Version 2.3.1 (Nov 19, 2002)
+----------------------------
+
+    - added optgroup support to html_options (Monte, Robert
+      Amos)
+    - set mtime on compile files so they match source
+      files (Monte, Peter Bowen)
+    - added proper support for open_basedir setting
+      (Monte, Alessandro Astarita)
+    - added strip variable modifier, updated docs (Monte)
+    - fixed access to $smarty.x variables as arrays. (Andrei)
+    - fixed errors with example setup docs (Monte, Matthew
+      Hagerty)
+    - added textformat block function (Monte)
+
+Version 2.3.0 (Aug 7, 2002)
+---------------------------
+
+    - added assign_by_ref() and append_by_ref() functions
+      (Bob Silva, Monte)
+    - changed default warning type for plugin errors from
+      E_USER_WARNING to E_USER_ERROR (Monte)
+    - added $all_extra, $hour_extra, $minute_extra,
+      $second_extra and $meridian_extra parameters to
+      html_select_time function (Rainer Collet, Monte)
+    - update debug console to print objects (Simon Willison,
+      Monte)
+    - fix Config_File class to not error when there are no
+      sections (Peter Kmet, Monte)
+    - add default modifier logic (Monte)
+    - updated popup_init to be xhtml compliant (Tom Oram, Monte)
+    - fix filename bug with windows (Gary Loescher, Monte)
+    - add ability to supply expire time in seconds when clearing
+      cache or compile files (Monte)
+    - add {debug} plugin to distribution (Monte)
+    - fixed bug with insert tags, loading from "script" attribute
+      when caching is enabled (Monte)
+    - fix bug with debug_tpl file path with Windows (.SMK., Monte)
+    - fix append() function with string/array problem (Monte)
+
+Version 2.2.0 (July 11, 2002)
+-----------------------------
+
+    - make debug.tpl work with any delimiter (Monte)
+    - change logic in assign() and append() to test var names
+      against != '' instead of empty() (Monte)
+    - fix PHP notice in append() function (Monte)
+    - allow $plugins_dir to be an array of directories
+      (Andreas Kossmeier, Monte)
+    - move debug.tpl to SMARTY_DIR, add to constructor (Monte)
+    - fixed warning message in function.assign_debug_info (Monte)
+    - fixed $template_dir, $compile_dir, $cache_dir, $config_dir,
+      $plugin_dir to respect include_path (Monte)
+    - fixed warning message with output filter array (Monte)
+    - add optional 2nd parameter to date_format, used as
+      the default date if the passed date is empty (Monte)
+    - gave $reset a default value in cycle plugin (Monte)
+    - fixed warnings with html_select_date and timestamp
+      functions (Monte)
+    - added support for sub directory exlusion format (Monte)
+    - added support for grouping by cache_id, compile_id
+      and segments thereof (Monte)
+    - changed cache and compile files to human readable
+      format (Monte)
+    - remove overlib.js file from distribution (Monte)
+    - fixed bug with 304 Not Modified response sending
+      content (Monte)
+    - fixed cycle function to respect delimiter after
+      initial setting (Monte)
+    - update $GLOBALS references to work properly with
+      track_globals settings (Michal Prinke, Monte)
+    - fixed bug in math function with call to assign
+      (Grigory V. Kareev, Monte)
+    - optimized for loops with count() function calls (Monte)
+    - add month_value_format attribute to html_select_date
+      plugin (Gary Loescher, Monte)
+    - made it possible to use simple variables inside [] for
+      indexing. (Andrei)
+    - added "once" attribute to {include_php}. (Monte)
+
+Version 2.1.1
+-------------
+    - added cycle function. (Monte)
+    - fixed bug with resource testing, and include_path. (Monte)
+    - fixed a bug with register_outputfilter function. (Monte)
+
+Version 2.1.0
+-------------
+
+    - introduced output filters. (Andrei)
+    - changed the way filters are loaded, added load_filter()
+      API function and $autoload_filters variable. (Andrei)
+    - added caching logic for expire times per cache file
+      (Norbert Rocher, Monte)
+    - fixed html_select_date when field separator is "/"
+      (Roberto Berto, Monte)
+    - added YYYY-MM-DD format support to html_select_date
+      (Jan Rosier, Monte)
+    - fixed cache_lifetime logic bug, also made -1 = never
+      expire (Monte)
+    - fixed directory separator issue for Windows. (Andrei)
+    - added ability to use simple variables as array indices or
+      object properties. (Andrei)
+    - added ability to unregister pre/postfilters plugins at
+      runtime. (Andrei)
+    - added 'htmlall' attribute to escape modifier. (Monte)
+    - added template_exists() API function. (Andrei)
+    - fixed a problem with using dynamic values for 'file'
+      attribute of {include_php} tag. (Andrei)
+    - added $smarty.template variable. (Andrei)
+    - fixed several plugins that would not work if the plugin
+      directory was not the default one. (Andrei)
+    - implemented support for block functions. (Andrei)
+    - made it possible to assign variables in pre/postfilter
+      plugins. (Andrei)
+
+Version 2.0.1
+-------------
+    - rename plugin .make_timestamp.php to shared.make_timestamp.php.
+      (Monte)
+    - changed crc32() generated values, replace '-' with 'N'. (Monte)
+    - added support for +/- N syntax in html_select_date year values.
+      (Monte)
+    - fixed behavior of inserts with script attribute. (Andrei)
+    - fixed bug with $smarty.cookies and $smarty.server. (Andrei)
+    - wordwrap and indent are missing from 2.0 release, now fixed.
+      (Monte)
+    - removed show_info_header and show_info_include variables. (Monte)
+
+Version 2.0.0
+-------------
+    - added "eval" function plugin for evaluating variables as
+      templates. (Monte)
+    - removed $tpl_file_ext class variable, no longer used. (Monte)
+    - added "hex" and "hexentity" escape types to escape modifier.
+      (Monte)
+    - removed dependency on PEAR. (Andrei)
+    - update popup_init to accept src attribute. (Monte, Duncan Forrest)
+    - implemented several optimizations, speeding up Smarty
+      significantly in most cases. (Andrei,Monte)
+    - implemented plugin architecture. (Andrei)
+    - added wordwrap and indent modifiers. (Monte)
+    - added support for 'If-Modified-Since' headers for cached content.
+      (Monte)
+    - removed insert_tag_check class variable, no longer needed. (Monte)
+    - optimized cache fetches by scanning for insert tags only if they
+      exist. (Monte)
+    - fixed bugs in overlib. (Monte, Duncan Forrest)
+    - fixed a problem with compile_id usage. (Andrei)
+    - fixed problem with using assigned vars with {include_php ...}
+      filepath. (Monte)
+
+Version 1.5.2
+-------------
+    - added Smarty object as fifth argument for template resource functions.
+      (Monte)
+    - fixed a bug with incorrectly combined cache and compile id in
+      clear_cache(). (Andrei)
+    - fixed bug in smarty_make_timestamp introduced in PHP 4.1.0. (Monte)
+    - fixed bug with cached insert debug timing. (Monte)
+    - added 'script' attribute to {insert..} which specifies the script that
+      the insert function can be found in. (Andrei)
+    - added default template function handler. (Monte)
+
+Version 1.5.1
+-------------
+    - removed error message from the generic _read_file() method, the caller
+      should take care of that. (Andrei)
+    - fixed a bug with incorrectly combined cache and compile id. (Andrei)
+
+Version 1.5.0
+-------------
+    - added include_php built-in function, documented. (Monte)
+    - added trusted_dir functionality, documented. (Monte)
+    - consolidated secure_dir tests to one function. (Monte)
+    - prepended _smarty_ to variable names in fetch() class function to avoid
+      namespace conflicts. (Monte)
+    - introduced $compile_id class variable that can be used to set persistent
+      compile identifier across multiple display calls, documented. (Andrei)
+    - fixed bug with concatenated null cache and compile identifiers. (Andrei)
+    - added $smarty.section.* syntax for accessing section properties,
+      documented. (Andrei)
+    - added custom cache handling function ability, documented. (Monte)
+    - added assign attribute to include, include_php, insert, fetch, math, and
+      counter functions, documented. (Monte)
+    - fixed bug with fetch testing for local file when http address. (Monte)
+    - fixed bug with counter and skipval setting. (Monte)
+    - made {config_load ...} merge globals from each config file only once per
+      scope, thus avoiding several problems. (Andrei)
+    - added {foreach ...} tag that can be used to iterate through
+      non-sequential and associative arrays, documented. (Andrei)
+    - speeded up section property access a bit. (Andrei)
+    - removed $smarty variable from storage used by normal template variables,
+      to prevent any problems. (Andrei)
+    - fixed a bug that could cause parse error with quotes inside literal
+      blocks. (Andrei, Alexander Belonosov)
+    - added 'field_array' attribute to html_select_time function, documented.
+      (Andrei, Michael Caplan)
+    - documented {section} "max" attribute. (Monte)
+    - fixed notice message in Smarty_Compiler.class.php. (Monte)
+    - fixed bug with clear_cache introduced in 1.4.6, third parameter should
+      default to null. (Monte)
+    - updated Config_File class to support '\' path separator in OS/2. (Monte,
+      Francesco Cipriani)
+    - removed secure_ext setting (not used). (Monte)
+    - made cache reading process more efficient. (Monte)
+    - fixed bug, is_cached() now supports new 1.4.6 caching behavior. (Monte)
+    - update FAQ with mailing list Reply-To header FAQ. (Monte)
+    - supress error messages for fopen(), fix cache to regenerate if cache
+      file is not available (i.e. cluster race condition). (Monte)
+    - added index key example to QUICKSTART guide. (Monte)
+
+Version 1.4.6
+-------------
+    - fixed bug with {assign ...} when passing an empty value. (Monte)
+    - add more warning message fixes. (Monte, Tara Johnson)
+    - documentation updates. (Monte)
+    - update fetch function to give proper warning when fetching a non-readable
+      or non-existant file. (Monte)
+    - fixed problem with newline at the end of included templates (Monte, Andrei)
+    - added feature to regenerate cache if compile_check is enabled and an
+      involved template or config file gets modified. (Monte)
+    - added DEBUG execution times to included files: REQUIRES updated debug.tpl
+      file! (Monte)
+    - added support for hidden config variables that cannot be read by
+      templates. (Andrei)
+    - added execution time to DEBUG console, total and inserts. (Monte)
+    - fixed bug where DEBUG console would not appear with cached content. (Monte)
+    - added support for postfilter functions that are applied to compiled
+      template right after compilation. (Andrei)
+    - fixed the name of clear_compile_tpl() API function to clear_compiled_tpl.
+      (Andrei)
+    - added fix for removing comments so that the line numbers are reported
+      correctly in case of errors. (patch from Anders Janson)
+    - made html_options output xhtml compatible code. (Monte, Arnaud Limbourg)
+
+Version 1.4.5
+-------------
+    - update FAQ with index of questions at the top
+    - update overlib to 3.50, adjust addon code so that the overlib.js
+      file isn't modified, and not using the mini one. (Monte)
+    - added many more options to html_select_date. (Alexander Skwar, Andrei)
+    - added support for generating different compiled templates from the same
+      source template. (Hans-Peter Oeri, Andrei)
+    - modified Smarty to pass itself to insert functions as the second
+      parameter. (Andrei)
+    - modified Smarty to pass itself to prefilter functions as the second
+      parameter. (Andrei)
+    - fixed syntax error when including a non-existant template with security
+      enabled. (Monte)
+    - fixed comments handling to allow commenting out template blocks. (Andrei)
+    - implemented named capture buffers, with results accessible via
+      $smarty.capture.<name>. (Andrei)
+    - added ability to index arrays directly by numbers. (Andrei)
+    - fixed bug with SMARTY_DIR not prepended to Config_File include. (Monte)
+
+Version 1.4.4
+-------------
+    - fixed problem with including insecure templates with security enabled.
+      (Monte)
+    - numerous documentation updates. (Monte)
+    - added ENT_QUOTES to escapement of html. (Monte, Sam Beckwith)
+    - implemented access to request variables via auto-assigned $smarty
+      template variable. (Andrei)
+    - fixed a bug with parsing function arguments inside {if} tags if a comma
+      was present. (Andrei)
+    - updated debug console with config file vars. (Monte)
+    - added SMARTY_DIR constant as an alternative to relying on include_path.
+      (Monte)
+    - added popup_init and popup functions (requires overlib.js). (Monte)
+    - updated debug console with config file vars. (Monte)
+    - added debugging url control. (Monte)
+    - added 'quotes' type to escape modifier. (Monte, Mike Krus)
+    - added 'total' and 'iteration' section properties. (Andrei)
+    - added 'start', 'max', and 'step' section attributes/properties. (Andrei)
+    - fixed a bug with security checking of functions inside {if} tags.
+      (Andrei)
+    - fixed a bug in Config_File that would incorrectly booleanize values that
+      weren't really booleans. (Andrei)
+
+Version 1.4.3
+-------------
+    - added regex_replace modifier, documented. (Monte)
+    - added debugging console feature and custom function assign_debug_info,
+      documented. (Monte)
+    - added 'scope' attribute for {config_load}, 'global' is now deprecated but
+      is still supported. (Andrei)
+    - reduced template symbol table pollution by moving config array into the
+      class itself. (Andrei)
+    - fixed a bug with passing quoted arguments to modifiers inside {if}
+      statements. (Andrei, Sam Beckwith)
+    - added security features for third party template editing, documented
+      (Monte)
+    - added assign custom function, documented. (Monte)
+    - fixed bug with template header using version instead of _version. (Monte)
+    - fixed a problem with putting $ followed by numbers inside {strip} and
+      {/strip} tags. (Andrei)
+    - fixed Config_File class to allow empty config paths (defaults to current
+      directory). (Andrei)
+
+Version 1.4.2
+-------------
+    - move $version to internal variable, remove from docs. (Monte)
+    - cleaned up compiled templates global scope by moving some variables into
+      the class itself. (Andrei)
+    - fixed a bug that would not allow referring to a section in the including
+      file from the included file. (Andrei)
+    - configs directory missing from 1.4.1 release, added back in. (Monte)
+    - added windows include_path setup instructions to FAQ & QUICKSTART.
+      (Monte)
+
+Version 1.4.1
+-------------
+    - fix LOCK_EX logic for all windows platforms (Monte)
+    - fixed indexing by section properties with the new syntax. (Andrei)
+    - updated Smarty to use absolute paths when requiring/including Smarty
+      components. (Andrei, John Lim)
+
+Version 1.4.0
+-------------
+    - added {capture}{/capture} function, documented (Monte)
+    - added {counter} function, documented (Monte)
+
+Version 1.4.0b2
+---------------
+    - fixed issue in Config_File.class with referencing blank sections (Andrei)
+    - fixed problem with passing variables to included files (Andrei)
+    - fixed resource path recognition for windows (Monte)
+
+Version 1.4.0b1
+---------------
+    - added "componentized templates" tip into documentation (Monte)
+    - added {php}{/php} tags for embedding php code into templates (Monte)
+    - changed default value of $show_info_header to false (Monte)
+    - implemented '->' syntax for accessing properties of objects passed to the
+      template. (Andrei)
+    - allowed custom functions to receive Smarty object as the second
+      parameter; this can be used to dynamically change template variables, for
+      example. (Andrei)
+    - added custom compiler functions support, register_compiler_function() and
+      unregister_compiler_function() API functions. (Andrei, Ivo Jansch).
+    - updated GLOBAL_ASSIGN to take SCRIPT_NAME from HTTP_SERVER_VARS
+      instead of global variable. You can also assign several variables
+      in one shot with an array. (Monte, Roman Neuhauser)
+    - added template prefilters, register_prefilter() and
+      unregister_prefilter() API functions. (Monte)
+    - added RELEASE_NOTES file to distribution. (Monte)
+    - moved CREDITS out of manual into its own file. (Monte)
+    - added register_resource() and unregister_resource() API functions. (Monte)
+    - changed the syntax of indexing template variables, thus supporting
+      structures of arbitrary complexity; supplied fix_vars.php script to fix
+      old syntax. (Andrei)
+    - added $insert_tag_check to speed up cached pages if {insert ...} is not
+      used. (Monte)
+    - added $compiler_class variable to allow specifying a different compiler
+      class. (Andrei)
+    - changed Smarty to compile templates at runtime, allowing for arbitrary
+      template resources. (Monte)
+    - added fix for LOCK_EX under Windows and changed a couple of file
+      permissions for security. (Monte, Fernando Nunes)
+    - allow arbitrary date strings to date_format, html_select_date and
+      html_select_time (Monte)
+
+Version 1.3.2
+-------------
+    - fixed a bug that caused some nested includes to loop infinitely. (Andrei)
+    - added optional HTML header to output. (Monte)
+    - significantly improved config_load performance. (Andrei)
+    - added format attribute to math function. (Monte)
+    - added html_select_time custom function. (Andrei)
+    - fixed minor PHP warning when attempting to unset an unset variable
+      (Monte)
+    - added count_characters, count_words, count_sentences, count_paragraphs
+      modifiers (Monte)
+
+Version 1.3.1pl1
+--------------
+    - bug fix, recovered missing _syntax_error function (Monte)
+
+Version 1.3.1
+-------------
+    - document first, last, index_prev, index_next (Monte)
+    - added 'first' and 'last' section properties. (Andrei)
+    - split out compiling code to separate class for faster template execution
+      time (Monte)
+    - fixed a couple of minor PHP warnings (Monte)
+    - added and documented unregister_modifier() and unregister_function() API
+      calls. (Monte)
+    - added and documented 'fetch' and 'math' functions. (Monte)
+    - added ability to index looped variables by section properties, e.g.
+      $foo.index_prev/bar. (Andrei)
+    - added index_prev and index_next section properties. (Andrei)
+    - fixed issue with php executing in literal blocks. (Monte)
+
+Version 1.3.0
+-------------
+    - moved license from GPL to LGPL (Monte)
+    - implemented workaround for PHP "feature" that eats carriage returns
+      if the PHP tag is at the end of the line. (Andrei)
+    - removed $allow_php, added $php_handling logic (Monte)
+    - added file locking to prevent reader/writer problem. (Andrei)
+    - made Smarty catch unimplemented modifiers and custom functions and output
+      error messages during compilation instead of failing during run time.
+      (Andrei)
+    - removed short-tags at the top of the smarty scripts (Monte)
+    - added register_function() and register_modifier() API calls to make
+      registering stuff easier. (Andrei)
+    - added template results caching capability. (Monte, Andrei)
+    - added optional 'options' attribute to html_options custom function
+      that allows passing associative arrays for values/output. (Andrei)
+    - modifier arguments can now contain '|' and ':' characters inside quoted
+      strings. (Andrei)
+
+Version 1.2.2
+-------------
+    - fixed bug that would not respect nested template directories and would
+      put all compiled files into top-level one. (Andrei)
+    - fixed bug using $PHP_VERSION instead of environment var PHP_VERSION.
+      (Monte)
+    - a couple small warning fixes. (Monte)
+
+Version 1.2.1
+-------------
+    - added $compile_dir, removed $compile_dir_ext, simplified usage. (Monte)
+    - added tips & tricks chapter to documentation. (Monte)
+    - misc documentation updates. (Monte)
+
+Version 1.2.0
+-------------
+    - updated documentation (Monte)
+    - added file and line number information to syntax error messages. (Andrei)
+    - added ability to index template vars by a key. (Andrei)
+
+Version 1.1.0
+-------------
+    - misc documentation changes, official stable release
+
+Version 1.0b
+------------
+    - fixed the bug that prevented using non-array values for 'loop' attribute.
+      (Andrei)
+    - many misc documentation changes & additions (Monte)
+
+Version 1.0a
+------------
+    - fixed bug that caused templates to recompile every time (Monte)
+
+Version 1.0
+------------
+    - initial release
+
+/* vim: set et tw=64 ft=changelog: */
Index: /tags/2.0.2/include/smarty/README
===================================================================
--- /tags/2.0.2/include/smarty/README	(revision 3278)
+++ /tags/2.0.2/include/smarty/README	(revision 3278)
@@ -0,0 +1,86 @@
+
+NAME:
+
+    Smarty - the PHP compiling template engine
+
+VERSION: 2.6.22
+
+AUTHORS:
+    
+    Monte Ohrt <monte at ohrt dot com>
+    Andrei Zmievski <andrei@php.net>
+
+MAILING LISTS:
+
+    We have a few mailing lists. "discussion" for you to share your ideas or ask
+	questions, "developers" for those interested in the development efforts of Smarty,
+	and "svn" for those that would like to track the updates made in the svn
+	repository.
+
+    send a blank e-mail message to:
+      smarty-discussion-subscribe@googlecode.com(subscribe to the general discussion list)
+      smarty-discussion-unsubscribe@googlecode.com (unsubscribe from the general discussion list)
+      smarty-discussion-digest-subscribe@googlecode.com (subscribe to digest)
+      smarty-discussion-digest-unsubscribe@googlecode.com (unsubscribe from digest)
+      smarty-developers-subscribe@googlecode.com (subscribe to the dev list)
+      smarty-developers-unsubscribe@googlecode.com (unsubscribe from the dev list)
+      smarty-svn-subscribe@googlecode.com (subscribe to the svn list)
+      smarty-svn-unsubscribe@googlecode.com (unsubscribe from the svn list)
+
+    You can also browse the mailing list archives at
+    http://groups.google.com/group/smarty-discussion
+    http://groups.google.com/group/smarty-developers
+
+    and the OLD list archives at
+    http://marc.theaimsgroup.com/?l=smarty&r=1&w=2
+
+SYNOPSIS:
+
+    require("Smarty.class.php");
+
+    $smarty = new Smarty;
+
+    $smarty->assign("Title","My Homepage");
+    $smarty->assign("Names",array("John","Gary","Gregg","James"));
+
+    $smarty->display("index.tpl");
+
+
+DESCRIPTION:
+
+    What is Smarty?
+
+    Smarty is a template engine for PHP. Many other template engines for PHP
+    provide basic variable substitution and dynamic block functionality.
+    Smarty takes a step further to be a "smart" template engine, adding
+    features such as configuration files, template functions, and variable
+    modifiers, and making all of this functionality as easy as possible to
+    use for both programmers and template designers. Smarty also converts
+    the templates into PHP scripts, eliminating the need to parse the
+    templates on every invocation. This makes Smarty extremely scalable and
+    manageable for large application needs.
+
+    Some of Smarty's features:
+
+    * it is extremely fast
+    * no template parsing overhead, only compiles once.
+	* it is smart about recompiling only the template files that have
+	  changed.
+    * the template language is remarkably extensible via the plugin
+      architecture.
+    * configurable template delimiter tag syntax, so you can use
+      {}, {{}}, <!--{}-->, or whatever you like.
+    * built-in caching of template output.
+    * arbitrary template sources (filesystem, databases, etc.)
+    * template if/elseif/else/endif constructs are passed to the PHP parser,
+      so the if syntax can be as simple or as complex as you like.
+    * unlimited nesting of sections, conditionals, etc. allowed
+    * it is possible to embed PHP code right in your template files,
+      although not recommended and doubtfully needed since the engine
+      is so customizable.
+    * and many more.
+
+COPYRIGHT:
+    Copyright (c) 2001-2005 New Digital Group, Inc. All rights reserved.
+    This software is released under the GNU Lesser General Public License.
+    Please read the disclaimer at the top of the Smarty.class.php file.
Index: /tags/2.0.2/include/smarty/libs/Config_File.class.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/Config_File.class.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/Config_File.class.php	(revision 3278)
@@ -0,0 +1,393 @@
+<?php
+
+/**
+ * Config_File class.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For questions, help, comments, discussion, etc., please join the
+ * Smarty mailing list. Send a blank e-mail to
+ * smarty-discussion-subscribe@googlegroups.com 
+ *
+ * @link http://www.smarty.net/
+ * @version 2.6.22
+ * @copyright Copyright: 2001-2005 New Digital Group, Inc.
+ * @author Andrei Zmievski <andrei@php.net>
+ * @access public
+ * @package Smarty
+ */
+
+/* $Id: Config_File.class.php 2786 2008-09-18 21:04:38Z Uwe.Tews $ */
+
+/**
+ * Config file reading class
+ * @package Smarty
+ */
+class Config_File {
+    /**#@+
+     * Options
+     * @var boolean
+     */
+    /**
+     * Controls whether variables with the same name overwrite each other.
+     */
+    var $overwrite        =    true;
+
+    /**
+     * Controls whether config values of on/true/yes and off/false/no get
+     * converted to boolean values automatically.
+     */
+    var $booleanize        =    true;
+
+    /**
+     * Controls whether hidden config sections/vars are read from the file.
+     */
+    var $read_hidden     =    true;
+
+    /**
+     * Controls whether or not to fix mac or dos formatted newlines.
+     * If set to true, \r or \r\n will be changed to \n.
+     */
+    var $fix_newlines =    true;
+    /**#@-*/
+
+    /** @access private */
+    var $_config_path    = "";
+    var $_config_data    = array();
+    /**#@-*/
+
+    /**
+     * Constructs a new config file class.
+     *
+     * @param string $config_path (optional) path to the config files
+     */
+    function Config_File($config_path = NULL)
+    {
+        if (isset($config_path))
+            $this->set_path($config_path);
+    }
+
+
+    /**
+     * Set the path where configuration files can be found.
+     *
+     * @param string $config_path path to the config files
+     */
+    function set_path($config_path)
+    {
+        if (!empty($config_path)) {
+            if (!is_string($config_path) || !file_exists($config_path) || !is_dir($config_path)) {
+                $this->_trigger_error_msg("Bad config file path '$config_path'");
+                return;
+            }
+            if(substr($config_path, -1) != DIRECTORY_SEPARATOR) {
+                $config_path .= DIRECTORY_SEPARATOR;
+            }
+
+            $this->_config_path = $config_path;
+        }
+    }
+
+
+    /**
+     * Retrieves config info based on the file, section, and variable name.
+     *
+     * @param string $file_name config file to get info for
+     * @param string $section_name (optional) section to get info for
+     * @param string $var_name (optional) variable to get info for
+     * @return string|array a value or array of values
+     */
+    function get($file_name, $section_name = NULL, $var_name = NULL)
+    {
+        if (empty($file_name)) {
+            $this->_trigger_error_msg('Empty config file name');
+            return;
+        } else {
+            $file_name = $this->_config_path . $file_name;
+            if (!isset($this->_config_data[$file_name]))
+                $this->load_file($file_name, false);
+        }
+
+        if (!empty($var_name)) {
+            if (empty($section_name)) {
+                return $this->_config_data[$file_name]["vars"][$var_name];
+            } else {
+                if(isset($this->_config_data[$file_name]["sections"][$section_name]["vars"][$var_name]))
+                    return $this->_config_data[$file_name]["sections"][$section_name]["vars"][$var_name];
+                else
+                    return array();
+            }
+        } else {
+            if (empty($section_name)) {
+                return (array)$this->_config_data[$file_name]["vars"];
+            } else {
+                if(isset($this->_config_data[$file_name]["sections"][$section_name]["vars"]))
+                    return (array)$this->_config_data[$file_name]["sections"][$section_name]["vars"];
+                else
+                    return array();
+            }
+        }
+    }
+
+
+    /**
+     * Retrieves config info based on the key.
+     *
+     * @param $file_name string config key (filename/section/var)
+     * @return string|array same as get()
+     * @uses get() retrieves information from config file and returns it
+     */
+    function &get_key($config_key)
+    {
+        list($file_name, $section_name, $var_name) = explode('/', $config_key, 3);
+        $result = &$this->get($file_name, $section_name, $var_name);
+        return $result;
+    }
+
+    /**
+     * Get all loaded config file names.
+     *
+     * @return array an array of loaded config file names
+     */
+    function get_file_names()
+    {
+        return array_keys($this->_config_data);
+    }
+
+
+    /**
+     * Get all section names from a loaded file.
+     *
+     * @param string $file_name config file to get section names from
+     * @return array an array of section names from the specified file
+     */
+    function get_section_names($file_name)
+    {
+        $file_name = $this->_config_path . $file_name;
+        if (!isset($this->_config_data[$file_name])) {
+            $this->_trigger_error_msg("Unknown config file '$file_name'");
+            return;
+        }
+
+        return array_keys($this->_config_data[$file_name]["sections"]);
+    }
+
+
+    /**
+     * Get all global or section variable names.
+     *
+     * @param string $file_name config file to get info for
+     * @param string $section_name (optional) section to get info for
+     * @return array an array of variables names from the specified file/section
+     */
+    function get_var_names($file_name, $section = NULL)
+    {
+        if (empty($file_name)) {
+            $this->_trigger_error_msg('Empty config file name');
+            return;
+        } else if (!isset($this->_config_data[$file_name])) {
+            $this->_trigger_error_msg("Unknown config file '$file_name'");
+            return;
+        }
+
+        if (empty($section))
+            return array_keys($this->_config_data[$file_name]["vars"]);
+        else
+            return array_keys($this->_config_data[$file_name]["sections"][$section]["vars"]);
+    }
+
+
+    /**
+     * Clear loaded config data for a certain file or all files.
+     *
+     * @param string $file_name file to clear config data for
+     */
+    function clear($file_name = NULL)
+    {
+        if ($file_name === NULL)
+            $this->_config_data = array();
+        else if (isset($this->_config_data[$file_name]))
+            $this->_config_data[$file_name] = array();
+    }
+
+
+    /**
+     * Load a configuration file manually.
+     *
+     * @param string $file_name file name to load
+     * @param boolean $prepend_path whether current config path should be
+     *                              prepended to the filename
+     */
+    function load_file($file_name, $prepend_path = true)
+    {
+        if ($prepend_path && $this->_config_path != "")
+            $config_file = $this->_config_path . $file_name;
+        else
+            $config_file = $file_name;
+
+        ini_set('track_errors', true);
+        $fp = @fopen($config_file, "r");
+        if (!is_resource($fp)) {
+            $this->_trigger_error_msg("Could not open config file '$config_file'");
+            return false;
+        }
+
+        $contents = ($size = filesize($config_file)) ? fread($fp, $size) : '';
+        fclose($fp);
+
+        $this->_config_data[$config_file] = $this->parse_contents($contents);
+        return true;
+    }
+
+    /**
+     * Store the contents of a file manually.
+     *
+     * @param string $config_file file name of the related contents
+     * @param string $contents the file-contents to parse
+     */
+    function set_file_contents($config_file, $contents)
+    {
+        $this->_config_data[$config_file] = $this->parse_contents($contents);
+        return true;
+    }
+
+    /**
+     * parse the source of a configuration file manually.
+     *
+     * @param string $contents the file-contents to parse
+     */
+    function parse_contents($contents)
+    {
+        if($this->fix_newlines) {
+            // fix mac/dos formatted newlines
+            $contents = preg_replace('!\r\n?!', "\n", $contents);
+        }
+
+        $config_data = array();
+        $config_data['sections'] = array();
+        $config_data['vars'] = array();
+
+        /* reference to fill with data */
+        $vars =& $config_data['vars'];
+
+        /* parse file line by line */
+        preg_match_all('!^.*\r?\n?!m', $contents, $match);
+        $lines = $match[0];
+        for ($i=0, $count=count($lines); $i<$count; $i++) {
+            $line = $lines[$i];
+            if (empty($line)) continue;
+
+            if ( substr($line, 0, 1) == '[' && preg_match('!^\[(.*?)\]!', $line, $match) ) {
+                /* section found */
+                if (substr($match[1], 0, 1) == '.') {
+                    /* hidden section */
+                    if ($this->read_hidden) {
+                        $section_name = substr($match[1], 1);
+                    } else {
+                        /* break reference to $vars to ignore hidden section */
+                        unset($vars);
+                        $vars = array();
+                        continue;
+                    }
+                } else {                    
+                    $section_name = $match[1];
+                }
+                if (!isset($config_data['sections'][$section_name]))
+                    $config_data['sections'][$section_name] = array('vars' => array());
+                $vars =& $config_data['sections'][$section_name]['vars'];
+                continue;
+            }
+
+            if (preg_match('/^\s*(\.?\w+)\s*=\s*(.*)/s', $line, $match)) {
+                /* variable found */
+                $var_name = rtrim($match[1]);
+                if (strpos($match[2], '"""') === 0) {
+                    /* handle multiline-value */
+                    $lines[$i] = substr($match[2], 3);
+                    $var_value = '';
+                    while ($i<$count) {
+                        if (($pos = strpos($lines[$i], '"""')) === false) {
+                            $var_value .= $lines[$i++];
+                        } else {
+                            /* end of multiline-value */
+                            $var_value .= substr($lines[$i], 0, $pos);
+                            break;
+                        }
+                    }
+                    $booleanize = false;
+
+                } else {
+                    /* handle simple value */
+                    $var_value = preg_replace('/^([\'"])(.*)\1$/', '\2', rtrim($match[2]));
+                    $booleanize = $this->booleanize;
+
+                }
+                $this->_set_config_var($vars, $var_name, $var_value, $booleanize);
+            }
+            /* else unparsable line / means it is a comment / means ignore it */
+        }
+        return $config_data;
+    }
+
+    /**#@+ @access private */
+    /**
+     * @param array &$container
+     * @param string $var_name
+     * @param mixed $var_value
+     * @param boolean $booleanize determines whether $var_value is converted to
+     *                            to true/false
+     */
+    function _set_config_var(&$container, $var_name, $var_value, $booleanize)
+    {
+        if (substr($var_name, 0, 1) == '.') {
+            if (!$this->read_hidden)
+                return;
+            else
+                $var_name = substr($var_name, 1);
+        }
+
+        if (!preg_match("/^[a-zA-Z_]\w*$/", $var_name)) {
+            $this->_trigger_error_msg("Bad variable name '$var_name'");
+            return;
+        }
+
+        if ($booleanize) {
+            if (preg_match("/^(on|true|yes)$/i", $var_value))
+                $var_value = true;
+            else if (preg_match("/^(off|false|no)$/i", $var_value))
+                $var_value = false;
+        }
+
+        if (!isset($container[$var_name]) || $this->overwrite)
+            $container[$var_name] = $var_value;
+        else {
+            settype($container[$var_name], 'array');
+            $container[$var_name][] = $var_value;
+        }
+    }
+
+    /**
+     * @uses trigger_error() creates a PHP warning/error
+     * @param string $error_msg
+     * @param integer $error_type one of
+     */
+    function _trigger_error_msg($error_msg, $error_type = E_USER_WARNING)
+    {
+        trigger_error("Config_File error: $error_msg", $error_type);
+    }
+    /**#@-*/
+}
+
+?>
Index: /tags/2.0.2/include/smarty/libs/Smarty.class.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/Smarty.class.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/Smarty.class.php	(revision 3278)
@@ -0,0 +1,1966 @@
+<?php
+
+/**
+ * Project:     Smarty: the PHP compiling template engine
+ * File:        Smarty.class.php
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For questions, help, comments, discussion, etc., please join the
+ * Smarty mailing list. Send a blank e-mail to
+ * smarty-discussion-subscribe@googlegroups.com
+ *
+ * @link http://www.smarty.net/
+ * @copyright 2001-2005 New Digital Group, Inc.
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @author Andrei Zmievski <andrei@php.net>
+ * @package Smarty
+ * @version 2.6.22
+ */
+
+/* $Id: Smarty.class.php 2785 2008-09-18 21:04:12Z Uwe.Tews $ */
+
+/**
+ * DIR_SEP isn't used anymore, but third party apps might
+ */
+if(!defined('DIR_SEP')) {
+    define('DIR_SEP', DIRECTORY_SEPARATOR);
+}
+
+/**
+ * set SMARTY_DIR to absolute path to Smarty library files.
+ * if not defined, include_path will be used. Sets SMARTY_DIR only if user
+ * application has not already defined it.
+ */
+
+if (!defined('SMARTY_DIR')) {
+    define('SMARTY_DIR', dirname(__FILE__) . DIRECTORY_SEPARATOR);
+}
+
+if (!defined('SMARTY_CORE_DIR')) {
+    define('SMARTY_CORE_DIR', SMARTY_DIR . 'internals' . DIRECTORY_SEPARATOR);
+}
+
+define('SMARTY_PHP_PASSTHRU',   0);
+define('SMARTY_PHP_QUOTE',      1);
+define('SMARTY_PHP_REMOVE',     2);
+define('SMARTY_PHP_ALLOW',      3);
+
+/**
+ * @package Smarty
+ */
+class Smarty
+{
+    /**#@+
+     * Smarty Configuration Section
+     */
+
+    /**
+     * The name of the directory where templates are located.
+     *
+     * @var string
+     */
+    var $template_dir    =  'templates';
+
+    /**
+     * The directory where compiled templates are located.
+     *
+     * @var string
+     */
+    var $compile_dir     =  'templates_c';
+
+    /**
+     * The directory where config files are located.
+     *
+     * @var string
+     */
+    var $config_dir      =  'configs';
+
+    /**
+     * An array of directories searched for plugins.
+     *
+     * @var array
+     */
+    var $plugins_dir     =  array('plugins');
+
+    /**
+     * If debugging is enabled, a debug console window will display
+     * when the page loads (make sure your browser allows unrequested
+     * popup windows)
+     *
+     * @var boolean
+     */
+    var $debugging       =  false;
+
+    /**
+     * When set, smarty does uses this value as error_reporting-level.
+     *
+     * @var boolean
+     */
+    var $error_reporting  =  null;
+
+    /**
+     * This is the path to the debug console template. If not set,
+     * the default one will be used.
+     *
+     * @var string
+     */
+    var $debug_tpl       =  '';
+
+    /**
+     * This determines if debugging is enable-able from the browser.
+     * <ul>
+     *  <li>NONE => no debugging control allowed</li>
+     *  <li>URL => enable debugging when SMARTY_DEBUG is found in the URL.</li>
+     * </ul>
+     * @link http://www.foo.dom/index.php?SMARTY_DEBUG
+     * @var string
+     */
+    var $debugging_ctrl  =  'NONE';
+
+    /**
+     * This tells Smarty whether to check for recompiling or not. Recompiling
+     * does not need to happen unless a template or config file is changed.
+     * Typically you enable this during development, and disable for
+     * production.
+     *
+     * @var boolean
+     */
+    var $compile_check   =  true;
+
+    /**
+     * This forces templates to compile every time. Useful for development
+     * or debugging.
+     *
+     * @var boolean
+     */
+    var $force_compile   =  false;
+
+    /**
+     * This enables template caching.
+     * <ul>
+     *  <li>0 = no caching</li>
+     *  <li>1 = use class cache_lifetime value</li>
+     *  <li>2 = use cache_lifetime in cache file</li>
+     * </ul>
+     * @var integer
+     */
+    var $caching         =  0;
+
+    /**
+     * The name of the directory for cache files.
+     *
+     * @var string
+     */
+    var $cache_dir       =  'cache';
+
+    /**
+     * This is the number of seconds cached content will persist.
+     * <ul>
+     *  <li>0 = always regenerate cache</li>
+     *  <li>-1 = never expires</li>
+     * </ul>
+     *
+     * @var integer
+     */
+    var $cache_lifetime  =  3600;
+
+    /**
+     * Only used when $caching is enabled. If true, then If-Modified-Since headers
+     * are respected with cached content, and appropriate HTTP headers are sent.
+     * This way repeated hits to a cached page do not send the entire page to the
+     * client every time.
+     *
+     * @var boolean
+     */
+    var $cache_modified_check = false;
+
+    /**
+     * This determines how Smarty handles "<?php ... ?>" tags in templates.
+     * possible values:
+     * <ul>
+     *  <li>SMARTY_PHP_PASSTHRU -> print tags as plain text</li>
+     *  <li>SMARTY_PHP_QUOTE    -> escape tags as entities</li>
+     *  <li>SMARTY_PHP_REMOVE   -> remove php tags</li>
+     *  <li>SMARTY_PHP_ALLOW    -> execute php tags</li>
+     * </ul>
+     *
+     * @var integer
+     */
+    var $php_handling    =  SMARTY_PHP_PASSTHRU;
+
+    /**
+     * This enables template security. When enabled, many things are restricted
+     * in the templates that normally would go unchecked. This is useful when
+     * untrusted parties are editing templates and you want a reasonable level
+     * of security. (no direct execution of PHP in templates for example)
+     *
+     * @var boolean
+     */
+    var $security       =   false;
+
+    /**
+     * This is the list of template directories that are considered secure. This
+     * is used only if {@link $security} is enabled. One directory per array
+     * element.  {@link $template_dir} is in this list implicitly.
+     *
+     * @var array
+     */
+    var $secure_dir     =   array();
+
+    /**
+     * These are the security settings for Smarty. They are used only when
+     * {@link $security} is enabled.
+     *
+     * @var array
+     */
+    var $security_settings  = array(
+                                    'PHP_HANDLING'    => false,
+                                    'IF_FUNCS'        => array('array', 'list',
+                                                               'isset', 'empty',
+                                                               'count', 'sizeof',
+                                                               'in_array', 'is_array',
+                                                               'true', 'false', 'null'),
+                                    'INCLUDE_ANY'     => false,
+                                    'PHP_TAGS'        => false,
+                                    'MODIFIER_FUNCS'  => array('count'),
+                                    'ALLOW_CONSTANTS'  => false
+                                   );
+
+    /**
+     * This is an array of directories where trusted php scripts reside.
+     * {@link $security} is disabled during their inclusion/execution.
+     *
+     * @var array
+     */
+    var $trusted_dir        = array();
+
+    /**
+     * The left delimiter used for the template tags.
+     *
+     * @var string
+     */
+    var $left_delimiter  =  '{';
+
+    /**
+     * The right delimiter used for the template tags.
+     *
+     * @var string
+     */
+    var $right_delimiter =  '}';
+
+    /**
+     * The order in which request variables are registered, similar to
+     * variables_order in php.ini E = Environment, G = GET, P = POST,
+     * C = Cookies, S = Server
+     *
+     * @var string
+     */
+    var $request_vars_order    = 'EGPCS';
+
+    /**
+     * Indicates wether $HTTP_*_VARS[] (request_use_auto_globals=false)
+     * are uses as request-vars or $_*[]-vars. note: if
+     * request_use_auto_globals is true, then $request_vars_order has
+     * no effect, but the php-ini-value "gpc_order"
+     *
+     * @var boolean
+     */
+    var $request_use_auto_globals      = true;
+
+    /**
+     * Set this if you want different sets of compiled files for the same
+     * templates. This is useful for things like different languages.
+     * Instead of creating separate sets of templates per language, you
+     * set different compile_ids like 'en' and 'de'.
+     *
+     * @var string
+     */
+    var $compile_id            = null;
+
+    /**
+     * This tells Smarty whether or not to use sub dirs in the cache/ and
+     * templates_c/ directories. sub directories better organized, but
+     * may not work well with PHP safe mode enabled.
+     *
+     * @var boolean
+     *
+     */
+    var $use_sub_dirs          = false;
+
+    /**
+     * This is a list of the modifiers to apply to all template variables.
+     * Put each modifier in a separate array element in the order you want
+     * them applied. example: <code>array('escape:"htmlall"');</code>
+     *
+     * @var array
+     */
+    var $default_modifiers        = array();
+
+    /**
+     * This is the resource type to be used when not specified
+     * at the beginning of the resource path. examples:
+     * $smarty->display('file:index.tpl');
+     * $smarty->display('db:index.tpl');
+     * $smarty->display('index.tpl'); // will use default resource type
+     * {include file="file:index.tpl"}
+     * {include file="db:index.tpl"}
+     * {include file="index.tpl"} {* will use default resource type *}
+     *
+     * @var array
+     */
+    var $default_resource_type    = 'file';
+
+    /**
+     * The function used for cache file handling. If not set, built-in caching is used.
+     *
+     * @var null|string function name
+     */
+    var $cache_handler_func   = null;
+
+    /**
+     * This indicates which filters are automatically loaded into Smarty.
+     *
+     * @var array array of filter names
+     */
+    var $autoload_filters = array();
+
+    /**#@+
+     * @var boolean
+     */
+    /**
+     * This tells if config file vars of the same name overwrite each other or not.
+     * if disabled, same name variables are accumulated in an array.
+     */
+    var $config_overwrite = true;
+
+    /**
+     * This tells whether or not to automatically booleanize config file variables.
+     * If enabled, then the strings "on", "true", and "yes" are treated as boolean
+     * true, and "off", "false" and "no" are treated as boolean false.
+     */
+    var $config_booleanize = true;
+
+    /**
+     * This tells whether hidden sections [.foobar] are readable from the
+     * tempalates or not. Normally you would never allow this since that is
+     * the point behind hidden sections: the application can access them, but
+     * the templates cannot.
+     */
+    var $config_read_hidden = false;
+
+    /**
+     * This tells whether or not automatically fix newlines in config files.
+     * It basically converts \r (mac) or \r\n (dos) to \n
+     */
+    var $config_fix_newlines = true;
+    /**#@-*/
+
+    /**
+     * If a template cannot be found, this PHP function will be executed.
+     * Useful for creating templates on-the-fly or other special action.
+     *
+     * @var string function name
+     */
+    var $default_template_handler_func = '';
+
+    /**
+     * The file that contains the compiler class. This can a full
+     * pathname, or relative to the php_include path.
+     *
+     * @var string
+     */
+    var $compiler_file        =    'Smarty_Compiler.class.php';
+
+    /**
+     * The class used for compiling templates.
+     *
+     * @var string
+     */
+    var $compiler_class        =   'Smarty_Compiler';
+
+    /**
+     * The class used to load config vars.
+     *
+     * @var string
+     */
+    var $config_class          =   'Config_File';
+
+/**#@+
+ * END Smarty Configuration Section
+ * There should be no need to touch anything below this line.
+ * @access private
+ */
+    /**
+     * where assigned template vars are kept
+     *
+     * @var array
+     */
+    var $_tpl_vars             = array();
+
+    /**
+     * stores run-time $smarty.* vars
+     *
+     * @var null|array
+     */
+    var $_smarty_vars          = null;
+
+    /**
+     * keeps track of sections
+     *
+     * @var array
+     */
+    var $_sections             = array();
+
+    /**
+     * keeps track of foreach blocks
+     *
+     * @var array
+     */
+    var $_foreach              = array();
+
+    /**
+     * keeps track of tag hierarchy
+     *
+     * @var array
+     */
+    var $_tag_stack            = array();
+
+    /**
+     * configuration object
+     *
+     * @var Config_file
+     */
+    var $_conf_obj             = null;
+
+    /**
+     * loaded configuration settings
+     *
+     * @var array
+     */
+    var $_config               = array(array('vars'  => array(), 'files' => array()));
+
+    /**
+     * md5 checksum of the string 'Smarty'
+     *
+     * @var string
+     */
+    var $_smarty_md5           = 'f8d698aea36fcbead2b9d5359ffca76f';
+
+    /**
+     * Smarty version number
+     *
+     * @var string
+     */
+    var $_version              = '2.6.22';
+
+    /**
+     * current template inclusion depth
+     *
+     * @var integer
+     */
+    var $_inclusion_depth      = 0;
+
+    /**
+     * for different compiled templates
+     *
+     * @var string
+     */
+    var $_compile_id           = null;
+
+    /**
+     * text in URL to enable debug mode
+     *
+     * @var string
+     */
+    var $_smarty_debug_id      = 'SMARTY_DEBUG';
+
+    /**
+     * debugging information for debug console
+     *
+     * @var array
+     */
+    var $_smarty_debug_info    = array();
+
+    /**
+     * info that makes up a cache file
+     *
+     * @var array
+     */
+    var $_cache_info           = array();
+
+    /**
+     * default file permissions
+     *
+     * @var integer
+     */
+    var $_file_perms           = 0644;
+
+    /**
+     * default dir permissions
+     *
+     * @var integer
+     */
+    var $_dir_perms               = 0771;
+
+    /**
+     * registered objects
+     *
+     * @var array
+     */
+    var $_reg_objects           = array();
+
+    /**
+     * table keeping track of plugins
+     *
+     * @var array
+     */
+    var $_plugins              = array(
+                                       'modifier'      => array(),
+                                       'function'      => array(),
+                                       'block'         => array(),
+                                       'compiler'      => array(),
+                                       'prefilter'     => array(),
+                                       'postfilter'    => array(),
+                                       'outputfilter'  => array(),
+                                       'resource'      => array(),
+                                       'insert'        => array());
+
+
+    /**
+     * cache serials
+     *
+     * @var array
+     */
+    var $_cache_serials = array();
+
+    /**
+     * name of optional cache include file
+     *
+     * @var string
+     */
+    var $_cache_include = null;
+
+    /**
+     * indicate if the current code is used in a compiled
+     * include
+     *
+     * @var string
+     */
+    var $_cache_including = false;
+
+    /**#@-*/
+    /**
+     * The class constructor.
+     */
+    function Smarty()
+    {
+      $this->assign('SCRIPT_NAME', isset($_SERVER['SCRIPT_NAME']) ? $_SERVER['SCRIPT_NAME']
+                    : @$GLOBALS['HTTP_SERVER_VARS']['SCRIPT_NAME']);
+    }
+
+    /**
+     * assigns values to template variables
+     *
+     * @param array|string $tpl_var the template variable name(s)
+     * @param mixed $value the value to assign
+     */
+    function assign($tpl_var, $value = null)
+    {
+        if (is_array($tpl_var)){
+            foreach ($tpl_var as $key => $val) {
+                if ($key != '') {
+                    $this->_tpl_vars[$key] = $val;
+                }
+            }
+        } else {
+            if ($tpl_var != '')
+                $this->_tpl_vars[$tpl_var] = $value;
+        }
+    }
+
+    /**
+     * assigns values to template variables by reference
+     *
+     * @param string $tpl_var the template variable name
+     * @param mixed $value the referenced value to assign
+     */
+    function assign_by_ref($tpl_var, &$value)
+    {
+        if ($tpl_var != '')
+            $this->_tpl_vars[$tpl_var] = &$value;
+    }
+
+    /**
+     * appends values to template variables
+     *
+     * @param array|string $tpl_var the template variable name(s)
+     * @param mixed $value the value to append
+     */
+    function append($tpl_var, $value=null, $merge=false)
+    {
+        if (is_array($tpl_var)) {
+            // $tpl_var is an array, ignore $value
+            foreach ($tpl_var as $_key => $_val) {
+                if ($_key != '') {
+                    if(!@is_array($this->_tpl_vars[$_key])) {
+                        settype($this->_tpl_vars[$_key],'array');
+                    }
+                    if($merge && is_array($_val)) {
+                        foreach($_val as $_mkey => $_mval) {
+                            $this->_tpl_vars[$_key][$_mkey] = $_mval;
+                        }
+                    } else {
+                        $this->_tpl_vars[$_key][] = $_val;
+                    }
+                }
+            }
+        } else {
+            if ($tpl_var != '' && isset($value)) {
+                if(!@is_array($this->_tpl_vars[$tpl_var])) {
+                    settype($this->_tpl_vars[$tpl_var],'array');
+                }
+                if($merge && is_array($value)) {
+                    foreach($value as $_mkey => $_mval) {
+                        $this->_tpl_vars[$tpl_var][$_mkey] = $_mval;
+                    }
+                } else {
+                    $this->_tpl_vars[$tpl_var][] = $value;
+                }
+            }
+        }
+    }
+
+    /**
+     * appends values to template variables by reference
+     *
+     * @param string $tpl_var the template variable name
+     * @param mixed $value the referenced value to append
+     */
+    function append_by_ref($tpl_var, &$value, $merge=false)
+    {
+        if ($tpl_var != '' && isset($value)) {
+            if(!@is_array($this->_tpl_vars[$tpl_var])) {
+             settype($this->_tpl_vars[$tpl_var],'array');
+            }
+            if ($merge && is_array($value)) {
+                foreach($value as $_key => $_val) {
+                    $this->_tpl_vars[$tpl_var][$_key] = &$value[$_key];
+                }
+            } else {
+                $this->_tpl_vars[$tpl_var][] = &$value;
+            }
+        }
+    }
+
+
+    /**
+     * clear the given assigned template variable.
+     *
+     * @param string $tpl_var the template variable to clear
+     */
+    function clear_assign($tpl_var)
+    {
+        if (is_array($tpl_var))
+            foreach ($tpl_var as $curr_var)
+                unset($this->_tpl_vars[$curr_var]);
+        else
+            unset($this->_tpl_vars[$tpl_var]);
+    }
+
+
+    /**
+     * Registers custom function to be used in templates
+     *
+     * @param string $function the name of the template function
+     * @param string $function_impl the name of the PHP function to register
+     */
+    function register_function($function, $function_impl, $cacheable=true, $cache_attrs=null)
+    {
+        $this->_plugins['function'][$function] =
+            array($function_impl, null, null, false, $cacheable, $cache_attrs);
+
+    }
+
+    /**
+     * Unregisters custom function
+     *
+     * @param string $function name of template function
+     */
+    function unregister_function($function)
+    {
+        unset($this->_plugins['function'][$function]);
+    }
+
+    /**
+     * Registers object to be used in templates
+     *
+     * @param string $object name of template object
+     * @param object &$object_impl the referenced PHP object to register
+     * @param null|array $allowed list of allowed methods (empty = all)
+     * @param boolean $smarty_args smarty argument format, else traditional
+     * @param null|array $block_functs list of methods that are block format
+     */
+    function register_object($object, &$object_impl, $allowed = array(), $smarty_args = true, $block_methods = array())
+    {
+        settype($allowed, 'array');
+        settype($smarty_args, 'boolean');
+        $this->_reg_objects[$object] =
+            array(&$object_impl, $allowed, $smarty_args, $block_methods);
+    }
+
+    /**
+     * Unregisters object
+     *
+     * @param string $object name of template object
+     */
+    function unregister_object($object)
+    {
+        unset($this->_reg_objects[$object]);
+    }
+
+
+    /**
+     * Registers block function to be used in templates
+     *
+     * @param string $block name of template block
+     * @param string $block_impl PHP function to register
+     */
+    function register_block($block, $block_impl, $cacheable=true, $cache_attrs=null)
+    {
+        $this->_plugins['block'][$block] =
+            array($block_impl, null, null, false, $cacheable, $cache_attrs);
+    }
+
+    /**
+     * Unregisters block function
+     *
+     * @param string $block name of template function
+     */
+    function unregister_block($block)
+    {
+        unset($this->_plugins['block'][$block]);
+    }
+
+    /**
+     * Registers compiler function
+     *
+     * @param string $function name of template function
+     * @param string $function_impl name of PHP function to register
+     */
+    function register_compiler_function($function, $function_impl, $cacheable=true)
+    {
+        $this->_plugins['compiler'][$function] =
+            array($function_impl, null, null, false, $cacheable);
+    }
+
+    /**
+     * Unregisters compiler function
+     *
+     * @param string $function name of template function
+     */
+    function unregister_compiler_function($function)
+    {
+        unset($this->_plugins['compiler'][$function]);
+    }
+
+    /**
+     * Registers modifier to be used in templates
+     *
+     * @param string $modifier name of template modifier
+     * @param string $modifier_impl name of PHP function to register
+     */
+    function register_modifier($modifier, $modifier_impl)
+    {
+        $this->_plugins['modifier'][$modifier] =
+            array($modifier_impl, null, null, false);
+    }
+
+    /**
+     * Unregisters modifier
+     *
+     * @param string $modifier name of template modifier
+     */
+    function unregister_modifier($modifier)
+    {
+        unset($this->_plugins['modifier'][$modifier]);
+    }
+
+    /**
+     * Registers a resource to fetch a template
+     *
+     * @param string $type name of resource
+     * @param array $functions array of functions to handle resource
+     */
+    function register_resource($type, $functions)
+    {
+        if (count($functions)==4) {
+            $this->_plugins['resource'][$type] =
+                array($functions, false);
+
+        } elseif (count($functions)==5) {
+            $this->_plugins['resource'][$type] =
+                array(array(array(&$functions[0], $functions[1])
+                            ,array(&$functions[0], $functions[2])
+                            ,array(&$functions[0], $functions[3])
+                            ,array(&$functions[0], $functions[4]))
+                      ,false);
+
+        } else {
+            $this->trigger_error("malformed function-list for '$type' in register_resource");
+
+        }
+    }
+
+    /**
+     * Unregisters a resource
+     *
+     * @param string $type name of resource
+     */
+    function unregister_resource($type)
+    {
+        unset($this->_plugins['resource'][$type]);
+    }
+
+    /**
+     * Registers a prefilter function to apply
+     * to a template before compiling
+     *
+     * @param callback $function
+     */
+    function register_prefilter($function)
+    {
+        $this->_plugins['prefilter'][$this->_get_filter_name($function)]
+            = array($function, null, null, false);
+    }
+
+    /**
+     * Unregisters a prefilter function
+     *
+     * @param callback $function
+     */
+    function unregister_prefilter($function)
+    {
+        unset($this->_plugins['prefilter'][$this->_get_filter_name($function)]);
+    }
+
+    /**
+     * Registers a postfilter function to apply
+     * to a compiled template after compilation
+     *
+     * @param callback $function
+     */
+    function register_postfilter($function)
+    {
+        $this->_plugins['postfilter'][$this->_get_filter_name($function)]
+            = array($function, null, null, false);
+    }
+
+    /**
+     * Unregisters a postfilter function
+     *
+     * @param callback $function
+     */
+    function unregister_postfilter($function)
+    {
+        unset($this->_plugins['postfilter'][$this->_get_filter_name($function)]);
+    }
+
+    /**
+     * Registers an output filter function to apply
+     * to a template output
+     *
+     * @param callback $function
+     */
+    function register_outputfilter($function)
+    {
+        $this->_plugins['outputfilter'][$this->_get_filter_name($function)]
+            = array($function, null, null, false);
+    }
+
+    /**
+     * Unregisters an outputfilter function
+     *
+     * @param callback $function
+     */
+    function unregister_outputfilter($function)
+    {
+        unset($this->_plugins['outputfilter'][$this->_get_filter_name($function)]);
+    }
+
+    /**
+     * load a filter of specified type and name
+     *
+     * @param string $type filter type
+     * @param string $name filter name
+     */
+    function load_filter($type, $name)
+    {
+        switch ($type) {
+            case 'output':
+                $_params = array('plugins' => array(array($type . 'filter', $name, null, null, false)));
+                require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');
+                smarty_core_load_plugins($_params, $this);
+                break;
+
+            case 'pre':
+            case 'post':
+                if (!isset($this->_plugins[$type . 'filter'][$name]))
+                    $this->_plugins[$type . 'filter'][$name] = false;
+                break;
+        }
+    }
+
+    /**
+     * clear cached content for the given template and cache id
+     *
+     * @param string $tpl_file name of template file
+     * @param string $cache_id name of cache_id
+     * @param string $compile_id name of compile_id
+     * @param string $exp_time expiration time
+     * @return boolean
+     */
+    function clear_cache($tpl_file = null, $cache_id = null, $compile_id = null, $exp_time = null)
+    {
+
+        if (!isset($compile_id))
+            $compile_id = $this->compile_id;
+
+        if (!isset($tpl_file))
+            $compile_id = null;
+
+        $_auto_id = $this->_get_auto_id($cache_id, $compile_id);
+
+        if (!empty($this->cache_handler_func)) {
+            return call_user_func_array($this->cache_handler_func,
+                                  array('clear', &$this, &$dummy, $tpl_file, $cache_id, $compile_id, $exp_time));
+        } else {
+            $_params = array('auto_base' => $this->cache_dir,
+                            'auto_source' => $tpl_file,
+                            'auto_id' => $_auto_id,
+                            'exp_time' => $exp_time);
+            require_once(SMARTY_CORE_DIR . 'core.rm_auto.php');
+            return smarty_core_rm_auto($_params, $this);
+        }
+
+    }
+
+
+    /**
+     * clear the entire contents of cache (all templates)
+     *
+     * @param string $exp_time expire time
+     * @return boolean results of {@link smarty_core_rm_auto()}
+     */
+    function clear_all_cache($exp_time = null)
+    {
+        return $this->clear_cache(null, null, null, $exp_time);
+    }
+
+
+    /**
+     * test to see if valid cache exists for this template
+     *
+     * @param string $tpl_file name of template file
+     * @param string $cache_id
+     * @param string $compile_id
+     * @return string|false results of {@link _read_cache_file()}
+     */
+    function is_cached($tpl_file, $cache_id = null, $compile_id = null)
+    {
+        if (!$this->caching)
+            return false;
+
+        if (!isset($compile_id))
+            $compile_id = $this->compile_id;
+
+        $_params = array(
+            'tpl_file' => $tpl_file,
+            'cache_id' => $cache_id,
+            'compile_id' => $compile_id
+        );
+        require_once(SMARTY_CORE_DIR . 'core.read_cache_file.php');
+        return smarty_core_read_cache_file($_params, $this);
+    }
+
+
+    /**
+     * clear all the assigned template variables.
+     *
+     */
+    function clear_all_assign()
+    {
+        $this->_tpl_vars = array();
+    }
+
+    /**
+     * clears compiled version of specified template resource,
+     * or all compiled template files if one is not specified.
+     * This function is for advanced use only, not normally needed.
+     *
+     * @param string $tpl_file
+     * @param string $compile_id
+     * @param string $exp_time
+     * @return boolean results of {@link smarty_core_rm_auto()}
+     */
+    function clear_compiled_tpl($tpl_file = null, $compile_id = null, $exp_time = null)
+    {
+        if (!isset($compile_id)) {
+            $compile_id = $this->compile_id;
+        }
+        $_params = array('auto_base' => $this->compile_dir,
+                        'auto_source' => $tpl_file,
+                        'auto_id' => $compile_id,
+                        'exp_time' => $exp_time,
+                        'extensions' => array('.inc', '.php'));
+        require_once(SMARTY_CORE_DIR . 'core.rm_auto.php');
+        return smarty_core_rm_auto($_params, $this);
+    }
+
+    /**
+     * Checks whether requested template exists.
+     *
+     * @param string $tpl_file
+     * @return boolean
+     */
+    function template_exists($tpl_file)
+    {
+        $_params = array('resource_name' => $tpl_file, 'quiet'=>true, 'get_source'=>false);
+        return $this->_fetch_resource_info($_params);
+    }
+
+    /**
+     * Returns an array containing template variables
+     *
+     * @param string $name
+     * @param string $type
+     * @return array
+     */
+    function &get_template_vars($name=null)
+    {
+        if(!isset($name)) {
+            return $this->_tpl_vars;
+        } elseif(isset($this->_tpl_vars[$name])) {
+            return $this->_tpl_vars[$name];
+        } else {
+            // var non-existant, return valid reference
+            $_tmp = null;
+            return $_tmp;
+        }
+    }
+
+    /**
+     * Returns an array containing config variables
+     *
+     * @param string $name
+     * @param string $type
+     * @return array
+     */
+    function &get_config_vars($name=null)
+    {
+        if(!isset($name) && is_array($this->_config[0])) {
+            return $this->_config[0]['vars'];
+        } else if(isset($this->_config[0]['vars'][$name])) {
+            return $this->_config[0]['vars'][$name];
+        } else {
+            // var non-existant, return valid reference
+            $_tmp = null;
+            return $_tmp;
+        }
+    }
+
+    /**
+     * trigger Smarty error
+     *
+     * @param string $error_msg
+     * @param integer $error_type
+     */
+    function trigger_error($error_msg, $error_type = E_USER_WARNING)
+    {
+        trigger_error("Smarty error: $error_msg", $error_type);
+    }
+
+
+    /**
+     * executes & displays the template results
+     *
+     * @param string $resource_name
+     * @param string $cache_id
+     * @param string $compile_id
+     */
+    function display($resource_name, $cache_id = null, $compile_id = null)
+    {
+        $this->fetch($resource_name, $cache_id, $compile_id, true);
+    }
+
+    /**
+     * executes & returns or displays the template results
+     *
+     * @param string $resource_name
+     * @param string $cache_id
+     * @param string $compile_id
+     * @param boolean $display
+     */
+    function fetch($resource_name, $cache_id = null, $compile_id = null, $display = false)
+    {
+        static $_cache_info = array();
+
+        $_smarty_old_error_level = $this->debugging ? error_reporting() : error_reporting(isset($this->error_reporting)
+               ? $this->error_reporting : error_reporting() & ~E_NOTICE);
+
+        if (!$this->debugging && $this->debugging_ctrl == 'URL') {
+            $_query_string = $this->request_use_auto_globals ? $_SERVER['QUERY_STRING'] : $GLOBALS['HTTP_SERVER_VARS']['QUERY_STRING'];
+            if (@strstr($_query_string, $this->_smarty_debug_id)) {
+                if (@strstr($_query_string, $this->_smarty_debug_id . '=on')) {
+                    // enable debugging for this browser session
+                    @setcookie('SMARTY_DEBUG', true);
+                    $this->debugging = true;
+                } elseif (@strstr($_query_string, $this->_smarty_debug_id . '=off')) {
+                    // disable debugging for this browser session
+                    @setcookie('SMARTY_DEBUG', false);
+                    $this->debugging = false;
+                } else {
+                    // enable debugging for this page
+                    $this->debugging = true;
+                }
+            } else {
+                $this->debugging = (bool)($this->request_use_auto_globals ? @$_COOKIE['SMARTY_DEBUG'] : @$GLOBALS['HTTP_COOKIE_VARS']['SMARTY_DEBUG']);
+            }
+        }
+
+        if ($this->debugging) {
+            // capture time for debugging info
+            $_params = array();
+            require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
+            $_debug_start_time = smarty_core_get_microtime($_params, $this);
+            $this->_smarty_debug_info[] = array('type'      => 'template',
+                                                'filename'  => $resource_name,
+                                                'depth'     => 0);
+            $_included_tpls_idx = count($this->_smarty_debug_info) - 1;
+        }
+
+        if (!isset($compile_id)) {
+            $compile_id = $this->compile_id;
+        }
+
+        $this->_compile_id = $compile_id;
+        $this->_inclusion_depth = 0;
+
+        if ($this->caching) {
+            // save old cache_info, initialize cache_info
+            array_push($_cache_info, $this->_cache_info);
+            $this->_cache_info = array();
+            $_params = array(
+                'tpl_file' => $resource_name,
+                'cache_id' => $cache_id,
+                'compile_id' => $compile_id,
+                'results' => null
+            );
+            require_once(SMARTY_CORE_DIR . 'core.read_cache_file.php');
+            if (smarty_core_read_cache_file($_params, $this)) {
+                $_smarty_results = $_params['results'];
+                if (!empty($this->_cache_info['insert_tags'])) {
+                    $_params = array('plugins' => $this->_cache_info['insert_tags']);
+                    require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');
+                    smarty_core_load_plugins($_params, $this);
+                    $_params = array('results' => $_smarty_results);
+                    require_once(SMARTY_CORE_DIR . 'core.process_cached_inserts.php');
+                    $_smarty_results = smarty_core_process_cached_inserts($_params, $this);
+                }
+                if (!empty($this->_cache_info['cache_serials'])) {
+                    $_params = array('results' => $_smarty_results);
+                    require_once(SMARTY_CORE_DIR . 'core.process_compiled_include.php');
+                    $_smarty_results = smarty_core_process_compiled_include($_params, $this);
+                }
+
+
+                if ($display) {
+                    if ($this->debugging)
+                    {
+                        // capture time for debugging info
+                        $_params = array();
+                        require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
+                        $this->_smarty_debug_info[$_included_tpls_idx]['exec_time'] = smarty_core_get_microtime($_params, $this) - $_debug_start_time;
+                        require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php');
+                        $_smarty_results .= smarty_core_display_debug_console($_params, $this);
+                    }
+                    if ($this->cache_modified_check) {
+                        $_server_vars = ($this->request_use_auto_globals) ? $_SERVER : $GLOBALS['HTTP_SERVER_VARS'];
+                        $_last_modified_date = @substr($_server_vars['HTTP_IF_MODIFIED_SINCE'], 0, strpos($_server_vars['HTTP_IF_MODIFIED_SINCE'], 'GMT') + 3);
+                        $_gmt_mtime = gmdate('D, d M Y H:i:s', $this->_cache_info['timestamp']).' GMT';
+                        if (@count($this->_cache_info['insert_tags']) == 0
+                            && !$this->_cache_serials
+                            && $_gmt_mtime == $_last_modified_date) {
+                            if (php_sapi_name()=='cgi')
+                                header('Status: 304 Not Modified');
+                            else
+                                header('HTTP/1.1 304 Not Modified');
+
+                        } else {
+                            header('Last-Modified: '.$_gmt_mtime);
+                            echo $_smarty_results;
+                        }
+                    } else {
+                            echo $_smarty_results;
+                    }
+                    error_reporting($_smarty_old_error_level);
+                    // restore initial cache_info
+                    $this->_cache_info = array_pop($_cache_info);
+                    return true;
+                } else {
+                    error_reporting($_smarty_old_error_level);
+                    // restore initial cache_info
+                    $this->_cache_info = array_pop($_cache_info);
+                    return $_smarty_results;
+                }
+            } else {
+                $this->_cache_info['template'][$resource_name] = true;
+                if ($this->cache_modified_check && $display) {
+                    header('Last-Modified: '.gmdate('D, d M Y H:i:s', time()).' GMT');
+                }
+            }
+        }
+
+        // load filters that are marked as autoload
+        if (count($this->autoload_filters)) {
+            foreach ($this->autoload_filters as $_filter_type => $_filters) {
+                foreach ($_filters as $_filter) {
+                    $this->load_filter($_filter_type, $_filter);
+                }
+            }
+        }
+
+        $_smarty_compile_path = $this->_get_compile_path($resource_name);
+
+        // if we just need to display the results, don't perform output
+        // buffering - for speed
+        $_cache_including = $this->_cache_including;
+        $this->_cache_including = false;
+        if ($display && !$this->caching && count($this->_plugins['outputfilter']) == 0) {
+            if ($this->_is_compiled($resource_name, $_smarty_compile_path)
+                    || $this->_compile_resource($resource_name, $_smarty_compile_path))
+            {
+                include($_smarty_compile_path);
+            }
+        } else {
+            ob_start();
+            if ($this->_is_compiled($resource_name, $_smarty_compile_path)
+                    || $this->_compile_resource($resource_name, $_smarty_compile_path))
+            {
+                include($_smarty_compile_path);
+            }
+            $_smarty_results = ob_get_contents();
+            ob_end_clean();
+
+            foreach ((array)$this->_plugins['outputfilter'] as $_output_filter) {
+                $_smarty_results = call_user_func_array($_output_filter[0], array($_smarty_results, &$this));
+            }
+        }
+
+        if ($this->caching) {
+            $_params = array('tpl_file' => $resource_name,
+                        'cache_id' => $cache_id,
+                        'compile_id' => $compile_id,
+                        'results' => $_smarty_results);
+            require_once(SMARTY_CORE_DIR . 'core.write_cache_file.php');
+            smarty_core_write_cache_file($_params, $this);
+            require_once(SMARTY_CORE_DIR . 'core.process_cached_inserts.php');
+            $_smarty_results = smarty_core_process_cached_inserts($_params, $this);
+
+            if ($this->_cache_serials) {
+                // strip nocache-tags from output
+                $_smarty_results = preg_replace('!(\{/?nocache\:[0-9a-f]{32}#\d+\})!s'
+                                                ,''
+                                                ,$_smarty_results);
+            }
+            // restore initial cache_info
+            $this->_cache_info = array_pop($_cache_info);
+        }
+        $this->_cache_including = $_cache_including;
+
+        if ($display) {
+            if (isset($_smarty_results)) { echo $_smarty_results; }
+            if ($this->debugging) {
+                // capture time for debugging info
+                $_params = array();
+                require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
+                $this->_smarty_debug_info[$_included_tpls_idx]['exec_time'] = (smarty_core_get_microtime($_params, $this) - $_debug_start_time);
+                require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php');
+                echo smarty_core_display_debug_console($_params, $this);
+            }
+            error_reporting($_smarty_old_error_level);
+            return;
+        } else {
+            if ($this->debugging) {
+                // capture time for debugging info
+                $_params = array();
+                require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
+                $this->_smarty_debug_info[$_included_tpls_idx]['exec_time'] = (smarty_core_get_microtime($_params, $this) - $_debug_start_time);
+            }
+            error_reporting($_smarty_old_error_level);
+            if (isset($_smarty_results)) { return $_smarty_results; }
+        }
+    }
+
+    /**
+     * load configuration values
+     *
+     * @param string $file
+     * @param string $section
+     * @param string $scope
+     */
+    function config_load($file, $section = null, $scope = 'global')
+    {
+        require_once($this->_get_plugin_filepath('function', 'config_load'));
+        smarty_function_config_load(array('file' => $file, 'section' => $section, 'scope' => $scope), $this);
+    }
+
+    /**
+     * return a reference to a registered object
+     *
+     * @param string $name
+     * @return object
+     */
+    function &get_registered_object($name) {
+        if (!isset($this->_reg_objects[$name]))
+        $this->_trigger_fatal_error("'$name' is not a registered object");
+
+        if (!is_object($this->_reg_objects[$name][0]))
+        $this->_trigger_fatal_error("registered '$name' is not an object");
+
+        return $this->_reg_objects[$name][0];
+    }
+
+    /**
+     * clear configuration values
+     *
+     * @param string $var
+     */
+    function clear_config($var = null)
+    {
+        if(!isset($var)) {
+            // clear all values
+            $this->_config = array(array('vars'  => array(),
+                                         'files' => array()));
+        } else {
+            unset($this->_config[0]['vars'][$var]);
+        }
+    }
+
+    /**
+     * get filepath of requested plugin
+     *
+     * @param string $type
+     * @param string $name
+     * @return string|false
+     */
+    function _get_plugin_filepath($type, $name)
+    {
+        $_params = array('type' => $type, 'name' => $name);
+        require_once(SMARTY_CORE_DIR . 'core.assemble_plugin_filepath.php');
+        return smarty_core_assemble_plugin_filepath($_params, $this);
+    }
+
+   /**
+     * test if resource needs compiling
+     *
+     * @param string $resource_name
+     * @param string $compile_path
+     * @return boolean
+     */
+    function _is_compiled($resource_name, $compile_path)
+    {
+        if (!$this->force_compile && file_exists($compile_path)) {
+            if (!$this->compile_check) {
+                // no need to check compiled file
+                return true;
+            } else {
+                // get file source and timestamp
+                $_params = array('resource_name' => $resource_name, 'get_source'=>false);
+                if (!$this->_fetch_resource_info($_params)) {
+                    return false;
+                }
+                if ($_params['resource_timestamp'] <= filemtime($compile_path)) {
+                    // template not expired, no recompile
+                    return true;
+                } else {
+                    // compile template
+                    return false;
+                }
+            }
+        } else {
+            // compiled template does not exist, or forced compile
+            return false;
+        }
+    }
+
+   /**
+     * compile the template
+     *
+     * @param string $resource_name
+     * @param string $compile_path
+     * @return boolean
+     */
+    function _compile_resource($resource_name, $compile_path)
+    {
+
+        $_params = array('resource_name' => $resource_name);
+        if (!$this->_fetch_resource_info($_params)) {
+            return false;
+        }
+
+        $_source_content = $_params['source_content'];
+        $_cache_include    = substr($compile_path, 0, -4).'.inc';
+
+        if ($this->_compile_source($resource_name, $_source_content, $_compiled_content, $_cache_include)) {
+            // if a _cache_serial was set, we also have to write an include-file:
+            if ($this->_cache_include_info) {
+                require_once(SMARTY_CORE_DIR . 'core.write_compiled_include.php');
+                smarty_core_write_compiled_include(array_merge($this->_cache_include_info, array('compiled_content'=>$_compiled_content, 'resource_name'=>$resource_name)),  $this);
+            }
+
+            $_params = array('compile_path'=>$compile_path, 'compiled_content' => $_compiled_content);
+            require_once(SMARTY_CORE_DIR . 'core.write_compiled_resource.php');
+            smarty_core_write_compiled_resource($_params, $this);
+
+            return true;
+        } else {
+            return false;
+        }
+
+    }
+
+   /**
+     * compile the given source
+     *
+     * @param string $resource_name
+     * @param string $source_content
+     * @param string $compiled_content
+     * @return boolean
+     */
+    function _compile_source($resource_name, &$source_content, &$compiled_content, $cache_include_path=null)
+    {
+        if (file_exists(SMARTY_DIR . $this->compiler_file)) {
+            require_once(SMARTY_DIR . $this->compiler_file);
+        } else {
+            // use include_path
+            require_once($this->compiler_file);
+        }
+
+
+        $smarty_compiler = new $this->compiler_class;
+
+        $smarty_compiler->template_dir      = $this->template_dir;
+        $smarty_compiler->compile_dir       = $this->compile_dir;
+        $smarty_compiler->plugins_dir       = $this->plugins_dir;
+        $smarty_compiler->config_dir        = $this->config_dir;
+        $smarty_compiler->force_compile     = $this->force_compile;
+        $smarty_compiler->caching           = $this->caching;
+        $smarty_compiler->php_handling      = $this->php_handling;
+        $smarty_compiler->left_delimiter    = $this->left_delimiter;
+        $smarty_compiler->right_delimiter   = $this->right_delimiter;
+        $smarty_compiler->_version          = $this->_version;
+        $smarty_compiler->security          = $this->security;
+        $smarty_compiler->secure_dir        = $this->secure_dir;
+        $smarty_compiler->security_settings = $this->security_settings;
+        $smarty_compiler->trusted_dir       = $this->trusted_dir;
+        $smarty_compiler->use_sub_dirs      = $this->use_sub_dirs;
+        $smarty_compiler->_reg_objects      = &$this->_reg_objects;
+        $smarty_compiler->_plugins          = &$this->_plugins;
+        $smarty_compiler->_tpl_vars         = &$this->_tpl_vars;
+        $smarty_compiler->default_modifiers = $this->default_modifiers;
+        $smarty_compiler->compile_id        = $this->_compile_id;
+        $smarty_compiler->_config            = $this->_config;
+        $smarty_compiler->request_use_auto_globals  = $this->request_use_auto_globals;
+
+        if (isset($cache_include_path) && isset($this->_cache_serials[$cache_include_path])) {
+            $smarty_compiler->_cache_serial = $this->_cache_serials[$cache_include_path];
+        }
+        $smarty_compiler->_cache_include = $cache_include_path;
+
+
+        $_results = $smarty_compiler->_compile_file($resource_name, $source_content, $compiled_content);
+
+        if ($smarty_compiler->_cache_serial) {
+            $this->_cache_include_info = array(
+                'cache_serial'=>$smarty_compiler->_cache_serial
+                ,'plugins_code'=>$smarty_compiler->_plugins_code
+                ,'include_file_path' => $cache_include_path);
+
+        } else {
+            $this->_cache_include_info = null;
+
+        }
+
+        return $_results;
+    }
+
+    /**
+     * Get the compile path for this resource
+     *
+     * @param string $resource_name
+     * @return string results of {@link _get_auto_filename()}
+     */
+    function _get_compile_path($resource_name)
+    {
+        return $this->_get_auto_filename($this->compile_dir, $resource_name,
+                                         $this->_compile_id) . '.php';
+    }
+
+    /**
+     * fetch the template info. Gets timestamp, and source
+     * if get_source is true
+     *
+     * sets $source_content to the source of the template, and
+     * $resource_timestamp to its time stamp
+     * @param string $resource_name
+     * @param string $source_content
+     * @param integer $resource_timestamp
+     * @param boolean $get_source
+     * @param boolean $quiet
+     * @return boolean
+     */
+
+    function _fetch_resource_info(&$params)
+    {
+        if(!isset($params['get_source'])) { $params['get_source'] = true; }
+        if(!isset($params['quiet'])) { $params['quiet'] = false; }
+
+        $_return = false;
+        $_params = array('resource_name' => $params['resource_name']) ;
+        if (isset($params['resource_base_path']))
+            $_params['resource_base_path'] = $params['resource_base_path'];
+        else
+            $_params['resource_base_path'] = $this->template_dir;
+
+        if ($this->_parse_resource_name($_params)) {
+            $_resource_type = $_params['resource_type'];
+            $_resource_name = $_params['resource_name'];
+            switch ($_resource_type) {
+                case 'file':
+                    if ($params['get_source']) {
+                        $params['source_content'] = $this->_read_file($_resource_name);
+                    }
+                    $params['resource_timestamp'] = filemtime($_resource_name);
+                    $_return = is_file($_resource_name);
+                    break;
+
+                default:
+                    // call resource functions to fetch the template source and timestamp
+                    if ($params['get_source']) {
+                        $_source_return = isset($this->_plugins['resource'][$_resource_type]) &&
+                            call_user_func_array($this->_plugins['resource'][$_resource_type][0][0],
+                                                 array($_resource_name, &$params['source_content'], &$this));
+                    } else {
+                        $_source_return = true;
+                    }
+
+                    $_timestamp_return = isset($this->_plugins['resource'][$_resource_type]) &&
+                        call_user_func_array($this->_plugins['resource'][$_resource_type][0][1],
+                                             array($_resource_name, &$params['resource_timestamp'], &$this));
+
+                    $_return = $_source_return && $_timestamp_return;
+                    break;
+            }
+        }
+
+        if (!$_return) {
+            // see if we can get a template with the default template handler
+            if (!empty($this->default_template_handler_func)) {
+                if (!is_callable($this->default_template_handler_func)) {
+                    $this->trigger_error("default template handler function \"$this->default_template_handler_func\" doesn't exist.");
+                } else {
+                    $_return = call_user_func_array(
+                        $this->default_template_handler_func,
+                        array($_params['resource_type'], $_params['resource_name'], &$params['source_content'], &$params['resource_timestamp'], &$this));
+                }
+            }
+        }
+
+        if (!$_return) {
+            if (!$params['quiet']) {
+                $this->trigger_error('unable to read resource: "' . $params['resource_name'] . '"');
+            }
+        } else if ($_return && $this->security) {
+            require_once(SMARTY_CORE_DIR . 'core.is_secure.php');
+            if (!smarty_core_is_secure($_params, $this)) {
+                if (!$params['quiet'])
+                    $this->trigger_error('(secure mode) accessing "' . $params['resource_name'] . '" is not allowed');
+                $params['source_content'] = null;
+                $params['resource_timestamp'] = null;
+                return false;
+            }
+        }
+        return $_return;
+    }
+
+
+    /**
+     * parse out the type and name from the resource
+     *
+     * @param string $resource_base_path
+     * @param string $resource_name
+     * @param string $resource_type
+     * @param string $resource_name
+     * @return boolean
+     */
+
+    function _parse_resource_name(&$params)
+    {
+
+        // split tpl_path by the first colon
+        $_resource_name_parts = explode(':', $params['resource_name'], 2);
+
+        if (count($_resource_name_parts) == 1) {
+            // no resource type given
+            $params['resource_type'] = $this->default_resource_type;
+            $params['resource_name'] = $_resource_name_parts[0];
+        } else {
+            if(strlen($_resource_name_parts[0]) == 1) {
+                // 1 char is not resource type, but part of filepath
+                $params['resource_type'] = $this->default_resource_type;
+                $params['resource_name'] = $params['resource_name'];
+            } else {
+                $params['resource_type'] = $_resource_name_parts[0];
+                $params['resource_name'] = $_resource_name_parts[1];
+            }
+        }
+
+        if ($params['resource_type'] == 'file') {
+            if (!preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $params['resource_name'])) {
+                // relative pathname to $params['resource_base_path']
+                // use the first directory where the file is found
+                foreach ((array)$params['resource_base_path'] as $_curr_path) {
+                    $_fullpath = $_curr_path . DIRECTORY_SEPARATOR . $params['resource_name'];
+                    if (file_exists($_fullpath) && is_file($_fullpath)) {
+                        $params['resource_name'] = $_fullpath;
+                        return true;
+                    }
+                    // didn't find the file, try include_path
+                    $_params = array('file_path' => $_fullpath);
+                    require_once(SMARTY_CORE_DIR . 'core.get_include_path.php');
+                    if(smarty_core_get_include_path($_params, $this)) {
+                        $params['resource_name'] = $_params['new_file_path'];
+                        return true;
+                    }
+                }
+                return false;
+            } else {
+                /* absolute path */
+                return file_exists($params['resource_name']);
+            }
+        } elseif (empty($this->_plugins['resource'][$params['resource_type']])) {
+            $_params = array('type' => $params['resource_type']);
+            require_once(SMARTY_CORE_DIR . 'core.load_resource_plugin.php');
+            smarty_core_load_resource_plugin($_params, $this);
+        }
+
+        return true;
+    }
+
+
+    /**
+     * Handle modifiers
+     *
+     * @param string|null $modifier_name
+     * @param array|null $map_array
+     * @return string result of modifiers
+     */
+    function _run_mod_handler()
+    {
+        $_args = func_get_args();
+        list($_modifier_name, $_map_array) = array_splice($_args, 0, 2);
+        list($_func_name, $_tpl_file, $_tpl_line) =
+            $this->_plugins['modifier'][$_modifier_name];
+
+        $_var = $_args[0];
+        foreach ($_var as $_key => $_val) {
+            $_args[0] = $_val;
+            $_var[$_key] = call_user_func_array($_func_name, $_args);
+        }
+        return $_var;
+    }
+
+    /**
+     * Remove starting and ending quotes from the string
+     *
+     * @param string $string
+     * @return string
+     */
+    function _dequote($string)
+    {
+        if ((substr($string, 0, 1) == "'" || substr($string, 0, 1) == '"') &&
+            substr($string, -1) == substr($string, 0, 1))
+            return substr($string, 1, -1);
+        else
+            return $string;
+    }
+
+
+    /**
+     * read in a file
+     *
+     * @param string $filename
+     * @return string
+     */
+    function _read_file($filename)
+    {
+        if ( file_exists($filename) && ($fd = @fopen($filename, 'rb')) ) {
+            $contents = '';
+            while (!feof($fd)) {
+                $contents .= fread($fd, 8192);
+            }
+            fclose($fd);
+            return $contents;
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * get a concrete filename for automagically created content
+     *
+     * @param string $auto_base
+     * @param string $auto_source
+     * @param string $auto_id
+     * @return string
+     * @staticvar string|null
+     * @staticvar string|null
+     */
+    function _get_auto_filename($auto_base, $auto_source = null, $auto_id = null)
+    {
+        $_compile_dir_sep =  $this->use_sub_dirs ? DIRECTORY_SEPARATOR : '^';
+        $_return = $auto_base . DIRECTORY_SEPARATOR;
+
+        if(isset($auto_id)) {
+            // make auto_id safe for directory names
+            $auto_id = str_replace('%7C',$_compile_dir_sep,(urlencode($auto_id)));
+            // split into separate directories
+            $_return .= $auto_id . $_compile_dir_sep;
+        }
+
+        if(isset($auto_source)) {
+            // make source name safe for filename
+            $_filename = urlencode(basename($auto_source));
+            $_crc32 = sprintf('%08X', crc32($auto_source));
+            // prepend %% to avoid name conflicts with
+            // with $params['auto_id'] names
+            $_crc32 = substr($_crc32, 0, 2) . $_compile_dir_sep .
+                      substr($_crc32, 0, 3) . $_compile_dir_sep . $_crc32;
+            $_return .= '%%' . $_crc32 . '%%' . $_filename;
+        }
+
+        return $_return;
+    }
+
+    /**
+     * unlink a file, possibly using expiration time
+     *
+     * @param string $resource
+     * @param integer $exp_time
+     */
+    function _unlink($resource, $exp_time = null)
+    {
+        if(isset($exp_time)) {
+            if(time() - @filemtime($resource) >= $exp_time) {
+                return @unlink($resource);
+            }
+        } else {
+            return @unlink($resource);
+        }
+    }
+
+    /**
+     * returns an auto_id for auto-file-functions
+     *
+     * @param string $cache_id
+     * @param string $compile_id
+     * @return string|null
+     */
+    function _get_auto_id($cache_id=null, $compile_id=null) {
+    if (isset($cache_id))
+        return (isset($compile_id)) ? $cache_id . '|' . $compile_id  : $cache_id;
+    elseif(isset($compile_id))
+        return $compile_id;
+    else
+        return null;
+    }
+
+    /**
+     * trigger Smarty plugin error
+     *
+     * @param string $error_msg
+     * @param string $tpl_file
+     * @param integer $tpl_line
+     * @param string $file
+     * @param integer $line
+     * @param integer $error_type
+     */
+    function _trigger_fatal_error($error_msg, $tpl_file = null, $tpl_line = null,
+            $file = null, $line = null, $error_type = E_USER_ERROR)
+    {
+        if(isset($file) && isset($line)) {
+            $info = ' ('.basename($file).", line $line)";
+        } else {
+            $info = '';
+        }
+        if (isset($tpl_line) && isset($tpl_file)) {
+            $this->trigger_error('[in ' . $tpl_file . ' line ' . $tpl_line . "]: $error_msg$info", $error_type);
+        } else {
+            $this->trigger_error($error_msg . $info, $error_type);
+        }
+    }
+
+
+    /**
+     * callback function for preg_replace, to call a non-cacheable block
+     * @return string
+     */
+    function _process_compiled_include_callback($match) {
+        $_func = '_smarty_tplfunc_'.$match[2].'_'.$match[3];
+        ob_start();
+        $_func($this);
+        $_ret = ob_get_contents();
+        ob_end_clean();
+        return $_ret;
+    }
+
+
+    /**
+     * called for included templates
+     *
+     * @param string $_smarty_include_tpl_file
+     * @param string $_smarty_include_vars
+     */
+
+    // $_smarty_include_tpl_file, $_smarty_include_vars
+
+    function _smarty_include($params)
+    {
+        if ($this->debugging) {
+            $_params = array();
+            require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
+            $debug_start_time = smarty_core_get_microtime($_params, $this);
+            $this->_smarty_debug_info[] = array('type'      => 'template',
+                                                  'filename'  => $params['smarty_include_tpl_file'],
+                                                  'depth'     => ++$this->_inclusion_depth);
+            $included_tpls_idx = count($this->_smarty_debug_info) - 1;
+        }
+
+        $this->_tpl_vars = array_merge($this->_tpl_vars, $params['smarty_include_vars']);
+
+        // config vars are treated as local, so push a copy of the
+        // current ones onto the front of the stack
+        array_unshift($this->_config, $this->_config[0]);
+
+        $_smarty_compile_path = $this->_get_compile_path($params['smarty_include_tpl_file']);
+
+
+        if ($this->_is_compiled($params['smarty_include_tpl_file'], $_smarty_compile_path)
+            || $this->_compile_resource($params['smarty_include_tpl_file'], $_smarty_compile_path))
+        {
+            include($_smarty_compile_path);
+        }
+
+        // pop the local vars off the front of the stack
+        array_shift($this->_config);
+
+        $this->_inclusion_depth--;
+
+        if ($this->debugging) {
+            // capture time for debugging info
+            $_params = array();
+            require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
+            $this->_smarty_debug_info[$included_tpls_idx]['exec_time'] = smarty_core_get_microtime($_params, $this) - $debug_start_time;
+        }
+
+        if ($this->caching) {
+            $this->_cache_info['template'][$params['smarty_include_tpl_file']] = true;
+        }
+    }
+
+
+    /**
+     * get or set an array of cached attributes for function that is
+     * not cacheable
+     * @return array
+     */
+    function &_smarty_cache_attrs($cache_serial, $count) {
+        $_cache_attrs =& $this->_cache_info['cache_attrs'][$cache_serial][$count];
+
+        if ($this->_cache_including) {
+            /* return next set of cache_attrs */
+            $_return = current($_cache_attrs);
+            next($_cache_attrs);
+            return $_return;
+
+        } else {
+            /* add a reference to a new set of cache_attrs */
+            $_cache_attrs[] = array();
+            return $_cache_attrs[count($_cache_attrs)-1];
+
+        }
+
+    }
+
+
+    /**
+     * wrapper for include() retaining $this
+     * @return mixed
+     */
+    function _include($filename, $once=false, $params=null)
+    {
+        if ($once) {
+            return include_once($filename);
+        } else {
+            return include($filename);
+        }
+    }
+
+
+    /**
+     * wrapper for eval() retaining $this
+     * @return mixed
+     */
+    function _eval($code, $params=null)
+    {
+        return eval($code);
+    }
+
+    /**
+     * Extracts the filter name from the given callback
+     *
+     * @param callback $function
+     * @return string
+     */
+	function _get_filter_name($function)
+	{
+		if (is_array($function)) {
+			$_class_name = (is_object($function[0]) ?
+				get_class($function[0]) : $function[0]);
+			return $_class_name . '_' . $function[1];
+		}
+		else {
+			return $function;
+		}
+	}
+
+    /**#@-*/
+
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/Smarty_Compiler.class.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/Smarty_Compiler.class.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/Smarty_Compiler.class.php	(revision 3278)
@@ -0,0 +1,2351 @@
+<?php
+
+/**
+ * Project:     Smarty: the PHP compiling template engine
+ * File:        Smarty_Compiler.class.php
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * @link http://www.smarty.net/
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @author Andrei Zmievski <andrei@php.net>
+ * @version 2.6.22
+ * @copyright 2001-2005 New Digital Group, Inc.
+ * @package Smarty
+ */
+
+/* $Id: Smarty_Compiler.class.php 2966 2008-12-08 15:10:03Z monte.ohrt $ */
+
+/**
+ * Template compiling class
+ * @package Smarty
+ */
+class Smarty_Compiler extends Smarty {
+
+    // internal vars
+    /**#@+
+     * @access private
+     */
+    var $_folded_blocks         =   array();    // keeps folded template blocks
+    var $_current_file          =   null;       // the current template being compiled
+    var $_current_line_no       =   1;          // line number for error messages
+    var $_capture_stack         =   array();    // keeps track of nested capture buffers
+    var $_plugin_info           =   array();    // keeps track of plugins to load
+    var $_init_smarty_vars      =   false;
+    var $_permitted_tokens      =   array('true','false','yes','no','on','off','null');
+    var $_db_qstr_regexp        =   null;        // regexps are setup in the constructor
+    var $_si_qstr_regexp        =   null;
+    var $_qstr_regexp           =   null;
+    var $_func_regexp           =   null;
+    var $_reg_obj_regexp        =   null;
+    var $_var_bracket_regexp    =   null;
+    var $_num_const_regexp      =   null;
+    var $_dvar_guts_regexp      =   null;
+    var $_dvar_regexp           =   null;
+    var $_cvar_regexp           =   null;
+    var $_svar_regexp           =   null;
+    var $_avar_regexp           =   null;
+    var $_mod_regexp            =   null;
+    var $_var_regexp            =   null;
+    var $_parenth_param_regexp  =   null;
+    var $_func_call_regexp      =   null;
+    var $_obj_ext_regexp        =   null;
+    var $_obj_start_regexp      =   null;
+    var $_obj_params_regexp     =   null;
+    var $_obj_call_regexp       =   null;
+    var $_cacheable_state       =   0;
+    var $_cache_attrs_count     =   0;
+    var $_nocache_count         =   0;
+    var $_cache_serial          =   null;
+    var $_cache_include         =   null;
+
+    var $_strip_depth           =   0;
+    var $_additional_newline    =   "\n";
+    
+    var $_phpversion            =   0;
+
+
+    /**#@-*/
+    /**
+     * The class constructor.
+     */
+    function Smarty_Compiler()
+    {
+        $this->_phpversion = substr(phpversion(),0,1);
+
+        // matches double quoted strings:
+        // "foobar"
+        // "foo\"bar"
+        $this->_db_qstr_regexp = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"';
+
+        // matches single quoted strings:
+        // 'foobar'
+        // 'foo\'bar'
+        $this->_si_qstr_regexp = '\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\'';
+
+        // matches single or double quoted strings
+        $this->_qstr_regexp = '(?:' . $this->_db_qstr_regexp . '|' . $this->_si_qstr_regexp . ')';
+
+        // matches bracket portion of vars
+        // [0]
+        // [foo]
+        // [$bar]
+        $this->_var_bracket_regexp = '\[\$?[\w\.]+\]';
+
+        // matches numerical constants
+        // 30
+        // -12
+        // 13.22
+        $this->_num_const_regexp = '(?:\-?\d+(?:\.\d+)?)';
+
+        // matches $ vars (not objects):
+        // $foo
+        // $foo.bar
+        // $foo.bar.foobar
+        // $foo[0]
+        // $foo[$bar]
+        // $foo[5][blah]
+        // $foo[5].bar[$foobar][4]
+        $this->_dvar_math_regexp = '(?:[\+\*\/\%]|(?:-(?!>)))';
+        $this->_dvar_math_var_regexp = '[\$\w\.\+\-\*\/\%\d\>\[\]]';
+        $this->_dvar_guts_regexp = '\w+(?:' . $this->_var_bracket_regexp
+                . ')*(?:\.\$?\w+(?:' . $this->_var_bracket_regexp . ')*)*(?:' . $this->_dvar_math_regexp . '(?:' . $this->_num_const_regexp . '|' . $this->_dvar_math_var_regexp . ')*)?';
+        $this->_dvar_regexp = '\$' . $this->_dvar_guts_regexp;
+
+        // matches config vars:
+        // #foo#
+        // #foobar123_foo#
+        $this->_cvar_regexp = '\#\w+\#';
+
+        // matches section vars:
+        // %foo.bar%
+        $this->_svar_regexp = '\%\w+\.\w+\%';
+
+        // matches all valid variables (no quotes, no modifiers)
+        $this->_avar_regexp = '(?:' . $this->_dvar_regexp . '|'
+           . $this->_cvar_regexp . '|' . $this->_svar_regexp . ')';
+
+        // matches valid variable syntax:
+        // $foo
+        // $foo
+        // #foo#
+        // #foo#
+        // "text"
+        // "text"
+        $this->_var_regexp = '(?:' . $this->_avar_regexp . '|' . $this->_qstr_regexp . ')';
+
+        // matches valid object call (one level of object nesting allowed in parameters):
+        // $foo->bar
+        // $foo->bar()
+        // $foo->bar("text")
+        // $foo->bar($foo, $bar, "text")
+        // $foo->bar($foo, "foo")
+        // $foo->bar->foo()
+        // $foo->bar->foo->bar()
+        // $foo->bar($foo->bar)
+        // $foo->bar($foo->bar())
+        // $foo->bar($foo->bar($blah,$foo,44,"foo",$foo[0].bar))
+        // $foo->getBar()->getFoo()
+        // $foo->getBar()->foo
+        $this->_obj_ext_regexp = '\->(?:\$?' . $this->_dvar_guts_regexp . ')';
+        $this->_obj_restricted_param_regexp = '(?:'
+             . '(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . ')(?:' . $this->_obj_ext_regexp . '(?:\((?:(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . ')'
+             . '(?:\s*,\s*(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . '))*)?\))?)*)';
+
+       $this->_obj_single_param_regexp = '(?:\w+|' . $this->_obj_restricted_param_regexp . '(?:\s*,\s*(?:(?:\w+|'
+                . $this->_var_regexp . $this->_obj_restricted_param_regexp . ')))*)';
+
+       $this->_obj_params_regexp = '\((?:' . $this->_obj_single_param_regexp
+                . '(?:\s*,\s*' . $this->_obj_single_param_regexp . ')*)?\)';
+       $this->_obj_start_regexp = '(?:' . $this->_dvar_regexp . '(?:' . $this->_obj_ext_regexp . ')+)';
+       $this->_obj_call_regexp = '(?:' . $this->_obj_start_regexp . '(?:' . $this->_obj_params_regexp . ')?(?:' . $this->_dvar_math_regexp . '(?:' . $this->_num_const_regexp . '|' . $this->_dvar_math_var_regexp . ')*)?)';
+        
+        // matches valid modifier syntax:
+        // |foo
+        // |@foo
+        // |foo:"bar"
+        // |foo:$bar
+        // |foo:"bar":$foobar
+        // |foo|bar
+        // |foo:$foo->bar
+        $this->_mod_regexp = '(?:\|@?\w+(?::(?:\w+|' . $this->_num_const_regexp . '|'
+           . $this->_obj_call_regexp . '|' . $this->_avar_regexp . '|' . $this->_qstr_regexp .'))*)';
+
+        // matches valid function name:
+        // foo123
+        // _foo_bar
+        $this->_func_regexp = '[a-zA-Z_]\w*';
+
+        // matches valid registered object:
+        // foo->bar
+        $this->_reg_obj_regexp = '[a-zA-Z_]\w*->[a-zA-Z_]\w*';
+
+        // matches valid parameter values:
+        // true
+        // $foo
+        // $foo|bar
+        // #foo#
+        // #foo#|bar
+        // "text"
+        // "text"|bar
+        // $foo->bar
+        $this->_param_regexp = '(?:\s*(?:' . $this->_obj_call_regexp . '|'
+           . $this->_var_regexp . '|' . $this->_num_const_regexp  . '|\w+)(?>' . $this->_mod_regexp . '*)\s*)';
+
+        // matches valid parenthesised function parameters:
+        //
+        // "text"
+        //    $foo, $bar, "text"
+        // $foo|bar, "foo"|bar, $foo->bar($foo)|bar
+        $this->_parenth_param_regexp = '(?:\((?:\w+|'
+                . $this->_param_regexp . '(?:\s*,\s*(?:(?:\w+|'
+                . $this->_param_regexp . ')))*)?\))';
+
+        // matches valid function call:
+        // foo()
+        // foo_bar($foo)
+        // _foo_bar($foo,"bar")
+        // foo123($foo,$foo->bar(),"foo")
+        $this->_func_call_regexp = '(?:' . $this->_func_regexp . '\s*(?:'
+           . $this->_parenth_param_regexp . '))';
+    }
+
+    /**
+     * compile a resource
+     *
+     * sets $compiled_content to the compiled source
+     * @param string $resource_name
+     * @param string $source_content
+     * @param string $compiled_content
+     * @return true
+     */
+    function _compile_file($resource_name, $source_content, &$compiled_content)
+    {
+
+        if ($this->security) {
+            // do not allow php syntax to be executed unless specified
+            if ($this->php_handling == SMARTY_PHP_ALLOW &&
+                !$this->security_settings['PHP_HANDLING']) {
+                $this->php_handling = SMARTY_PHP_PASSTHRU;
+            }
+        }
+
+        $this->_load_filters();
+
+        $this->_current_file = $resource_name;
+        $this->_current_line_no = 1;
+        $ldq = preg_quote($this->left_delimiter, '~');
+        $rdq = preg_quote($this->right_delimiter, '~');
+
+        // run template source through prefilter functions
+        if (count($this->_plugins['prefilter']) > 0) {
+            foreach ($this->_plugins['prefilter'] as $filter_name => $prefilter) {
+                if ($prefilter === false) continue;
+                if ($prefilter[3] || is_callable($prefilter[0])) {
+                    $source_content = call_user_func_array($prefilter[0],
+                                                            array($source_content, &$this));
+                    $this->_plugins['prefilter'][$filter_name][3] = true;
+                } else {
+                    $this->_trigger_fatal_error("[plugin] prefilter '$filter_name' is not implemented");
+                }
+            }
+        }
+
+        /* fetch all special blocks */
+        $search = "~{$ldq}\*(.*?)\*{$rdq}|{$ldq}\s*literal\s*{$rdq}(.*?){$ldq}\s*/literal\s*{$rdq}|{$ldq}\s*php\s*{$rdq}(.*?){$ldq}\s*/php\s*{$rdq}~s";
+
+        preg_match_all($search, $source_content, $match,  PREG_SET_ORDER);
+        $this->_folded_blocks = $match;
+        reset($this->_folded_blocks);
+
+        /* replace special blocks by "{php}" */
+        $source_content = preg_replace($search.'e', "'"
+                                       . $this->_quote_replace($this->left_delimiter) . 'php'
+                                       . "' . str_repeat(\"\n\", substr_count('\\0', \"\n\")) .'"
+                                       . $this->_quote_replace($this->right_delimiter)
+                                       . "'"
+                                       , $source_content);
+
+        /* Gather all template tags. */
+        preg_match_all("~{$ldq}\s*(.*?)\s*{$rdq}~s", $source_content, $_match);
+        $template_tags = $_match[1];
+        /* Split content by template tags to obtain non-template content. */
+        $text_blocks = preg_split("~{$ldq}.*?{$rdq}~s", $source_content);
+
+        /* loop through text blocks */
+        for ($curr_tb = 0, $for_max = count($text_blocks); $curr_tb < $for_max; $curr_tb++) {
+            /* match anything resembling php tags */
+            if (preg_match_all('~(<\?(?:\w+|=)?|\?>|language\s*=\s*[\"\']?\s*php\s*[\"\']?)~is', $text_blocks[$curr_tb], $sp_match)) {
+                /* replace tags with placeholders to prevent recursive replacements */
+                $sp_match[1] = array_unique($sp_match[1]);
+                usort($sp_match[1], '_smarty_sort_length');
+                for ($curr_sp = 0, $for_max2 = count($sp_match[1]); $curr_sp < $for_max2; $curr_sp++) {
+                    $text_blocks[$curr_tb] = str_replace($sp_match[1][$curr_sp],'%%%SMARTYSP'.$curr_sp.'%%%',$text_blocks[$curr_tb]);
+                }
+                /* process each one */
+                for ($curr_sp = 0, $for_max2 = count($sp_match[1]); $curr_sp < $for_max2; $curr_sp++) {
+                    if ($this->php_handling == SMARTY_PHP_PASSTHRU) {
+                        /* echo php contents */
+                        $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', '<?php echo \''.str_replace("'", "\'", $sp_match[1][$curr_sp]).'\'; ?>'."\n", $text_blocks[$curr_tb]);
+                    } else if ($this->php_handling == SMARTY_PHP_QUOTE) {
+                        /* quote php tags */
+                        $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', htmlspecialchars($sp_match[1][$curr_sp]), $text_blocks[$curr_tb]);
+                    } else if ($this->php_handling == SMARTY_PHP_REMOVE) {
+                        /* remove php tags */
+                        $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', '', $text_blocks[$curr_tb]);
+                    } else {
+                        /* SMARTY_PHP_ALLOW, but echo non php starting tags */
+                        $sp_match[1][$curr_sp] = preg_replace('~(<\?(?!php|=|$))~i', '<?php echo \'\\1\'?>'."\n", $sp_match[1][$curr_sp]);
+                        $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', $sp_match[1][$curr_sp], $text_blocks[$curr_tb]);
+                    }
+                }
+            }
+        }
+        
+        /* Compile the template tags into PHP code. */
+        $compiled_tags = array();
+        for ($i = 0, $for_max = count($template_tags); $i < $for_max; $i++) {
+            $this->_current_line_no += substr_count($text_blocks[$i], "\n");
+            $compiled_tags[] = $this->_compile_tag($template_tags[$i]);
+            $this->_current_line_no += substr_count($template_tags[$i], "\n");
+        }
+        if (count($this->_tag_stack)>0) {
+            list($_open_tag, $_line_no) = end($this->_tag_stack);
+            $this->_syntax_error("unclosed tag \{$_open_tag} (opened line $_line_no).", E_USER_ERROR, __FILE__, __LINE__);
+            return;
+        }
+
+        /* Reformat $text_blocks between 'strip' and '/strip' tags,
+           removing spaces, tabs and newlines. */
+        $strip = false;
+        for ($i = 0, $for_max = count($compiled_tags); $i < $for_max; $i++) {
+            if ($compiled_tags[$i] == '{strip}') {
+                $compiled_tags[$i] = '';
+                $strip = true;
+                /* remove leading whitespaces */
+                $text_blocks[$i + 1] = ltrim($text_blocks[$i + 1]);
+            }
+            if ($strip) {
+                /* strip all $text_blocks before the next '/strip' */
+                for ($j = $i + 1; $j < $for_max; $j++) {
+                    /* remove leading and trailing whitespaces of each line */
+                    $text_blocks[$j] = preg_replace('![\t ]*[\r\n]+[\t ]*!', '', $text_blocks[$j]);
+                    if ($compiled_tags[$j] == '{/strip}') {                       
+                        /* remove trailing whitespaces from the last text_block */
+                        $text_blocks[$j] = rtrim($text_blocks[$j]);
+                    }
+                    $text_blocks[$j] = "<?php echo '" . strtr($text_blocks[$j], array("'"=>"\'", "\\"=>"\\\\")) . "'; ?>";
+                    if ($compiled_tags[$j] == '{/strip}') {
+                        $compiled_tags[$j] = "\n"; /* slurped by php, but necessary
+                                    if a newline is following the closing strip-tag */
+                        $strip = false;
+                        $i = $j;
+                        break;
+                    }
+                }
+            }
+        }
+        $compiled_content = '';
+        
+        $tag_guard = '%%%SMARTYOTG' . md5(uniqid(rand(), true)) . '%%%';
+        
+        /* Interleave the compiled contents and text blocks to get the final result. */
+        for ($i = 0, $for_max = count($compiled_tags); $i < $for_max; $i++) {
+            if ($compiled_tags[$i] == '') {
+                // tag result empty, remove first newline from following text block
+                $text_blocks[$i+1] = preg_replace('~^(\r\n|\r|\n)~', '', $text_blocks[$i+1]);
+            }
+            // replace legit PHP tags with placeholder
+            $text_blocks[$i] = str_replace('<?', $tag_guard, $text_blocks[$i]);
+            $compiled_tags[$i] = str_replace('<?', $tag_guard, $compiled_tags[$i]);
+            
+            $compiled_content .= $text_blocks[$i] . $compiled_tags[$i];
+        }
+        $compiled_content .= str_replace('<?', $tag_guard, $text_blocks[$i]);
+
+        // escape php tags created by interleaving
+        $compiled_content = str_replace('<?', "<?php echo '<?' ?>\n", $compiled_content);
+        $compiled_content = preg_replace("~(?<!')language\s*=\s*[\"\']?\s*php\s*[\"\']?~", "<?php echo 'language=php' ?>\n", $compiled_content);
+
+        // recover legit tags
+        $compiled_content = str_replace($tag_guard, '<?', $compiled_content); 
+        
+        // remove \n from the end of the file, if any
+        if (strlen($compiled_content) && (substr($compiled_content, -1) == "\n") ) {
+            $compiled_content = substr($compiled_content, 0, -1);
+        }
+
+        if (!empty($this->_cache_serial)) {
+            $compiled_content = "<?php \$this->_cache_serials['".$this->_cache_include."'] = '".$this->_cache_serial."'; ?>" . $compiled_content;
+        }
+
+        // run compiled template through postfilter functions
+        if (count($this->_plugins['postfilter']) > 0) {
+            foreach ($this->_plugins['postfilter'] as $filter_name => $postfilter) {
+                if ($postfilter === false) continue;
+                if ($postfilter[3] || is_callable($postfilter[0])) {
+                    $compiled_content = call_user_func_array($postfilter[0],
+                                                              array($compiled_content, &$this));
+                    $this->_plugins['postfilter'][$filter_name][3] = true;
+                } else {
+                    $this->_trigger_fatal_error("Smarty plugin error: postfilter '$filter_name' is not implemented");
+                }
+            }
+        }
+
+        // put header at the top of the compiled template
+        $template_header = "<?php /* Smarty version ".$this->_version.", created on ".strftime("%Y-%m-%d %H:%M:%S")."\n";
+        $template_header .= "         compiled from ".strtr(urlencode($resource_name), array('%2F'=>'/', '%3A'=>':'))." */ ?>\n";
+
+        /* Emit code to load needed plugins. */
+        $this->_plugins_code = '';
+        if (count($this->_plugin_info)) {
+            $_plugins_params = "array('plugins' => array(";
+            foreach ($this->_plugin_info as $plugin_type => $plugins) {
+                foreach ($plugins as $plugin_name => $plugin_info) {
+                    $_plugins_params .= "array('$plugin_type', '$plugin_name', '" . strtr($plugin_info[0], array("'" => "\\'", "\\" => "\\\\")) . "', $plugin_info[1], ";
+                    $_plugins_params .= $plugin_info[2] ? 'true),' : 'false),';
+                }
+            }
+            $_plugins_params .= '))';
+            $plugins_code = "<?php require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');\nsmarty_core_load_plugins($_plugins_params, \$this); ?>\n";
+            $template_header .= $plugins_code;
+            $this->_plugin_info = array();
+            $this->_plugins_code = $plugins_code;
+        }
+
+        if ($this->_init_smarty_vars) {
+            $template_header .= "<?php require_once(SMARTY_CORE_DIR . 'core.assign_smarty_interface.php');\nsmarty_core_assign_smarty_interface(null, \$this); ?>\n";
+            $this->_init_smarty_vars = false;
+        }
+
+        $compiled_content = $template_header . $compiled_content;
+        return true;
+    }
+
+    /**
+     * Compile a template tag
+     *
+     * @param string $template_tag
+     * @return string
+     */
+    function _compile_tag($template_tag)
+    {
+        /* Matched comment. */
+        if (substr($template_tag, 0, 1) == '*' && substr($template_tag, -1) == '*')
+            return '';
+        
+        /* Split tag into two three parts: command, command modifiers and the arguments. */
+        if(! preg_match('~^(?:(' . $this->_num_const_regexp . '|' . $this->_obj_call_regexp . '|' . $this->_var_regexp
+                . '|\/?' . $this->_reg_obj_regexp . '|\/?' . $this->_func_regexp . ')(' . $this->_mod_regexp . '*))
+                      (?:\s+(.*))?$
+                    ~xs', $template_tag, $match)) {
+            $this->_syntax_error("unrecognized tag: $template_tag", E_USER_ERROR, __FILE__, __LINE__);
+        }
+        
+        $tag_command = $match[1];
+        $tag_modifier = isset($match[2]) ? $match[2] : null;
+        $tag_args = isset($match[3]) ? $match[3] : null;
+
+        if (preg_match('~^' . $this->_num_const_regexp . '|' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '$~', $tag_command)) {
+            /* tag name is a variable or object */
+            $_return = $this->_parse_var_props($tag_command . $tag_modifier);
+            return "<?php echo $_return; ?>" . $this->_additional_newline;
+        }
+
+        /* If the tag name is a registered object, we process it. */
+        if (preg_match('~^\/?' . $this->_reg_obj_regexp . '$~', $tag_command)) {
+            return $this->_compile_registered_object_tag($tag_command, $this->_parse_attrs($tag_args), $tag_modifier);
+        }
+
+        switch ($tag_command) {
+            case 'include':
+                return $this->_compile_include_tag($tag_args);
+
+            case 'include_php':
+                return $this->_compile_include_php_tag($tag_args);
+
+            case 'if':
+                $this->_push_tag('if');
+                return $this->_compile_if_tag($tag_args);
+
+            case 'else':
+                list($_open_tag) = end($this->_tag_stack);
+                if ($_open_tag != 'if' && $_open_tag != 'elseif')
+                    $this->_syntax_error('unexpected {else}', E_USER_ERROR, __FILE__, __LINE__);
+                else
+                    $this->_push_tag('else');
+                return '<?php else: ?>';
+
+            case 'elseif':
+                list($_open_tag) = end($this->_tag_stack);
+                if ($_open_tag != 'if' && $_open_tag != 'elseif')
+                    $this->_syntax_error('unexpected {elseif}', E_USER_ERROR, __FILE__, __LINE__);
+                if ($_open_tag == 'if')
+                    $this->_push_tag('elseif');
+                return $this->_compile_if_tag($tag_args, true);
+
+            case '/if':
+                $this->_pop_tag('if');
+                return '<?php endif; ?>';
+
+            case 'capture':
+                return $this->_compile_capture_tag(true, $tag_args);
+
+            case '/capture':
+                return $this->_compile_capture_tag(false);
+
+            case 'ldelim':
+                return $this->left_delimiter;
+
+            case 'rdelim':
+                return $this->right_delimiter;
+
+            case 'section':
+                $this->_push_tag('section');
+                return $this->_compile_section_start($tag_args);
+
+            case 'sectionelse':
+                $this->_push_tag('sectionelse');
+                return "<?php endfor; else: ?>";
+                break;
+
+            case '/section':
+                $_open_tag = $this->_pop_tag('section');
+                if ($_open_tag == 'sectionelse')
+                    return "<?php endif; ?>";
+                else
+                    return "<?php endfor; endif; ?>";
+
+            case 'foreach':
+                $this->_push_tag('foreach');
+                return $this->_compile_foreach_start($tag_args);
+                break;
+
+            case 'foreachelse':
+                $this->_push_tag('foreachelse');
+                return "<?php endforeach; else: ?>";
+
+            case '/foreach':
+                $_open_tag = $this->_pop_tag('foreach');
+                if ($_open_tag == 'foreachelse')
+                    return "<?php endif; unset(\$_from); ?>";
+                else
+                    return "<?php endforeach; endif; unset(\$_from); ?>";
+                break;
+
+            case 'strip':
+            case '/strip':
+                if (substr($tag_command, 0, 1)=='/') {
+                    $this->_pop_tag('strip');
+                    if (--$this->_strip_depth==0) { /* outermost closing {/strip} */
+                        $this->_additional_newline = "\n";
+                        return '{' . $tag_command . '}';
+                    }
+                } else {
+                    $this->_push_tag('strip');
+                    if ($this->_strip_depth++==0) { /* outermost opening {strip} */
+                        $this->_additional_newline = "";
+                        return '{' . $tag_command . '}';
+                    }
+                }
+                return '';
+
+            case 'php':
+                /* handle folded tags replaced by {php} */
+                list(, $block) = each($this->_folded_blocks);
+                $this->_current_line_no += substr_count($block[0], "\n");
+                /* the number of matched elements in the regexp in _compile_file()
+                   determins the type of folded tag that was found */
+                switch (count($block)) {
+                    case 2: /* comment */
+                        return '';
+
+                    case 3: /* literal */
+                        return "<?php echo '" . strtr($block[2], array("'"=>"\'", "\\"=>"\\\\")) . "'; ?>" . $this->_additional_newline;
+
+                    case 4: /* php */
+                        if ($this->security && !$this->security_settings['PHP_TAGS']) {
+                            $this->_syntax_error("(secure mode) php tags not permitted", E_USER_WARNING, __FILE__, __LINE__);
+                            return;
+                        }
+                        return '<?php ' . $block[3] .' ?>';
+                }
+                break;
+
+            case 'insert':
+                return $this->_compile_insert_tag($tag_args);
+
+            default:
+                if ($this->_compile_compiler_tag($tag_command, $tag_args, $output)) {
+                    return $output;
+                } else if ($this->_compile_block_tag($tag_command, $tag_args, $tag_modifier, $output)) {
+                    return $output;
+                } else if ($this->_compile_custom_tag($tag_command, $tag_args, $tag_modifier, $output)) {
+                    return $output;                    
+                } else {
+                    $this->_syntax_error("unrecognized tag '$tag_command'", E_USER_ERROR, __FILE__, __LINE__);
+                }
+
+        }
+    }
+
+
+    /**
+     * compile the custom compiler tag
+     *
+     * sets $output to the compiled custom compiler tag
+     * @param string $tag_command
+     * @param string $tag_args
+     * @param string $output
+     * @return boolean
+     */
+    function _compile_compiler_tag($tag_command, $tag_args, &$output)
+    {
+        $found = false;
+        $have_function = true;
+
+        /*
+         * First we check if the compiler function has already been registered
+         * or loaded from a plugin file.
+         */
+        if (isset($this->_plugins['compiler'][$tag_command])) {
+            $found = true;
+            $plugin_func = $this->_plugins['compiler'][$tag_command][0];
+            if (!is_callable($plugin_func)) {
+                $message = "compiler function '$tag_command' is not implemented";
+                $have_function = false;
+            }
+        }
+        /*
+         * Otherwise we need to load plugin file and look for the function
+         * inside it.
+         */
+        else if ($plugin_file = $this->_get_plugin_filepath('compiler', $tag_command)) {
+            $found = true;
+
+            include_once $plugin_file;
+
+            $plugin_func = 'smarty_compiler_' . $tag_command;
+            if (!is_callable($plugin_func)) {
+                $message = "plugin function $plugin_func() not found in $plugin_file\n";
+                $have_function = false;
+            } else {
+                $this->_plugins['compiler'][$tag_command] = array($plugin_func, null, null, null, true);
+            }
+        }
+
+        /*
+         * True return value means that we either found a plugin or a
+         * dynamically registered function. False means that we didn't and the
+         * compiler should now emit code to load custom function plugin for this
+         * tag.
+         */
+        if ($found) {
+            if ($have_function) {
+                $output = call_user_func_array($plugin_func, array($tag_args, &$this));
+                if($output != '') {
+                $output = '<?php ' . $this->_push_cacheable_state('compiler', $tag_command)
+                                   . $output
+                                   . $this->_pop_cacheable_state('compiler', $tag_command) . ' ?>';
+                }
+            } else {
+                $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__);
+            }
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+
+    /**
+     * compile block function tag
+     *
+     * sets $output to compiled block function tag
+     * @param string $tag_command
+     * @param string $tag_args
+     * @param string $tag_modifier
+     * @param string $output
+     * @return boolean
+     */
+    function _compile_block_tag($tag_command, $tag_args, $tag_modifier, &$output)
+    {
+        if (substr($tag_command, 0, 1) == '/') {
+            $start_tag = false;
+            $tag_command = substr($tag_command, 1);
+        } else
+            $start_tag = true;
+
+        $found = false;
+        $have_function = true;
+
+        /*
+         * First we check if the block function has already been registered
+         * or loaded from a plugin file.
+         */
+        if (isset($this->_plugins['block'][$tag_command])) {
+            $found = true;
+            $plugin_func = $this->_plugins['block'][$tag_command][0];
+            if (!is_callable($plugin_func)) {
+                $message = "block function '$tag_command' is not implemented";
+                $have_function = false;
+            }
+        }
+        /*
+         * Otherwise we need to load plugin file and look for the function
+         * inside it.
+         */
+        else if ($plugin_file = $this->_get_plugin_filepath('block', $tag_command)) {
+            $found = true;
+
+            include_once $plugin_file;
+
+            $plugin_func = 'smarty_block_' . $tag_command;
+            if (!function_exists($plugin_func)) {
+                $message = "plugin function $plugin_func() not found in $plugin_file\n";
+                $have_function = false;
+            } else {
+                $this->_plugins['block'][$tag_command] = array($plugin_func, null, null, null, true);
+
+            }
+        }
+
+        if (!$found) {
+            return false;
+        } else if (!$have_function) {
+            $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__);
+            return true;
+        }
+
+        /*
+         * Even though we've located the plugin function, compilation
+         * happens only once, so the plugin will still need to be loaded
+         * at runtime for future requests.
+         */
+        $this->_add_plugin('block', $tag_command);
+
+        if ($start_tag)
+            $this->_push_tag($tag_command);
+        else
+            $this->_pop_tag($tag_command);
+
+        if ($start_tag) {
+            $output = '<?php ' . $this->_push_cacheable_state('block', $tag_command);
+            $attrs = $this->_parse_attrs($tag_args);
+            $_cache_attrs='';
+            $arg_list = $this->_compile_arg_list('block', $tag_command, $attrs, $_cache_attrs);
+            $output .= "$_cache_attrs\$this->_tag_stack[] = array('$tag_command', array(".implode(',', $arg_list).')); ';
+            $output .= '$_block_repeat=true;' . $this->_compile_plugin_call('block', $tag_command).'($this->_tag_stack[count($this->_tag_stack)-1][1], null, $this, $_block_repeat);';
+            $output .= 'while ($_block_repeat) { ob_start(); ?>';
+        } else {
+            $output = '<?php $_block_content = ob_get_contents(); ob_end_clean(); ';
+            $_out_tag_text = $this->_compile_plugin_call('block', $tag_command).'($this->_tag_stack[count($this->_tag_stack)-1][1], $_block_content, $this, $_block_repeat)';
+            if ($tag_modifier != '') {
+                $this->_parse_modifiers($_out_tag_text, $tag_modifier);
+            }
+            $output .= '$_block_repeat=false;echo ' . $_out_tag_text . '; } ';
+            $output .= " array_pop(\$this->_tag_stack); " . $this->_pop_cacheable_state('block', $tag_command) . '?>';
+        }
+
+        return true;
+    }
+
+
+    /**
+     * compile custom function tag
+     *
+     * @param string $tag_command
+     * @param string $tag_args
+     * @param string $tag_modifier
+     * @return string
+     */
+    function _compile_custom_tag($tag_command, $tag_args, $tag_modifier, &$output)
+    {
+        $found = false;
+        $have_function = true;
+
+        /*
+         * First we check if the custom function has already been registered
+         * or loaded from a plugin file.
+         */
+        if (isset($this->_plugins['function'][$tag_command])) {
+            $found = true;
+            $plugin_func = $this->_plugins['function'][$tag_command][0];
+            if (!is_callable($plugin_func)) {
+                $message = "custom function '$tag_command' is not implemented";
+                $have_function = false;
+            }
+        }
+        /*
+         * Otherwise we need to load plugin file and look for the function
+         * inside it.
+         */
+        else if ($plugin_file = $this->_get_plugin_filepath('function', $tag_command)) {
+            $found = true;
+
+            include_once $plugin_file;
+
+            $plugin_func = 'smarty_function_' . $tag_command;
+            if (!function_exists($plugin_func)) {
+                $message = "plugin function $plugin_func() not found in $plugin_file\n";
+                $have_function = false;
+            } else {
+                $this->_plugins['function'][$tag_command] = array($plugin_func, null, null, null, true);
+
+            }
+        }
+
+        if (!$found) {
+            return false;
+        } else if (!$have_function) {
+            $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__);
+            return true;
+        }
+
+        /* declare plugin to be loaded on display of the template that
+           we compile right now */
+        $this->_add_plugin('function', $tag_command);
+
+        $_cacheable_state = $this->_push_cacheable_state('function', $tag_command);
+        $attrs = $this->_parse_attrs($tag_args);
+        $_cache_attrs = '';
+        $arg_list = $this->_compile_arg_list('function', $tag_command, $attrs, $_cache_attrs);
+
+        $output = $this->_compile_plugin_call('function', $tag_command).'(array('.implode(',', $arg_list)."), \$this)";
+        if($tag_modifier != '') {
+            $this->_parse_modifiers($output, $tag_modifier);
+        }
+
+        if($output != '') {
+            $output =  '<?php ' . $_cacheable_state . $_cache_attrs . 'echo ' . $output . ';'
+                . $this->_pop_cacheable_state('function', $tag_command) . "?>" . $this->_additional_newline;
+        }
+
+        return true;
+    }
+
+    /**
+     * compile a registered object tag
+     *
+     * @param string $tag_command
+     * @param array $attrs
+     * @param string $tag_modifier
+     * @return string
+     */
+    function _compile_registered_object_tag($tag_command, $attrs, $tag_modifier)
+    {
+        if (substr($tag_command, 0, 1) == '/') {
+            $start_tag = false;
+            $tag_command = substr($tag_command, 1);
+        } else {
+            $start_tag = true;
+        }
+
+        list($object, $obj_comp) = explode('->', $tag_command);
+
+        $arg_list = array();
+        if(count($attrs)) {
+            $_assign_var = false;
+            foreach ($attrs as $arg_name => $arg_value) {
+                if($arg_name == 'assign') {
+                    $_assign_var = $arg_value;
+                    unset($attrs['assign']);
+                    continue;
+                }
+                if (is_bool($arg_value))
+                    $arg_value = $arg_value ? 'true' : 'false';
+                $arg_list[] = "'$arg_name' => $arg_value";
+            }
+        }
+
+        if($this->_reg_objects[$object][2]) {
+            // smarty object argument format
+            $args = "array(".implode(',', (array)$arg_list)."), \$this";
+        } else {
+            // traditional argument format
+            $args = implode(',', array_values($attrs));
+            if (empty($args)) {
+                $args = '';
+            }
+        }
+
+        $prefix = '';
+        $postfix = '';
+        $newline = '';
+        if(!is_object($this->_reg_objects[$object][0])) {
+            $this->_trigger_fatal_error("registered '$object' is not an object" , $this->_current_file, $this->_current_line_no, __FILE__, __LINE__);
+        } elseif(!empty($this->_reg_objects[$object][1]) && !in_array($obj_comp, $this->_reg_objects[$object][1])) {
+            $this->_trigger_fatal_error("'$obj_comp' is not a registered component of object '$object'", $this->_current_file, $this->_current_line_no, __FILE__, __LINE__);
+        } elseif(method_exists($this->_reg_objects[$object][0], $obj_comp)) {
+            // method
+            if(in_array($obj_comp, $this->_reg_objects[$object][3])) {
+                // block method
+                if ($start_tag) {
+                    $prefix = "\$this->_tag_stack[] = array('$obj_comp', $args); ";
+                    $prefix .= "\$_block_repeat=true; \$this->_reg_objects['$object'][0]->$obj_comp(\$this->_tag_stack[count(\$this->_tag_stack)-1][1], null, \$this, \$_block_repeat); ";
+                    $prefix .= "while (\$_block_repeat) { ob_start();";
+                    $return = null;
+                    $postfix = '';
+                } else {
+                    $prefix = "\$_obj_block_content = ob_get_contents(); ob_end_clean(); \$_block_repeat=false;";
+                    $return = "\$this->_reg_objects['$object'][0]->$obj_comp(\$this->_tag_stack[count(\$this->_tag_stack)-1][1], \$_obj_block_content, \$this, \$_block_repeat)";
+                    $postfix = "} array_pop(\$this->_tag_stack);";
+                }
+            } else {
+                // non-block method
+                $return = "\$this->_reg_objects['$object'][0]->$obj_comp($args)";
+            }
+        } else {
+            // property
+            $return = "\$this->_reg_objects['$object'][0]->$obj_comp";
+        }
+
+        if($return != null) {
+            if($tag_modifier != '') {
+                $this->_parse_modifiers($return, $tag_modifier);
+            }
+
+            if(!empty($_assign_var)) {
+                $output = "\$this->assign('" . $this->_dequote($_assign_var) ."',  $return);";
+            } else {
+                $output = 'echo ' . $return . ';';
+                $newline = $this->_additional_newline;
+            }
+        } else {
+            $output = '';
+        }
+
+        return '<?php ' . $prefix . $output . $postfix . "?>" . $newline;
+    }
+
+    /**
+     * Compile {insert ...} tag
+     *
+     * @param string $tag_args
+     * @return string
+     */
+    function _compile_insert_tag($tag_args)
+    {
+        $attrs = $this->_parse_attrs($tag_args);
+        $name = $this->_dequote($attrs['name']);
+
+        if (empty($name)) {
+            return $this->_syntax_error("missing insert name", E_USER_ERROR, __FILE__, __LINE__);
+        }
+        
+        if (!preg_match('~^\w+$~', $name)) {
+            return $this->_syntax_error("'insert: 'name' must be an insert function name", E_USER_ERROR, __FILE__, __LINE__);
+        }
+
+        if (!empty($attrs['script'])) {
+            $delayed_loading = true;
+        } else {
+            $delayed_loading = false;
+        }
+
+        foreach ($attrs as $arg_name => $arg_value) {
+            if (is_bool($arg_value))
+                $arg_value = $arg_value ? 'true' : 'false';
+            $arg_list[] = "'$arg_name' => $arg_value";
+        }
+
+        $this->_add_plugin('insert', $name, $delayed_loading);
+
+        $_params = "array('args' => array(".implode(', ', (array)$arg_list)."))";
+
+        return "<?php require_once(SMARTY_CORE_DIR . 'core.run_insert_handler.php');\necho smarty_core_run_insert_handler($_params, \$this); ?>" . $this->_additional_newline;
+    }
+
+    /**
+     * Compile {include ...} tag
+     *
+     * @param string $tag_args
+     * @return string
+     */
+    function _compile_include_tag($tag_args)
+    {
+        $attrs = $this->_parse_attrs($tag_args);
+        $arg_list = array();
+
+        if (empty($attrs['file'])) {
+            $this->_syntax_error("missing 'file' attribute in include tag", E_USER_ERROR, __FILE__, __LINE__);
+        }
+
+        foreach ($attrs as $arg_name => $arg_value) {
+            if ($arg_name == 'file') {
+                $include_file = $arg_value;
+                continue;
+            } else if ($arg_name == 'assign') {
+                $assign_var = $arg_value;
+                continue;
+            }
+            if (is_bool($arg_value))
+                $arg_value = $arg_value ? 'true' : 'false';
+            $arg_list[] = "'$arg_name' => $arg_value";
+        }
+
+        $output = '<?php ';
+
+        if (isset($assign_var)) {
+            $output .= "ob_start();\n";
+        }
+
+        $output .=
+            "\$_smarty_tpl_vars = \$this->_tpl_vars;\n";
+
+
+        $_params = "array('smarty_include_tpl_file' => " . $include_file . ", 'smarty_include_vars' => array(".implode(',', (array)$arg_list)."))";
+        $output .= "\$this->_smarty_include($_params);\n" .
+        "\$this->_tpl_vars = \$_smarty_tpl_vars;\n" .
+        "unset(\$_smarty_tpl_vars);\n";
+
+        if (isset($assign_var)) {
+            $output .= "\$this->assign(" . $assign_var . ", ob_get_contents()); ob_end_clean();\n";
+        }
+
+        $output .= ' ?>';
+
+        return $output;
+
+    }
+
+    /**
+     * Compile {include ...} tag
+     *
+     * @param string $tag_args
+     * @return string
+     */
+    function _compile_include_php_tag($tag_args)
+    {
+        $attrs = $this->_parse_attrs($tag_args);
+
+        if (empty($attrs['file'])) {
+            $this->_syntax_error("missing 'file' attribute in include_php tag", E_USER_ERROR, __FILE__, __LINE__);
+        }
+
+        $assign_var = (empty($attrs['assign'])) ? '' : $this->_dequote($attrs['assign']);
+        $once_var = (empty($attrs['once']) || $attrs['once']=='false') ? 'false' : 'true';
+
+        $arg_list = array();
+        foreach($attrs as $arg_name => $arg_value) {
+            if($arg_name != 'file' AND $arg_name != 'once' AND $arg_name != 'assign') {
+                if(is_bool($arg_value))
+                    $arg_value = $arg_value ? 'true' : 'false';
+                $arg_list[] = "'$arg_name' => $arg_value";
+            }
+        }
+
+        $_params = "array('smarty_file' => " . $attrs['file'] . ", 'smarty_assign' => '$assign_var', 'smarty_once' => $once_var, 'smarty_include_vars' => array(".implode(',', $arg_list)."))";
+
+        return "<?php require_once(SMARTY_CORE_DIR . 'core.smarty_include_php.php');\nsmarty_core_smarty_include_php($_params, \$this); ?>" . $this->_additional_newline;
+    }
+
+
+    /**
+     * Compile {section ...} tag
+     *
+     * @param string $tag_args
+     * @return string
+     */
+    function _compile_section_start($tag_args)
+    {
+        $attrs = $this->_parse_attrs($tag_args);
+        $arg_list = array();
+
+        $output = '<?php ';
+        $section_name = $attrs['name'];
+        if (empty($section_name)) {
+            $this->_syntax_error("missing section name", E_USER_ERROR, __FILE__, __LINE__);
+        }
+
+        $output .= "unset(\$this->_sections[$section_name]);\n";
+        $section_props = "\$this->_sections[$section_name]";
+
+        foreach ($attrs as $attr_name => $attr_value) {
+            switch ($attr_name) {
+                case 'loop':
+                    $output .= "{$section_props}['loop'] = is_array(\$_loop=$attr_value) ? count(\$_loop) : max(0, (int)\$_loop); unset(\$_loop);\n";
+                    break;
+
+                case 'show':
+                    if (is_bool($attr_value))
+                        $show_attr_value = $attr_value ? 'true' : 'false';
+                    else
+                        $show_attr_value = "(bool)$attr_value";
+                    $output .= "{$section_props}['show'] = $show_attr_value;\n";
+                    break;
+
+                case 'name':
+                    $output .= "{$section_props}['$attr_name'] = $attr_value;\n";
+                    break;
+
+                case 'max':
+                case 'start':
+                    $output .= "{$section_props}['$attr_name'] = (int)$attr_value;\n";
+                    break;
+
+                case 'step':
+                    $output .= "{$section_props}['$attr_name'] = ((int)$attr_value) == 0 ? 1 : (int)$attr_value;\n";
+                    break;
+
+                default:
+                    $this->_syntax_error("unknown section attribute - '$attr_name'", E_USER_ERROR, __FILE__, __LINE__);
+                    break;
+            }
+        }
+
+        if (!isset($attrs['show']))
+            $output .= "{$section_props}['show'] = true;\n";
+
+        if (!isset($attrs['loop']))
+            $output .= "{$section_props}['loop'] = 1;\n";
+
+        if (!isset($attrs['max']))
+            $output .= "{$section_props}['max'] = {$section_props}['loop'];\n";
+        else
+            $output .= "if ({$section_props}['max'] < 0)\n" .
+                       "    {$section_props}['max'] = {$section_props}['loop'];\n";
+
+        if (!isset($attrs['step']))
+            $output .= "{$section_props}['step'] = 1;\n";
+
+        if (!isset($attrs['start']))
+            $output .= "{$section_props}['start'] = {$section_props}['step'] > 0 ? 0 : {$section_props}['loop']-1;\n";
+        else {
+            $output .= "if ({$section_props}['start'] < 0)\n" .
+                       "    {$section_props}['start'] = max({$section_props}['step'] > 0 ? 0 : -1, {$section_props}['loop'] + {$section_props}['start']);\n" .
+                       "else\n" .
+                       "    {$section_props}['start'] = min({$section_props}['start'], {$section_props}['step'] > 0 ? {$section_props}['loop'] : {$section_props}['loop']-1);\n";
+        }
+
+        $output .= "if ({$section_props}['show']) {\n";
+        if (!isset($attrs['start']) && !isset($attrs['step']) && !isset($attrs['max'])) {
+            $output .= "    {$section_props}['total'] = {$section_props}['loop'];\n";
+        } else {
+            $output .= "    {$section_props}['total'] = min(ceil(({$section_props}['step'] > 0 ? {$section_props}['loop'] - {$section_props}['start'] : {$section_props}['start']+1)/abs({$section_props}['step'])), {$section_props}['max']);\n";
+        }
+        $output .= "    if ({$section_props}['total'] == 0)\n" .
+                   "        {$section_props}['show'] = false;\n" .
+                   "} else\n" .
+                   "    {$section_props}['total'] = 0;\n";
+
+        $output .= "if ({$section_props}['show']):\n";
+        $output .= "
+            for ({$section_props}['index'] = {$section_props}['start'], {$section_props}['iteration'] = 1;
+                 {$section_props}['iteration'] <= {$section_props}['total'];
+                 {$section_props}['index'] += {$section_props}['step'], {$section_props}['iteration']++):\n";
+        $output .= "{$section_props}['rownum'] = {$section_props}['iteration'];\n";
+        $output .= "{$section_props}['index_prev'] = {$section_props}['index'] - {$section_props}['step'];\n";
+        $output .= "{$section_props}['index_next'] = {$section_props}['index'] + {$section_props}['step'];\n";
+        $output .= "{$section_props}['first']      = ({$section_props}['iteration'] == 1);\n";
+        $output .= "{$section_props}['last']       = ({$section_props}['iteration'] == {$section_props}['total']);\n";
+
+        $output .= "?>";
+
+        return $output;
+    }
+
+
+    /**
+     * Compile {foreach ...} tag.
+     *
+     * @param string $tag_args
+     * @return string
+     */
+    function _compile_foreach_start($tag_args)
+    {
+        $attrs = $this->_parse_attrs($tag_args);
+        $arg_list = array();
+
+        if (empty($attrs['from'])) {
+            return $this->_syntax_error("foreach: missing 'from' attribute", E_USER_ERROR, __FILE__, __LINE__);
+        }
+        $from = $attrs['from'];
+
+        if (empty($attrs['item'])) {
+            return $this->_syntax_error("foreach: missing 'item' attribute", E_USER_ERROR, __FILE__, __LINE__);
+        }
+        $item = $this->_dequote($attrs['item']);
+        if (!preg_match('~^\w+$~', $item)) {
+            return $this->_syntax_error("foreach: 'item' must be a variable name (literal string)", E_USER_ERROR, __FILE__, __LINE__);
+        }
+
+        if (isset($attrs['key'])) {
+            $key  = $this->_dequote($attrs['key']);
+            if (!preg_match('~^\w+$~', $key)) {
+                return $this->_syntax_error("foreach: 'key' must to be a variable name (literal string)", E_USER_ERROR, __FILE__, __LINE__);
+            }
+            $key_part = "\$this->_tpl_vars['$key'] => ";
+        } else {
+            $key = null;
+            $key_part = '';
+        }
+
+        if (isset($attrs['name'])) {
+            $name = $attrs['name'];
+        } else {
+            $name = null;
+        }
+
+        $output = '<?php ';
+        $output .= "\$_from = $from; if (!is_array(\$_from) && !is_object(\$_from)) { settype(\$_from, 'array'); }";
+        if (isset($name)) {
+            $foreach_props = "\$this->_foreach[$name]";
+            $output .= "{$foreach_props} = array('total' => count(\$_from), 'iteration' => 0);\n";
+            $output .= "if ({$foreach_props}['total'] > 0):\n";
+            $output .= "    foreach (\$_from as $key_part\$this->_tpl_vars['$item']):\n";
+            $output .= "        {$foreach_props}['iteration']++;\n";
+        } else {
+            $output .= "if (count(\$_from)):\n";
+            $output .= "    foreach (\$_from as $key_part\$this->_tpl_vars['$item']):\n";
+        }
+        $output .= '?>';
+
+        return $output;
+    }
+
+
+    /**
+     * Compile {capture} .. {/capture} tags
+     *
+     * @param boolean $start true if this is the {capture} tag
+     * @param string $tag_args
+     * @return string
+     */
+
+    function _compile_capture_tag($start, $tag_args = '')
+    {
+        $attrs = $this->_parse_attrs($tag_args);
+
+        if ($start) {
+            $buffer = isset($attrs['name']) ? $attrs['name'] : "'default'";
+            $assign = isset($attrs['assign']) ? $attrs['assign'] : null;
+            $append = isset($attrs['append']) ? $attrs['append'] : null;
+            
+            $output = "<?php ob_start(); ?>";
+            $this->_capture_stack[] = array($buffer, $assign, $append);
+        } else {
+            list($buffer, $assign, $append) = array_pop($this->_capture_stack);
+            $output = "<?php \$this->_smarty_vars['capture'][$buffer] = ob_get_contents(); ";
+            if (isset($assign)) {
+                $output .= " \$this->assign($assign, ob_get_contents());";
+            }
+            if (isset($append)) {
+                $output .= " \$this->append($append, ob_get_contents());";
+            }
+            $output .= "ob_end_clean(); ?>";
+        }
+
+        return $output;
+    }
+
+    /**
+     * Compile {if ...} tag
+     *
+     * @param string $tag_args
+     * @param boolean $elseif if true, uses elseif instead of if
+     * @return string
+     */
+    function _compile_if_tag($tag_args, $elseif = false)
+    {
+
+        /* Tokenize args for 'if' tag. */
+        preg_match_all('~(?>
+                ' . $this->_obj_call_regexp . '(?:' . $this->_mod_regexp . '*)? | # valid object call
+                ' . $this->_var_regexp . '(?:' . $this->_mod_regexp . '*)?    | # var or quoted string
+                \-?0[xX][0-9a-fA-F]+|\-?\d+(?:\.\d+)?|\.\d+|!==|===|==|!=|<>|<<|>>|<=|>=|\&\&|\|\||\(|\)|,|\!|\^|=|\&|\~|<|>|\||\%|\+|\-|\/|\*|\@    | # valid non-word token
+                \b\w+\b                                                        | # valid word token
+                \S+                                                           # anything else
+                )~x', $tag_args, $match);
+
+        $tokens = $match[0];
+
+        if(empty($tokens)) {
+            $_error_msg = $elseif ? "'elseif'" : "'if'";
+            $_error_msg .= ' statement requires arguments'; 
+            $this->_syntax_error($_error_msg, E_USER_ERROR, __FILE__, __LINE__);
+        }
+            
+                
+        // make sure we have balanced parenthesis
+        $token_count = array_count_values($tokens);
+        if(isset($token_count['(']) && $token_count['('] != $token_count[')']) {
+            $this->_syntax_error("unbalanced parenthesis in if statement", E_USER_ERROR, __FILE__, __LINE__);
+        }
+
+        $is_arg_stack = array();
+
+        for ($i = 0; $i < count($tokens); $i++) {
+
+            $token = &$tokens[$i];
+
+            switch (strtolower($token)) {
+                case '!':
+                case '%':
+                case '!==':
+                case '==':
+                case '===':
+                case '>':
+                case '<':
+                case '!=':
+                case '<>':
+                case '<<':
+                case '>>':
+                case '<=':
+                case '>=':
+                case '&&':
+                case '||':
+                case '|':
+                case '^':
+                case '&':
+                case '~':
+                case ')':
+                case ',':
+                case '+':
+                case '-':
+                case '*':
+                case '/':
+                case '@':
+                    break;
+
+                case 'eq':
+                    $token = '==';
+                    break;
+
+                case 'ne':
+                case 'neq':
+                    $token = '!=';
+                    break;
+
+                case 'lt':
+                    $token = '<';
+                    break;
+
+                case 'le':
+                case 'lte':
+                    $token = '<=';
+                    break;
+
+                case 'gt':
+                    $token = '>';
+                    break;
+
+                case 'ge':
+                case 'gte':
+                    $token = '>=';
+                    break;
+
+                case 'and':
+                    $token = '&&';
+                    break;
+
+                case 'or':
+                    $token = '||';
+                    break;
+
+                case 'not':
+                    $token = '!';
+                    break;
+
+                case 'mod':
+                    $token = '%';
+                    break;
+
+                case '(':
+                    array_push($is_arg_stack, $i);
+                    break;
+
+                case 'is':
+                    /* If last token was a ')', we operate on the parenthesized
+                       expression. The start of the expression is on the stack.
+                       Otherwise, we operate on the last encountered token. */
+                    if ($tokens[$i-1] == ')') {
+                        $is_arg_start = array_pop($is_arg_stack);
+                        if ($is_arg_start != 0) {
+                            if (preg_match('~^' . $this->_func_regexp . '$~', $tokens[$is_arg_start-1])) {
+                                $is_arg_start--;
+                            } 
+                        } 
+                    } else
+                        $is_arg_start = $i-1;
+                    /* Construct the argument for 'is' expression, so it knows
+                       what to operate on. */
+                    $is_arg = implode(' ', array_slice($tokens, $is_arg_start, $i - $is_arg_start));
+
+                    /* Pass all tokens from next one until the end to the
+                       'is' expression parsing function. The function will
+                       return modified tokens, where the first one is the result
+                       of the 'is' expression and the rest are the tokens it
+                       didn't touch. */
+                    $new_tokens = $this->_parse_is_expr($is_arg, array_slice($tokens, $i+1));
+
+                    /* Replace the old tokens with the new ones. */
+                    array_splice($tokens, $is_arg_start, count($tokens), $new_tokens);
+
+                    /* Adjust argument start so that it won't change from the
+                       current position for the next iteration. */
+                    $i = $is_arg_start;
+                    break;
+
+                default:
+                    if(preg_match('~^' . $this->_func_regexp . '$~', $token) ) {
+                            // function call
+                            if($this->security &&
+                               !in_array($token, $this->security_settings['IF_FUNCS'])) {
+                                $this->_syntax_error("(secure mode) '$token' not allowed in if statement", E_USER_ERROR, __FILE__, __LINE__);
+                            }
+                    } elseif(preg_match('~^' . $this->_var_regexp . '$~', $token) && (strpos('+-*/^%&|', substr($token, -1)) === false) && isset($tokens[$i+1]) && $tokens[$i+1] == '(') {
+                        // variable function call
+                        $this->_syntax_error("variable function call '$token' not allowed in if statement", E_USER_ERROR, __FILE__, __LINE__);                      
+                    } elseif(preg_match('~^' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '(?:' . $this->_mod_regexp . '*)$~', $token)) {
+                        // object or variable
+                        $token = $this->_parse_var_props($token);
+                    } elseif(is_numeric($token)) {
+                        // number, skip it
+                    } else {
+                        $this->_syntax_error("unidentified token '$token'", E_USER_ERROR, __FILE__, __LINE__);
+                    }
+                    break;
+            }
+        }
+
+        if ($elseif)
+            return '<?php elseif ('.implode(' ', $tokens).'): ?>';
+        else
+            return '<?php if ('.implode(' ', $tokens).'): ?>';
+    }
+
+
+    function _compile_arg_list($type, $name, $attrs, &$cache_code) {
+        $arg_list = array();
+
+        if (isset($type) && isset($name)
+            && isset($this->_plugins[$type])
+            && isset($this->_plugins[$type][$name])
+            && empty($this->_plugins[$type][$name][4])
+            && is_array($this->_plugins[$type][$name][5])
+            ) {
+            /* we have a list of parameters that should be cached */
+            $_cache_attrs = $this->_plugins[$type][$name][5];
+            $_count = $this->_cache_attrs_count++;
+            $cache_code = "\$_cache_attrs =& \$this->_smarty_cache_attrs('$this->_cache_serial','$_count');";
+
+        } else {
+            /* no parameters are cached */
+            $_cache_attrs = null;
+        }
+
+        foreach ($attrs as $arg_name => $arg_value) {
+            if (is_bool($arg_value))
+                $arg_value = $arg_value ? 'true' : 'false';
+            if (is_null($arg_value))
+                $arg_value = 'null';
+            if ($_cache_attrs && in_array($arg_name, $_cache_attrs)) {
+                $arg_list[] = "'$arg_name' => (\$this->_cache_including) ? \$_cache_attrs['$arg_name'] : (\$_cache_attrs['$arg_name']=$arg_value)";
+            } else {
+                $arg_list[] = "'$arg_name' => $arg_value";
+            }
+        }
+        return $arg_list;
+    }
+
+    /**
+     * Parse is expression
+     *
+     * @param string $is_arg
+     * @param array $tokens
+     * @return array
+     */
+    function _parse_is_expr($is_arg, $tokens)
+    {
+        $expr_end = 0;
+        $negate_expr = false;
+
+        if (($first_token = array_shift($tokens)) == 'not') {
+            $negate_expr = true;
+            $expr_type = array_shift($tokens);
+        } else
+            $expr_type = $first_token;
+
+        switch ($expr_type) {
+            case 'even':
+                if (isset($tokens[$expr_end]) && $tokens[$expr_end] == 'by') {
+                    $expr_end++;
+                    $expr_arg = $tokens[$expr_end++];
+                    $expr = "!(1 & ($is_arg / " . $this->_parse_var_props($expr_arg) . "))";
+                } else
+                    $expr = "!(1 & $is_arg)";
+                break;
+
+            case 'odd':
+                if (isset($tokens[$expr_end]) && $tokens[$expr_end] == 'by') {
+                    $expr_end++;
+                    $expr_arg = $tokens[$expr_end++];
+                    $expr = "(1 & ($is_arg / " . $this->_parse_var_props($expr_arg) . "))";
+                } else
+                    $expr = "(1 & $is_arg)";
+                break;
+
+            case 'div':
+                if (@$tokens[$expr_end] == 'by') {
+                    $expr_end++;
+                    $expr_arg = $tokens[$expr_end++];
+                    $expr = "!($is_arg % " . $this->_parse_var_props($expr_arg) . ")";
+                } else {
+                    $this->_syntax_error("expecting 'by' after 'div'", E_USER_ERROR, __FILE__, __LINE__);
+                }
+                break;
+
+            default:
+                $this->_syntax_error("unknown 'is' expression - '$expr_type'", E_USER_ERROR, __FILE__, __LINE__);
+                break;
+        }
+
+        if ($negate_expr) {
+            $expr = "!($expr)";
+        }
+
+        array_splice($tokens, 0, $expr_end, $expr);
+
+        return $tokens;
+    }
+
+
+    /**
+     * Parse attribute string
+     *
+     * @param string $tag_args
+     * @return array
+     */
+    function _parse_attrs($tag_args)
+    {
+
+        /* Tokenize tag attributes. */
+        preg_match_all('~(?:' . $this->_obj_call_regexp . '|' . $this->_qstr_regexp . ' | (?>[^"\'=\s]+)
+                         )+ |
+                         [=]
+                        ~x', $tag_args, $match);
+        $tokens       = $match[0];
+
+        $attrs = array();
+        /* Parse state:
+            0 - expecting attribute name
+            1 - expecting '='
+            2 - expecting attribute value (not '=') */
+        $state = 0;
+
+        foreach ($tokens as $token) {
+            switch ($state) {
+                case 0:
+                    /* If the token is a valid identifier, we set attribute name
+                       and go to state 1. */
+                    if (preg_match('~^\w+$~', $token)) {
+                        $attr_name = $token;
+                        $state = 1;
+                    } else
+                        $this->_syntax_error("invalid attribute name: '$token'", E_USER_ERROR, __FILE__, __LINE__);
+                    break;
+
+                case 1:
+                    /* If the token is '=', then we go to state 2. */
+                    if ($token == '=') {
+                        $state = 2;
+                    } else
+                        $this->_syntax_error("expecting '=' after attribute name '$last_token'", E_USER_ERROR, __FILE__, __LINE__);
+                    break;
+
+                case 2:
+                    /* If token is not '=', we set the attribute value and go to
+                       state 0. */
+                    if ($token != '=') {
+                        /* We booleanize the token if it's a non-quoted possible
+                           boolean value. */
+                        if (preg_match('~^(on|yes|true)$~', $token)) {
+                            $token = 'true';
+                        } else if (preg_match('~^(off|no|false)$~', $token)) {
+                            $token = 'false';
+                        } else if ($token == 'null') {
+                            $token = 'null';
+                        } else if (preg_match('~^' . $this->_num_const_regexp . '|0[xX][0-9a-fA-F]+$~', $token)) {
+                            /* treat integer literally */
+                        } else if (!preg_match('~^' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '(?:' . $this->_mod_regexp . ')*$~', $token)) {
+                            /* treat as a string, double-quote it escaping quotes */
+                            $token = '"'.addslashes($token).'"';
+                        }
+
+                        $attrs[$attr_name] = $token;
+                        $state = 0;
+                    } else
+                        $this->_syntax_error("'=' cannot be an attribute value", E_USER_ERROR, __FILE__, __LINE__);
+                    break;
+            }
+            $last_token = $token;
+        }
+
+        if($state != 0) {
+            if($state == 1) {
+                $this->_syntax_error("expecting '=' after attribute name '$last_token'", E_USER_ERROR, __FILE__, __LINE__);
+            } else {
+                $this->_syntax_error("missing attribute value", E_USER_ERROR, __FILE__, __LINE__);
+            }
+        }
+
+        $this->_parse_vars_props($attrs);
+
+        return $attrs;
+    }
+
+    /**
+     * compile multiple variables and section properties tokens into
+     * PHP code
+     *
+     * @param array $tokens
+     */
+    function _parse_vars_props(&$tokens)
+    {
+        foreach($tokens as $key => $val) {
+            $tokens[$key] = $this->_parse_var_props($val);
+        }
+    }
+
+    /**
+     * compile single variable and section properties token into
+     * PHP code
+     *
+     * @param string $val
+     * @param string $tag_attrs
+     * @return string
+     */
+    function _parse_var_props($val)
+    {
+        $val = trim($val);
+
+        if(preg_match('~^(' . $this->_obj_call_regexp . '|' . $this->_dvar_regexp . ')(' . $this->_mod_regexp . '*)$~', $val, $match)) {
+            // $ variable or object
+            $return = $this->_parse_var($match[1]);
+            $modifiers = $match[2];
+            if (!empty($this->default_modifiers) && !preg_match('~(^|\|)smarty:nodefaults($|\|)~',$modifiers)) {
+                $_default_mod_string = implode('|',(array)$this->default_modifiers);
+                $modifiers = empty($modifiers) ? $_default_mod_string : $_default_mod_string . '|' . $modifiers;
+            }
+            $this->_parse_modifiers($return, $modifiers);
+            return $return;
+        } elseif (preg_match('~^' . $this->_db_qstr_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) {
+                // double quoted text
+                preg_match('~^(' . $this->_db_qstr_regexp . ')('. $this->_mod_regexp . '*)$~', $val, $match);
+                $return = $this->_expand_quoted_text($match[1]);
+                if($match[2] != '') {
+                    $this->_parse_modifiers($return, $match[2]);
+                }
+                return $return;
+            }
+        elseif(preg_match('~^' . $this->_num_const_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) {
+                // numerical constant
+                preg_match('~^(' . $this->_num_const_regexp . ')('. $this->_mod_regexp . '*)$~', $val, $match);
+                if($match[2] != '') {
+                    $this->_parse_modifiers($match[1], $match[2]);
+                    return $match[1];
+                }
+            }
+        elseif(preg_match('~^' . $this->_si_qstr_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) {
+                // single quoted text
+                preg_match('~^(' . $this->_si_qstr_regexp . ')('. $this->_mod_regexp . '*)$~', $val, $match);
+                if($match[2] != '') {
+                    $this->_parse_modifiers($match[1], $match[2]);
+                    return $match[1];
+                }
+            }
+        elseif(preg_match('~^' . $this->_cvar_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) {
+                // config var
+                return $this->_parse_conf_var($val);
+            }
+        elseif(preg_match('~^' . $this->_svar_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) {
+                // section var
+                return $this->_parse_section_prop($val);
+            }
+        elseif(!in_array($val, $this->_permitted_tokens) && !is_numeric($val)) {
+            // literal string
+            return $this->_expand_quoted_text('"' . strtr($val, array('\\' => '\\\\', '"' => '\\"')) .'"');
+        }
+        return $val;
+    }
+
+    /**
+     * expand quoted text with embedded variables
+     *
+     * @param string $var_expr
+     * @return string
+     */
+    function _expand_quoted_text($var_expr)
+    {
+        // if contains unescaped $, expand it
+        if(preg_match_all('~(?:\`(?<!\\\\)\$' . $this->_dvar_guts_regexp . '(?:' . $this->_obj_ext_regexp . ')*\`)|(?:(?<!\\\\)\$\w+(\[[a-zA-Z0-9]+\])*)~', $var_expr, $_match)) {
+            $_match = $_match[0];
+            $_replace = array();
+            foreach($_match as $_var) {
+                $_replace[$_var] = '".(' . $this->_parse_var(str_replace('`','',$_var)) . ')."';
+            }
+            $var_expr = strtr($var_expr, $_replace);
+            $_return = preg_replace('~\.""|(?<!\\\\)""\.~', '', $var_expr);
+        } else {
+            $_return = $var_expr;
+        }
+        // replace double quoted literal string with single quotes
+        $_return = preg_replace('~^"([\s\w]+)"$~',"'\\1'",$_return);
+        // escape dollar sign if not printing a var
+        $_return = preg_replace('~\$(\W)~',"\\\\\$\\1",$_return);
+        return $_return;
+    }
+
+    /**
+     * parse variable expression into PHP code
+     *
+     * @param string $var_expr
+     * @param string $output
+     * @return string
+     */
+    function _parse_var($var_expr)
+    {
+        $_has_math = false;
+        $_has_php4_method_chaining = false;
+        $_math_vars = preg_split('~('.$this->_dvar_math_regexp.'|'.$this->_qstr_regexp.')~', $var_expr, -1, PREG_SPLIT_DELIM_CAPTURE);
+
+        if(count($_math_vars) > 1) {
+            $_first_var = "";
+            $_complete_var = "";
+            $_output = "";
+            // simple check if there is any math, to stop recursion (due to modifiers with "xx % yy" as parameter)
+            foreach($_math_vars as $_k => $_math_var) {
+                $_math_var = $_math_vars[$_k];
+
+                if(!empty($_math_var) || is_numeric($_math_var)) {
+                    // hit a math operator, so process the stuff which came before it
+                    if(preg_match('~^' . $this->_dvar_math_regexp . '$~', $_math_var)) {
+                        $_has_math = true;
+                        if(!empty($_complete_var) || is_numeric($_complete_var)) {
+                            $_output .= $this->_parse_var($_complete_var);
+                        }
+
+                        // just output the math operator to php
+                        $_output .= $_math_var;
+
+                        if(empty($_first_var))
+                            $_first_var = $_complete_var;
+
+                        $_complete_var = "";
+                    } else {
+                        $_complete_var .= $_math_var;
+                    }
+                }
+            }
+            if($_has_math) {
+                if(!empty($_complete_var) || is_numeric($_complete_var))
+                    $_output .= $this->_parse_var($_complete_var);
+
+                // get the modifiers working (only the last var from math + modifier is left)
+                $var_expr = $_complete_var;
+            }
+        }
+
+        // prevent cutting of first digit in the number (we _definitly_ got a number if the first char is a digit)
+        if(is_numeric(substr($var_expr, 0, 1)))
+            $_var_ref = $var_expr;
+        else
+            $_var_ref = substr($var_expr, 1);
+        
+        if(!$_has_math) {
+            
+            // get [foo] and .foo and ->foo and (...) pieces
+            preg_match_all('~(?:^\w+)|' . $this->_obj_params_regexp . '|(?:' . $this->_var_bracket_regexp . ')|->\$?\w+|\.\$?\w+|\S+~', $_var_ref, $match);
+                        
+            $_indexes = $match[0];
+            $_var_name = array_shift($_indexes);
+
+            /* Handle $smarty.* variable references as a special case. */
+            if ($_var_name == 'smarty') {
+                /*
+                 * If the reference could be compiled, use the compiled output;
+                 * otherwise, fall back on the $smarty variable generated at
+                 * run-time.
+                 */
+                if (($smarty_ref = $this->_compile_smarty_ref($_indexes)) !== null) {
+                    $_output = $smarty_ref;
+                } else {
+                    $_var_name = substr(array_shift($_indexes), 1);
+                    $_output = "\$this->_smarty_vars['$_var_name']";
+                }
+            } elseif(is_numeric($_var_name) && is_numeric(substr($var_expr, 0, 1))) {
+                // because . is the operator for accessing arrays thru inidizes we need to put it together again for floating point numbers
+                if(count($_indexes) > 0)
+                {
+                    $_var_name .= implode("", $_indexes);
+                    $_indexes = array();
+                }
+                $_output = $_var_name;
+            } else {
+                $_output = "\$this->_tpl_vars['$_var_name']";
+            }
+
+            foreach ($_indexes as $_index) {
+                if (substr($_index, 0, 1) == '[') {
+                    $_index = substr($_index, 1, -1);
+                    if (is_numeric($_index)) {
+                        $_output .= "[$_index]";
+                    } elseif (substr($_index, 0, 1) == '$') {
+                        if (strpos($_index, '.') !== false) {
+                            $_output .= '[' . $this->_parse_var($_index) . ']';
+                        } else {
+                            $_output .= "[\$this->_tpl_vars['" . substr($_index, 1) . "']]";
+                        }
+                    } else {
+                        $_var_parts = explode('.', $_index);
+                        $_var_section = $_var_parts[0];
+                        $_var_section_prop = isset($_var_parts[1]) ? $_var_parts[1] : 'index';
+                        $_output .= "[\$this->_sections['$_var_section']['$_var_section_prop']]";
+                    }
+                } else if (substr($_index, 0, 1) == '.') {
+                    if (substr($_index, 1, 1) == '$')
+                        $_output .= "[\$this->_tpl_vars['" . substr($_index, 2) . "']]";
+                    else
+                        $_output .= "['" . substr($_index, 1) . "']";
+                } else if (substr($_index,0,2) == '->') {
+                    if(substr($_index,2,2) == '__') {
+                        $this->_syntax_error('call to internal object members is not allowed', E_USER_ERROR, __FILE__, __LINE__);
+                    } elseif($this->security && substr($_index, 2, 1) == '_') {
+                        $this->_syntax_error('(secure) call to private object member is not allowed', E_USER_ERROR, __FILE__, __LINE__);
+                    } elseif (substr($_index, 2, 1) == '$') {
+                        if ($this->security) {
+                            $this->_syntax_error('(secure) call to dynamic object member is not allowed', E_USER_ERROR, __FILE__, __LINE__);
+                        } else {
+                            $_output .= '->{(($_var=$this->_tpl_vars[\''.substr($_index,3).'\']) && substr($_var,0,2)!=\'__\') ? $_var : $this->trigger_error("cannot access property \\"$_var\\"")}';
+                        }
+                    } else {
+                       if ($this->_phpversion < 5) {
+                         $_has_php4_method_chaining = true;
+                         $_output .= "; \$_foo = \$_foo";
+                       }
+                        $_output .= $_index;
+                    }
+                } elseif (substr($_index, 0, 1) == '(') {
+                    $_index = $this->_parse_parenth_args($_index);
+                    $_output .= $_index;
+                } else {
+                    $_output .= $_index;
+                }
+            }
+        }
+
+        if ($_has_php4_method_chaining) {
+           $_tmp = str_replace("'","\'",'$_foo = '.$_output.'; return $_foo;');
+           return "eval('".$_tmp."')";
+        } else {
+           return $_output; 
+        }
+    }
+
+    /**
+     * parse arguments in function call parenthesis
+     *
+     * @param string $parenth_args
+     * @return string
+     */
+    function _parse_parenth_args($parenth_args)
+    {
+        preg_match_all('~' . $this->_param_regexp . '~',$parenth_args, $match);
+        $orig_vals = $match = $match[0];
+        $this->_parse_vars_props($match);
+        $replace = array();
+        for ($i = 0, $count = count($match); $i < $count; $i++) {
+            $replace[$orig_vals[$i]] = $match[$i];
+        }
+        return strtr($parenth_args, $replace);
+    }
+
+    /**
+     * parse configuration variable expression into PHP code
+     *
+     * @param string $conf_var_expr
+     */
+    function _parse_conf_var($conf_var_expr)
+    {
+        $parts = explode('|', $conf_var_expr, 2);
+        $var_ref = $parts[0];
+        $modifiers = isset($parts[1]) ? $parts[1] : '';
+
+        $var_name = substr($var_ref, 1, -1);
+
+        $output = "\$this->_config[0]['vars']['$var_name']";
+
+        $this->_parse_modifiers($output, $modifiers);
+
+        return $output;
+    }
+
+    /**
+     * parse section property expression into PHP code
+     *
+     * @param string $section_prop_expr
+     * @return string
+     */
+    function _parse_section_prop($section_prop_expr)
+    {
+        $parts = explode('|', $section_prop_expr, 2);
+        $var_ref = $parts[0];
+        $modifiers = isset($parts[1]) ? $parts[1] : '';
+
+        preg_match('!%(\w+)\.(\w+)%!', $var_ref, $match);
+        $section_name = $match[1];
+        $prop_name = $match[2];
+
+        $output = "\$this->_sections['$section_name']['$prop_name']";
+
+        $this->_parse_modifiers($output, $modifiers);
+
+        return $output;
+    }
+
+
+    /**
+     * parse modifier chain into PHP code
+     *
+     * sets $output to parsed modified chain
+     * @param string $output
+     * @param string $modifier_string
+     */
+    function _parse_modifiers(&$output, $modifier_string)
+    {
+        preg_match_all('~\|(@?\w+)((?>:(?:'. $this->_qstr_regexp . '|[^|]+))*)~', '|' . $modifier_string, $_match);
+        list(, $_modifiers, $modifier_arg_strings) = $_match;
+
+        for ($_i = 0, $_for_max = count($_modifiers); $_i < $_for_max; $_i++) {
+            $_modifier_name = $_modifiers[$_i];
+
+            if($_modifier_name == 'smarty') {
+                // skip smarty modifier
+                continue;
+            }
+
+            preg_match_all('~:(' . $this->_qstr_regexp . '|[^:]+)~', $modifier_arg_strings[$_i], $_match);
+            $_modifier_args = $_match[1];
+
+            if (substr($_modifier_name, 0, 1) == '@') {
+                $_map_array = false;
+                $_modifier_name = substr($_modifier_name, 1);
+            } else {
+                $_map_array = true;
+            }
+
+            if (empty($this->_plugins['modifier'][$_modifier_name])
+                && !$this->_get_plugin_filepath('modifier', $_modifier_name)
+                && function_exists($_modifier_name)) {
+                if ($this->security && !in_array($_modifier_name, $this->security_settings['MODIFIER_FUNCS'])) {
+                    $this->_trigger_fatal_error("[plugin] (secure mode) modifier '$_modifier_name' is not allowed" , $this->_current_file, $this->_current_line_no, __FILE__, __LINE__);
+                } else {
+                    $this->_plugins['modifier'][$_modifier_name] = array($_modifier_name,  null, null, false);
+                }
+            }
+            $this->_add_plugin('modifier', $_modifier_name);
+
+            $this->_parse_vars_props($_modifier_args);
+
+            if($_modifier_name == 'default') {
+                // supress notifications of default modifier vars and args
+                if(substr($output, 0, 1) == '$') {
+                    $output = '@' . $output;
+                }
+                if(isset($_modifier_args[0]) && substr($_modifier_args[0], 0, 1) == '$') {
+                    $_modifier_args[0] = '@' . $_modifier_args[0];
+                }
+            }
+            if (count($_modifier_args) > 0)
+                $_modifier_args = ', '.implode(', ', $_modifier_args);
+            else
+                $_modifier_args = '';
+
+            if ($_map_array) {
+                $output = "((is_array(\$_tmp=$output)) ? \$this->_run_mod_handler('$_modifier_name', true, \$_tmp$_modifier_args) : " . $this->_compile_plugin_call('modifier', $_modifier_name) . "(\$_tmp$_modifier_args))";
+
+            } else {
+
+                $output = $this->_compile_plugin_call('modifier', $_modifier_name)."($output$_modifier_args)";
+
+            }
+        }
+    }
+
+
+    /**
+     * add plugin
+     *
+     * @param string $type
+     * @param string $name
+     * @param boolean? $delayed_loading
+     */
+    function _add_plugin($type, $name, $delayed_loading = null)
+    {
+        if (!isset($this->_plugin_info[$type])) {
+            $this->_plugin_info[$type] = array();
+        }
+        if (!isset($this->_plugin_info[$type][$name])) {
+            $this->_plugin_info[$type][$name] = array($this->_current_file,
+                                                      $this->_current_line_no,
+                                                      $delayed_loading);
+        }
+    }
+
+
+    /**
+     * Compiles references of type $smarty.foo
+     *
+     * @param string $indexes
+     * @return string
+     */
+    function _compile_smarty_ref(&$indexes)
+    {
+        /* Extract the reference name. */
+        $_ref = substr($indexes[0], 1);
+        foreach($indexes as $_index_no=>$_index) {
+            if (substr($_index, 0, 1) != '.' && $_index_no<2 || !preg_match('~^(\.|\[|->)~', $_index)) {
+                $this->_syntax_error('$smarty' . implode('', array_slice($indexes, 0, 2)) . ' is an invalid reference', E_USER_ERROR, __FILE__, __LINE__);
+            }
+        }
+
+        switch ($_ref) {
+            case 'now':
+                $compiled_ref = 'time()';
+                $_max_index = 1;
+                break;
+
+            case 'foreach':
+                array_shift($indexes);
+                $_var = $this->_parse_var_props(substr($indexes[0], 1));
+                $_propname = substr($indexes[1], 1);
+                $_max_index = 1;
+                switch ($_propname) {
+                    case 'index':
+                        array_shift($indexes);
+                        $compiled_ref = "(\$this->_foreach[$_var]['iteration']-1)";
+                        break;
+                        
+                    case 'first':
+                        array_shift($indexes);
+                        $compiled_ref = "(\$this->_foreach[$_var]['iteration'] <= 1)";
+                        break;
+
+                    case 'last':
+                        array_shift($indexes);
+                        $compiled_ref = "(\$this->_foreach[$_var]['iteration'] == \$this->_foreach[$_var]['total'])";
+                        break;
+                        
+                    case 'show':
+                        array_shift($indexes);
+                        $compiled_ref = "(\$this->_foreach[$_var]['total'] > 0)";
+                        break;
+                        
+                    default:
+                        unset($_max_index);
+                        $compiled_ref = "\$this->_foreach[$_var]";
+                }
+                break;
+
+            case 'section':
+                array_shift($indexes);
+                $_var = $this->_parse_var_props(substr($indexes[0], 1));
+                $compiled_ref = "\$this->_sections[$_var]";
+                break;
+
+            case 'get':
+                $compiled_ref = ($this->request_use_auto_globals) ? '$_GET' : "\$GLOBALS['HTTP_GET_VARS']";
+                break;
+
+            case 'post':
+                $compiled_ref = ($this->request_use_auto_globals) ? '$_POST' : "\$GLOBALS['HTTP_POST_VARS']";
+                break;
+
+            case 'cookies':
+                $compiled_ref = ($this->request_use_auto_globals) ? '$_COOKIE' : "\$GLOBALS['HTTP_COOKIE_VARS']";
+                break;
+
+            case 'env':
+                $compiled_ref = ($this->request_use_auto_globals) ? '$_ENV' : "\$GLOBALS['HTTP_ENV_VARS']";
+                break;
+
+            case 'server':
+                $compiled_ref = ($this->request_use_auto_globals) ? '$_SERVER' : "\$GLOBALS['HTTP_SERVER_VARS']";
+                break;
+
+            case 'session':
+                $compiled_ref = ($this->request_use_auto_globals) ? '$_SESSION' : "\$GLOBALS['HTTP_SESSION_VARS']";
+                break;
+
+            /*
+             * These cases are handled either at run-time or elsewhere in the
+             * compiler.
+             */
+            case 'request':
+                if ($this->request_use_auto_globals) {
+                    $compiled_ref = '$_REQUEST';
+                    break;
+                } else {
+                    $this->_init_smarty_vars = true;
+                }
+                return null;
+
+            case 'capture':
+                return null;
+
+            case 'template':
+                $compiled_ref = "'$this->_current_file'";
+                $_max_index = 1;
+                break;
+
+            case 'version':
+                $compiled_ref = "'$this->_version'";
+                $_max_index = 1;
+                break;
+
+            case 'const':
+                if ($this->security && !$this->security_settings['ALLOW_CONSTANTS']) {
+                    $this->_syntax_error("(secure mode) constants not permitted",
+                                         E_USER_WARNING, __FILE__, __LINE__);
+                    return;
+                }
+                array_shift($indexes);
+                if (preg_match('!^\.\w+$!', $indexes[0])) {
+                    $compiled_ref = '@' . substr($indexes[0], 1);
+                } else {
+                    $_val = $this->_parse_var_props(substr($indexes[0], 1));
+                    $compiled_ref = '@constant(' . $_val . ')';
+                }
+                $_max_index = 1;
+                break;
+
+            case 'config':
+                $compiled_ref = "\$this->_config[0]['vars']";
+                $_max_index = 3;
+                break;
+
+            case 'ldelim':
+                $compiled_ref = "'$this->left_delimiter'";
+                break;
+
+            case 'rdelim':
+                $compiled_ref = "'$this->right_delimiter'";
+                break;
+                
+            default:
+                $this->_syntax_error('$smarty.' . $_ref . ' is an unknown reference', E_USER_ERROR, __FILE__, __LINE__);
+                break;
+        }
+
+        if (isset($_max_index) && count($indexes) > $_max_index) {
+            $this->_syntax_error('$smarty' . implode('', $indexes) .' is an invalid reference', E_USER_ERROR, __FILE__, __LINE__);
+        }
+
+        array_shift($indexes);
+        return $compiled_ref;
+    }
+
+    /**
+     * compiles call to plugin of type $type with name $name
+     * returns a string containing the function-name or method call
+     * without the paramter-list that would have follow to make the
+     * call valid php-syntax
+     *
+     * @param string $type
+     * @param string $name
+     * @return string
+     */
+    function _compile_plugin_call($type, $name) {
+        if (isset($this->_plugins[$type][$name])) {
+            /* plugin loaded */
+            if (is_array($this->_plugins[$type][$name][0])) {
+                return ((is_object($this->_plugins[$type][$name][0][0])) ?
+                        "\$this->_plugins['$type']['$name'][0][0]->"    /* method callback */
+                        : (string)($this->_plugins[$type][$name][0][0]).'::'    /* class callback */
+                       ). $this->_plugins[$type][$name][0][1];
+
+            } else {
+                /* function callback */
+                return $this->_plugins[$type][$name][0];
+
+            }
+        } else {
+            /* plugin not loaded -> auto-loadable-plugin */
+            return 'smarty_'.$type.'_'.$name;
+
+        }
+    }
+
+    /**
+     * load pre- and post-filters
+     */
+    function _load_filters()
+    {
+        if (count($this->_plugins['prefilter']) > 0) {
+            foreach ($this->_plugins['prefilter'] as $filter_name => $prefilter) {
+                if ($prefilter === false) {
+                    unset($this->_plugins['prefilter'][$filter_name]);
+                    $_params = array('plugins' => array(array('prefilter', $filter_name, null, null, false)));
+                    require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');
+                    smarty_core_load_plugins($_params, $this);
+                }
+            }
+        }
+        if (count($this->_plugins['postfilter']) > 0) {
+            foreach ($this->_plugins['postfilter'] as $filter_name => $postfilter) {
+                if ($postfilter === false) {
+                    unset($this->_plugins['postfilter'][$filter_name]);
+                    $_params = array('plugins' => array(array('postfilter', $filter_name, null, null, false)));
+                    require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');
+                    smarty_core_load_plugins($_params, $this);
+                }
+            }
+        }
+    }
+
+
+    /**
+     * Quote subpattern references
+     *
+     * @param string $string
+     * @return string
+     */
+    function _quote_replace($string)
+    {
+        return strtr($string, array('\\' => '\\\\', '$' => '\\$'));
+    }
+
+    /**
+     * display Smarty syntax error
+     *
+     * @param string $error_msg
+     * @param integer $error_type
+     * @param string $file
+     * @param integer $line
+     */
+    function _syntax_error($error_msg, $error_type = E_USER_ERROR, $file=null, $line=null)
+    {
+        $this->_trigger_fatal_error("syntax error: $error_msg", $this->_current_file, $this->_current_line_no, $file, $line, $error_type);
+    }
+
+
+    /**
+     * check if the compilation changes from cacheable to
+     * non-cacheable state with the beginning of the current
+     * plugin. return php-code to reflect the transition.
+     * @return string
+     */
+    function _push_cacheable_state($type, $name) {
+        $_cacheable = !isset($this->_plugins[$type][$name]) || $this->_plugins[$type][$name][4];
+        if ($_cacheable
+            || 0<$this->_cacheable_state++) return '';
+        if (!isset($this->_cache_serial)) $this->_cache_serial = md5(uniqid('Smarty'));
+        $_ret = 'if ($this->caching && !$this->_cache_including): echo \'{nocache:'
+            . $this->_cache_serial . '#' . $this->_nocache_count
+            . '}\'; endif;';
+        return $_ret;
+    }
+
+
+    /**
+     * check if the compilation changes from non-cacheable to
+     * cacheable state with the end of the current plugin return
+     * php-code to reflect the transition.
+     * @return string
+     */
+    function _pop_cacheable_state($type, $name) {
+        $_cacheable = !isset($this->_plugins[$type][$name]) || $this->_plugins[$type][$name][4];
+        if ($_cacheable
+            || --$this->_cacheable_state>0) return '';
+        return 'if ($this->caching && !$this->_cache_including): echo \'{/nocache:'
+            . $this->_cache_serial . '#' . ($this->_nocache_count++)
+            . '}\'; endif;';
+    }
+
+
+    /**
+     * push opening tag-name, file-name and line-number on the tag-stack
+     * @param string the opening tag's name
+     */
+    function _push_tag($open_tag)
+    {
+        array_push($this->_tag_stack, array($open_tag, $this->_current_line_no));
+    }
+
+    /**
+     * pop closing tag-name
+     * raise an error if this stack-top doesn't match with the closing tag
+     * @param string the closing tag's name
+     * @return string the opening tag's name
+     */
+    function _pop_tag($close_tag)
+    {
+        $message = '';
+        if (count($this->_tag_stack)>0) {
+            list($_open_tag, $_line_no) = array_pop($this->_tag_stack);
+            if ($close_tag == $_open_tag) {
+                return $_open_tag;
+            }
+            if ($close_tag == 'if' && ($_open_tag == 'else' || $_open_tag == 'elseif' )) {
+                return $this->_pop_tag($close_tag);
+            }
+            if ($close_tag == 'section' && $_open_tag == 'sectionelse') {
+                $this->_pop_tag($close_tag);
+                return $_open_tag;
+            }
+            if ($close_tag == 'foreach' && $_open_tag == 'foreachelse') {
+                $this->_pop_tag($close_tag);
+                return $_open_tag;
+            }
+            if ($_open_tag == 'else' || $_open_tag == 'elseif') {
+                $_open_tag = 'if';
+            } elseif ($_open_tag == 'sectionelse') {
+                $_open_tag = 'section';
+            } elseif ($_open_tag == 'foreachelse') {
+                $_open_tag = 'foreach';
+            }
+            $message = " expected {/$_open_tag} (opened line $_line_no).";
+        }
+        $this->_syntax_error("mismatched tag {/$close_tag}.$message",
+                             E_USER_ERROR, __FILE__, __LINE__);
+    }
+
+}
+
+/**
+ * compare to values by their string length
+ *
+ * @access private
+ * @param string $a
+ * @param string $b
+ * @return 0|-1|1
+ */
+function _smarty_sort_length($a, $b)
+{
+    if($a == $b)
+        return 0;
+
+    if(strlen($a) == strlen($b))
+        return ($a > $b) ? -1 : 1;
+
+    return (strlen($a) > strlen($b)) ? -1 : 1;
+}
+
+
+/* vim: set et: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/debug.tpl
===================================================================
--- /tags/2.0.2/include/smarty/libs/debug.tpl	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/debug.tpl	(revision 3278)
@@ -0,0 +1,157 @@
+{* Smarty *}
+{* debug.tpl, last updated version 2.1.0 *}
+{assign_debug_info}
+{capture assign=debug_output}
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+<head>
+    <title>Smarty Debug Console</title>
+{literal}
+<style type="text/css">
+/* <![CDATA[ */
+body, h1, h2, td, th, p {
+    font-family: sans-serif;
+    font-weight: normal;
+    font-size: 0.9em;
+    margin: 1px;
+    padding: 0;
+}
+
+h1 {
+    margin: 0;
+    text-align: left;
+    padding: 2px;
+    background-color: #f0c040;
+    color:  black;
+    font-weight: bold;
+    font-size: 1.2em;
+ }
+
+h2 {
+    background-color: #9B410E;
+    color: white;
+    text-align: left;
+    font-weight: bold;
+    padding: 2px;
+    border-top: 1px solid black;
+}
+
+body {
+    background: black; 
+}
+
+p, table, div {
+    background: #f0ead8;
+} 
+
+p {
+    margin: 0;
+    font-style: italic;
+    text-align: center;
+}
+
+table {
+    width: 100%;
+}
+
+th, td {
+    font-family: monospace;
+    vertical-align: top;
+    text-align: left;
+    width: 50%;
+}
+
+td {
+    color: green;
+}
+
+.odd {
+    background-color: #eeeeee;
+}
+
+.even {
+    background-color: #fafafa;
+}
+
+.exectime {
+    font-size: 0.8em;
+    font-style: italic;
+}
+
+#table_assigned_vars th {
+    color: blue;
+}
+
+#table_config_vars th {
+    color: maroon;
+}
+/* ]]> */
+</style>
+{/literal}
+</head>
+<body>
+
+<h1>Smarty Debug Console</h1>
+
+<h2>included templates &amp; config files (load time in seconds)</h2>
+
+<div>
+{section name=templates loop=$_debug_tpls}
+    {section name=indent loop=$_debug_tpls[templates].depth}&nbsp;&nbsp;&nbsp;{/section}
+    <font color={if $_debug_tpls[templates].type eq "template"}brown{elseif $_debug_tpls[templates].type eq "insert"}black{else}green{/if}>
+        {$_debug_tpls[templates].filename|escape:html}</font>
+    {if isset($_debug_tpls[templates].exec_time)}
+        <span class="exectime">
+        ({$_debug_tpls[templates].exec_time|string_format:"%.5f"})
+        {if %templates.index% eq 0}(total){/if}
+        </span>
+    {/if}
+    <br />
+{sectionelse}
+    <p>no templates included</p>
+{/section}
+</div>
+
+<h2>assigned template variables</h2>
+
+<table id="table_assigned_vars">
+    {section name=vars loop=$_debug_keys}
+        <tr class="{cycle values="odd,even"}">
+            <th>{ldelim}${$_debug_keys[vars]|escape:'html'}{rdelim}</th>
+            <td>{$_debug_vals[vars]|@debug_print_var}</td></tr>
+    {sectionelse}
+        <tr><td><p>no template variables assigned</p></td></tr>
+    {/section}
+</table>
+
+<h2>assigned config file variables (outer template scope)</h2>
+
+<table id="table_config_vars">
+    {section name=config_vars loop=$_debug_config_keys}
+        <tr class="{cycle values="odd,even"}">
+            <th>{ldelim}#{$_debug_config_keys[config_vars]|escape:'html'}#{rdelim}</th>
+            <td>{$_debug_config_vals[config_vars]|@debug_print_var}</td></tr>
+    {sectionelse}
+        <tr><td><p>no config vars assigned</p></td></tr>
+    {/section}
+</table>
+</body>
+</html>
+{/capture}
+{if isset($_smarty_debug_output) and $_smarty_debug_output eq "html"}
+    {$debug_output}
+{else}
+<script type="text/javascript">
+// <![CDATA[
+    if ( self.name == '' ) {ldelim}
+       var title = 'Console';
+    {rdelim}
+    else {ldelim}
+       var title = 'Console_' + self.name;
+    {rdelim}
+    _smarty_console = window.open("",title.value,"width=680,height=600,resizable,scrollbars=yes");
+    _smarty_console.document.write('{$debug_output|escape:'javascript'}');
+    _smarty_console.document.close();
+// ]]>
+</script>
+{/if}
Index: /tags/2.0.2/include/smarty/libs/internals/core.assemble_plugin_filepath.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/internals/core.assemble_plugin_filepath.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/internals/core.assemble_plugin_filepath.php	(revision 3278)
@@ -0,0 +1,67 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * assemble filepath of requested plugin
+ *
+ * @param string $type
+ * @param string $name
+ * @return string|false
+ */
+function smarty_core_assemble_plugin_filepath($params, &$smarty)
+{
+    static $_filepaths_cache = array();
+
+    $_plugin_filename = $params['type'] . '.' . $params['name'] . '.php';
+    if (isset($_filepaths_cache[$_plugin_filename])) {
+        return $_filepaths_cache[$_plugin_filename];
+    }
+    $_return = false;
+
+    foreach ((array)$smarty->plugins_dir as $_plugin_dir) {
+
+        $_plugin_filepath = $_plugin_dir . DIRECTORY_SEPARATOR . $_plugin_filename;
+
+        // see if path is relative
+        if (!preg_match("/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/", $_plugin_dir)) {
+            $_relative_paths[] = $_plugin_dir;
+            // relative path, see if it is in the SMARTY_DIR
+            if (@is_readable(SMARTY_DIR . $_plugin_filepath)) {
+                $_return = SMARTY_DIR . $_plugin_filepath;
+                break;
+            }
+        }
+        // try relative to cwd (or absolute)
+        if (@is_readable($_plugin_filepath)) {
+            $_return = $_plugin_filepath;
+            break;
+        }
+    }
+
+    if($_return === false) {
+        // still not found, try PHP include_path
+        if(isset($_relative_paths)) {
+            foreach ((array)$_relative_paths as $_plugin_dir) {
+
+                $_plugin_filepath = $_plugin_dir . DIRECTORY_SEPARATOR . $_plugin_filename;
+
+                $_params = array('file_path' => $_plugin_filepath);
+                require_once(SMARTY_CORE_DIR . 'core.get_include_path.php');
+                if(smarty_core_get_include_path($_params, $smarty)) {
+                    $_return = $_params['new_file_path'];
+                    break;
+                }
+            }
+        }
+    }
+    $_filepaths_cache[$_plugin_filename] = $_return;
+    return $_return;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/internals/core.assign_smarty_interface.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/internals/core.assign_smarty_interface.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/internals/core.assign_smarty_interface.php	(revision 3278)
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Smarty assign_smarty_interface core plugin
+ *
+ * Type:     core<br>
+ * Name:     assign_smarty_interface<br>
+ * Purpose:  assign the $smarty interface variable
+ * @param array Format: null
+ * @param Smarty
+ */
+function smarty_core_assign_smarty_interface($params, &$smarty)
+{
+        if (isset($smarty->_smarty_vars) && isset($smarty->_smarty_vars['request'])) {
+            return;
+        }
+
+        $_globals_map = array('g'  => 'HTTP_GET_VARS',
+                             'p'  => 'HTTP_POST_VARS',
+                             'c'  => 'HTTP_COOKIE_VARS',
+                             's'  => 'HTTP_SERVER_VARS',
+                             'e'  => 'HTTP_ENV_VARS');
+
+        $_smarty_vars_request  = array();
+
+        foreach (preg_split('!!', strtolower($smarty->request_vars_order)) as $_c) {
+            if (isset($_globals_map[$_c])) {
+                $_smarty_vars_request = array_merge($_smarty_vars_request, $GLOBALS[$_globals_map[$_c]]);
+            }
+        }
+        $_smarty_vars_request = @array_merge($_smarty_vars_request, $GLOBALS['HTTP_SESSION_VARS']);
+
+        $smarty->_smarty_vars['request'] = $_smarty_vars_request;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/internals/core.create_dir_structure.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/internals/core.create_dir_structure.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/internals/core.create_dir_structure.php	(revision 3278)
@@ -0,0 +1,79 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * create full directory structure
+ *
+ * @param string $dir
+ */
+
+// $dir
+
+function smarty_core_create_dir_structure($params, &$smarty)
+{
+    if (!file_exists($params['dir'])) {
+        $_open_basedir_ini = ini_get('open_basedir');
+
+        if (DIRECTORY_SEPARATOR=='/') {
+            /* unix-style paths */
+            $_dir = $params['dir'];
+            $_dir_parts = preg_split('!/+!', $_dir, -1, PREG_SPLIT_NO_EMPTY);
+            $_new_dir = (substr($_dir, 0, 1)=='/') ? '/' : getcwd().'/';
+            if($_use_open_basedir = !empty($_open_basedir_ini)) {
+                $_open_basedirs = explode(':', $_open_basedir_ini);
+            }
+
+        } else {
+            /* other-style paths */
+            $_dir = str_replace('\\','/', $params['dir']);
+            $_dir_parts = preg_split('!/+!', $_dir, -1, PREG_SPLIT_NO_EMPTY);
+            if (preg_match('!^((//)|([a-zA-Z]:/))!', $_dir, $_root_dir)) {
+                /* leading "//" for network volume, or "[letter]:/" for full path */
+                $_new_dir = $_root_dir[1];
+                /* remove drive-letter from _dir_parts */
+                if (isset($_root_dir[3])) array_shift($_dir_parts);
+
+            } else {
+                $_new_dir = str_replace('\\', '/', getcwd()).'/';
+
+            }
+
+            if($_use_open_basedir = !empty($_open_basedir_ini)) {
+                $_open_basedirs = explode(';', str_replace('\\', '/', $_open_basedir_ini));
+            }
+
+        }
+
+        /* all paths use "/" only from here */
+        foreach ($_dir_parts as $_dir_part) {
+            $_new_dir .= $_dir_part;
+
+            if ($_use_open_basedir) {
+                // do not attempt to test or make directories outside of open_basedir
+                $_make_new_dir = false;
+                foreach ($_open_basedirs as $_open_basedir) {
+                    if (substr($_new_dir, 0, strlen($_open_basedir)) == $_open_basedir) {
+                        $_make_new_dir = true;
+                        break;
+                    }
+                }
+            } else {
+                $_make_new_dir = true;
+            }
+
+            if ($_make_new_dir && !file_exists($_new_dir) && !@mkdir($_new_dir, $smarty->_dir_perms) && !is_dir($_new_dir)) {
+                $smarty->trigger_error("problem creating directory '" . $_new_dir . "'");
+                return false;
+            }
+            $_new_dir .= '/';
+        }
+    }
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/internals/core.display_debug_console.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/internals/core.display_debug_console.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/internals/core.display_debug_console.php	(revision 3278)
@@ -0,0 +1,61 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Smarty debug_console function plugin
+ *
+ * Type:     core<br>
+ * Name:     display_debug_console<br>
+ * Purpose:  display the javascript debug console window
+ * @param array Format: null
+ * @param Smarty
+ */
+function smarty_core_display_debug_console($params, &$smarty)
+{
+    // we must force compile the debug template in case the environment
+    // changed between separate applications.
+
+    if(empty($smarty->debug_tpl)) {
+        // set path to debug template from SMARTY_DIR
+        $smarty->debug_tpl = SMARTY_DIR . 'debug.tpl';
+        if($smarty->security && is_file($smarty->debug_tpl)) {
+            $smarty->secure_dir[] = realpath($smarty->debug_tpl);
+        }
+        $smarty->debug_tpl = 'file:' . SMARTY_DIR . 'debug.tpl';
+    }
+
+    $_ldelim_orig = $smarty->left_delimiter;
+    $_rdelim_orig = $smarty->right_delimiter;
+
+    $smarty->left_delimiter = '{';
+    $smarty->right_delimiter = '}';
+
+    $_compile_id_orig = $smarty->_compile_id;
+    $smarty->_compile_id = null;
+
+    $_compile_path = $smarty->_get_compile_path($smarty->debug_tpl);
+    if ($smarty->_compile_resource($smarty->debug_tpl, $_compile_path))
+    {
+        ob_start();
+        $smarty->_include($_compile_path);
+        $_results = ob_get_contents();
+        ob_end_clean();
+    } else {
+        $_results = '';
+    }
+
+    $smarty->_compile_id = $_compile_id_orig;
+
+    $smarty->left_delimiter = $_ldelim_orig;
+    $smarty->right_delimiter = $_rdelim_orig;
+
+    return $_results;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/internals/core.get_include_path.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/internals/core.get_include_path.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/internals/core.get_include_path.php	(revision 3278)
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Get path to file from include_path
+ *
+ * @param string $file_path
+ * @param string $new_file_path
+ * @return boolean
+ * @staticvar array|null
+ */
+
+//  $file_path, &$new_file_path
+
+function smarty_core_get_include_path(&$params, &$smarty)
+{
+    static $_path_array = null;
+
+    if(!isset($_path_array)) {
+        $_ini_include_path = ini_get('include_path');
+
+        if(strstr($_ini_include_path,';')) {
+            // windows pathnames
+            $_path_array = explode(';',$_ini_include_path);
+        } else {
+            $_path_array = explode(':',$_ini_include_path);
+        }
+    }
+    foreach ($_path_array as $_include_path) {
+        if (@is_readable($_include_path . DIRECTORY_SEPARATOR . $params['file_path'])) {
+               $params['new_file_path'] = $_include_path . DIRECTORY_SEPARATOR . $params['file_path'];
+            return true;
+        }
+    }
+    return false;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/internals/core.get_microtime.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/internals/core.get_microtime.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/internals/core.get_microtime.php	(revision 3278)
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Get seconds and microseconds
+ * @return double
+ */
+function smarty_core_get_microtime($params, &$smarty)
+{
+    $mtime = microtime();
+    $mtime = explode(" ", $mtime);
+    $mtime = (double)($mtime[1]) + (double)($mtime[0]);
+    return ($mtime);
+}
+
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/internals/core.get_php_resource.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/internals/core.get_php_resource.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/internals/core.get_php_resource.php	(revision 3278)
@@ -0,0 +1,80 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Retrieves PHP script resource
+ *
+ * sets $php_resource to the returned resource
+ * @param string $resource
+ * @param string $resource_type
+ * @param  $php_resource
+ * @return boolean
+ */
+
+function smarty_core_get_php_resource(&$params, &$smarty)
+{
+
+    $params['resource_base_path'] = $smarty->trusted_dir;
+    $smarty->_parse_resource_name($params, $smarty);
+
+    /*
+     * Find out if the resource exists.
+     */
+
+    if ($params['resource_type'] == 'file') {
+        $_readable = false;
+        if(file_exists($params['resource_name']) && is_readable($params['resource_name'])) {
+            $_readable = true;
+        } else {
+            // test for file in include_path
+            $_params = array('file_path' => $params['resource_name']);
+            require_once(SMARTY_CORE_DIR . 'core.get_include_path.php');
+            if(smarty_core_get_include_path($_params, $smarty)) {
+                $_include_path = $_params['new_file_path'];
+                $_readable = true;
+            }
+        }
+    } else if ($params['resource_type'] != 'file') {
+        $_template_source = null;
+        $_readable = is_callable($smarty->_plugins['resource'][$params['resource_type']][0][0])
+            && call_user_func_array($smarty->_plugins['resource'][$params['resource_type']][0][0],
+                                    array($params['resource_name'], &$_template_source, &$smarty));
+    }
+
+    /*
+     * Set the error function, depending on which class calls us.
+     */
+    if (method_exists($smarty, '_syntax_error')) {
+        $_error_funcc = '_syntax_error';
+    } else {
+        $_error_funcc = 'trigger_error';
+    }
+
+    if ($_readable) {
+        if ($smarty->security) {
+            require_once(SMARTY_CORE_DIR . 'core.is_trusted.php');
+            if (!smarty_core_is_trusted($params, $smarty)) {
+                $smarty->$_error_funcc('(secure mode) ' . $params['resource_type'] . ':' . $params['resource_name'] . ' is not trusted');
+                return false;
+            }
+        }
+    } else {
+        $smarty->$_error_funcc($params['resource_type'] . ':' . $params['resource_name'] . ' is not readable');
+        return false;
+    }
+
+    if ($params['resource_type'] == 'file') {
+        $params['php_resource'] = $params['resource_name'];
+    } else {
+        $params['php_resource'] = $_template_source;
+    }
+    return true;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/internals/core.is_secure.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/internals/core.is_secure.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/internals/core.is_secure.php	(revision 3278)
@@ -0,0 +1,59 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * determines if a resource is secure or not.
+ *
+ * @param string $resource_type
+ * @param string $resource_name
+ * @return boolean
+ */
+
+//  $resource_type, $resource_name
+
+function smarty_core_is_secure($params, &$smarty)
+{
+    if (!$smarty->security || $smarty->security_settings['INCLUDE_ANY']) {
+        return true;
+    }
+
+    if ($params['resource_type'] == 'file') {
+        $_rp = realpath($params['resource_name']);
+        if (isset($params['resource_base_path'])) {
+            foreach ((array)$params['resource_base_path'] as $curr_dir) {
+                if ( ($_cd = realpath($curr_dir)) !== false &&
+                     strncmp($_rp, $_cd, strlen($_cd)) == 0 &&
+                     substr($_rp, strlen($_cd), 1) == DIRECTORY_SEPARATOR ) {
+                    return true;
+                }
+            }
+        }
+        if (!empty($smarty->secure_dir)) {
+            foreach ((array)$smarty->secure_dir as $curr_dir) {
+                if ( ($_cd = realpath($curr_dir)) !== false) {
+                    if($_cd == $_rp) {
+                        return true;
+                    } elseif (strncmp($_rp, $_cd, strlen($_cd)) == 0 &&
+                        substr($_rp, strlen($_cd), 1) == DIRECTORY_SEPARATOR) {
+                        return true;
+                    }
+                }
+            }
+        }
+    } else {
+        // resource is not on local file system
+        return call_user_func_array(
+            $smarty->_plugins['resource'][$params['resource_type']][0][2],
+            array($params['resource_name'], &$smarty));
+    }
+
+    return false;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/internals/core.is_trusted.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/internals/core.is_trusted.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/internals/core.is_trusted.php	(revision 3278)
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * determines if a resource is trusted or not
+ *
+ * @param string $resource_type
+ * @param string $resource_name
+ * @return boolean
+ */
+
+ // $resource_type, $resource_name
+
+function smarty_core_is_trusted($params, &$smarty)
+{
+    $_smarty_trusted = false;
+    if ($params['resource_type'] == 'file') {
+        if (!empty($smarty->trusted_dir)) {
+            $_rp = realpath($params['resource_name']);
+            foreach ((array)$smarty->trusted_dir as $curr_dir) {
+                if (!empty($curr_dir) && is_readable ($curr_dir)) {
+                    $_cd = realpath($curr_dir);
+                    if (strncmp($_rp, $_cd, strlen($_cd)) == 0
+                        && substr($_rp, strlen($_cd), 1) == DIRECTORY_SEPARATOR ) {
+                        $_smarty_trusted = true;
+                        break;
+                    }
+                }
+            }
+        }
+
+    } else {
+        // resource is not on local file system
+        $_smarty_trusted = call_user_func_array($smarty->_plugins['resource'][$params['resource_type']][0][3],
+                                                array($params['resource_name'], $smarty));
+    }
+
+    return $_smarty_trusted;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/internals/core.load_plugins.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/internals/core.load_plugins.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/internals/core.load_plugins.php	(revision 3278)
@@ -0,0 +1,125 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Load requested plugins
+ *
+ * @param array $plugins
+ */
+
+// $plugins
+
+function smarty_core_load_plugins($params, &$smarty)
+{
+
+    foreach ($params['plugins'] as $_plugin_info) {
+        list($_type, $_name, $_tpl_file, $_tpl_line, $_delayed_loading) = $_plugin_info;
+        $_plugin = &$smarty->_plugins[$_type][$_name];
+
+        /*
+         * We do not load plugin more than once for each instance of Smarty.
+         * The following code checks for that. The plugin can also be
+         * registered dynamically at runtime, in which case template file
+         * and line number will be unknown, so we fill them in.
+         *
+         * The final element of the info array is a flag that indicates
+         * whether the dynamically registered plugin function has been
+         * checked for existence yet or not.
+         */
+        if (isset($_plugin)) {
+            if (empty($_plugin[3])) {
+                if (!is_callable($_plugin[0])) {
+                    $smarty->_trigger_fatal_error("[plugin] $_type '$_name' is not implemented", $_tpl_file, $_tpl_line, __FILE__, __LINE__);
+                } else {
+                    $_plugin[1] = $_tpl_file;
+                    $_plugin[2] = $_tpl_line;
+                    $_plugin[3] = true;
+                    if (!isset($_plugin[4])) $_plugin[4] = true; /* cacheable */
+                }
+            }
+            continue;
+        } else if ($_type == 'insert') {
+            /*
+             * For backwards compatibility, we check for insert functions in
+             * the symbol table before trying to load them as a plugin.
+             */
+            $_plugin_func = 'insert_' . $_name;
+            if (function_exists($_plugin_func)) {
+                $_plugin = array($_plugin_func, $_tpl_file, $_tpl_line, true, false);
+                continue;
+            }
+        }
+
+        $_plugin_file = $smarty->_get_plugin_filepath($_type, $_name);
+
+        if (! $_found = ($_plugin_file != false)) {
+            $_message = "could not load plugin file '$_type.$_name.php'\n";
+        }
+
+        /*
+         * If plugin file is found, it -must- provide the properly named
+         * plugin function. In case it doesn't, simply output the error and
+         * do not fall back on any other method.
+         */
+        if ($_found) {
+            include_once $_plugin_file;
+
+            $_plugin_func = 'smarty_' . $_type . '_' . $_name;
+            if (!function_exists($_plugin_func)) {
+                $smarty->_trigger_fatal_error("[plugin] function $_plugin_func() not found in $_plugin_file", $_tpl_file, $_tpl_line, __FILE__, __LINE__);
+                continue;
+            }
+        }
+        /*
+         * In case of insert plugins, their code may be loaded later via
+         * 'script' attribute.
+         */
+        else if ($_type == 'insert' && $_delayed_loading) {
+            $_plugin_func = 'smarty_' . $_type . '_' . $_name;
+            $_found = true;
+        }
+
+        /*
+         * Plugin specific processing and error checking.
+         */
+        if (!$_found) {
+            if ($_type == 'modifier') {
+                /*
+                 * In case modifier falls back on using PHP functions
+                 * directly, we only allow those specified in the security
+                 * context.
+                 */
+                if ($smarty->security && !in_array($_name, $smarty->security_settings['MODIFIER_FUNCS'])) {
+                    $_message = "(secure mode) modifier '$_name' is not allowed";
+                } else {
+                    if (!function_exists($_name)) {
+                        $_message = "modifier '$_name' is not implemented";
+                    } else {
+                        $_plugin_func = $_name;
+                        $_found = true;
+                    }
+                }
+            } else if ($_type == 'function') {
+                /*
+                 * This is a catch-all situation.
+                 */
+                $_message = "unknown tag - '$_name'";
+            }
+        }
+
+        if ($_found) {
+            $smarty->_plugins[$_type][$_name] = array($_plugin_func, $_tpl_file, $_tpl_line, true, true);
+        } else {
+            // output error
+            $smarty->_trigger_fatal_error('[plugin] ' . $_message, $_tpl_file, $_tpl_line, __FILE__, __LINE__);
+        }
+    }
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/internals/core.load_resource_plugin.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/internals/core.load_resource_plugin.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/internals/core.load_resource_plugin.php	(revision 3278)
@@ -0,0 +1,74 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * load a resource plugin
+ *
+ * @param string $type
+ */
+
+// $type
+
+function smarty_core_load_resource_plugin($params, &$smarty)
+{
+    /*
+     * Resource plugins are not quite like the other ones, so they are
+     * handled differently. The first element of plugin info is the array of
+     * functions provided by the plugin, the second one indicates whether
+     * all of them exist or not.
+     */
+
+    $_plugin = &$smarty->_plugins['resource'][$params['type']];
+    if (isset($_plugin)) {
+        if (!$_plugin[1] && count($_plugin[0])) {
+            $_plugin[1] = true;
+            foreach ($_plugin[0] as $_plugin_func) {
+                if (!is_callable($_plugin_func)) {
+                    $_plugin[1] = false;
+                    break;
+                }
+            }
+        }
+
+        if (!$_plugin[1]) {
+            $smarty->_trigger_fatal_error("[plugin] resource '" . $params['type'] . "' is not implemented", null, null, __FILE__, __LINE__);
+        }
+
+        return;
+    }
+
+    $_plugin_file = $smarty->_get_plugin_filepath('resource', $params['type']);
+    $_found = ($_plugin_file != false);
+
+    if ($_found) {            /*
+         * If the plugin file is found, it -must- provide the properly named
+         * plugin functions.
+         */
+        include_once($_plugin_file);
+
+        /*
+         * Locate functions that we require the plugin to provide.
+         */
+        $_resource_ops = array('source', 'timestamp', 'secure', 'trusted');
+        $_resource_funcs = array();
+        foreach ($_resource_ops as $_op) {
+            $_plugin_func = 'smarty_resource_' . $params['type'] . '_' . $_op;
+            if (!function_exists($_plugin_func)) {
+                $smarty->_trigger_fatal_error("[plugin] function $_plugin_func() not found in $_plugin_file", null, null, __FILE__, __LINE__);
+                return;
+            } else {
+                $_resource_funcs[] = $_plugin_func;
+            }
+        }
+
+        $smarty->_plugins['resource'][$params['type']] = array($_resource_funcs, true);
+    }
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/internals/core.process_cached_inserts.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/internals/core.process_cached_inserts.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/internals/core.process_cached_inserts.php	(revision 3278)
@@ -0,0 +1,71 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Replace cached inserts with the actual results
+ *
+ * @param string $results
+ * @return string
+ */
+function smarty_core_process_cached_inserts($params, &$smarty)
+{
+    preg_match_all('!'.$smarty->_smarty_md5.'{insert_cache (.*)}'.$smarty->_smarty_md5.'!Uis',
+                   $params['results'], $match);
+    list($cached_inserts, $insert_args) = $match;
+
+    for ($i = 0, $for_max = count($cached_inserts); $i < $for_max; $i++) {
+        if ($smarty->debugging) {
+            $_params = array();
+            require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
+            $debug_start_time = smarty_core_get_microtime($_params, $smarty);
+        }
+
+        $args = unserialize($insert_args[$i]);
+        $name = $args['name'];
+
+        if (isset($args['script'])) {
+            $_params = array('resource_name' => $smarty->_dequote($args['script']));
+            require_once(SMARTY_CORE_DIR . 'core.get_php_resource.php');
+            if(!smarty_core_get_php_resource($_params, $smarty)) {
+                return false;
+            }
+            $resource_type = $_params['resource_type'];
+            $php_resource = $_params['php_resource'];
+
+
+            if ($resource_type == 'file') {
+                $smarty->_include($php_resource, true);
+            } else {
+                $smarty->_eval($php_resource);
+            }
+        }
+
+        $function_name = $smarty->_plugins['insert'][$name][0];
+        if (empty($args['assign'])) {
+            $replace = $function_name($args, $smarty);
+        } else {
+            $smarty->assign($args['assign'], $function_name($args, $smarty));
+            $replace = '';
+        }
+
+        $params['results'] = substr_replace($params['results'], $replace, strpos($params['results'], $cached_inserts[$i]), strlen($cached_inserts[$i]));
+        if ($smarty->debugging) {
+            $_params = array();
+            require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
+            $smarty->_smarty_debug_info[] = array('type'      => 'insert',
+                                                'filename'  => 'insert_'.$name,
+                                                'depth'     => $smarty->_inclusion_depth,
+                                                'exec_time' => smarty_core_get_microtime($_params, $smarty) - $debug_start_time);
+        }
+    }
+
+    return $params['results'];
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/internals/core.process_compiled_include.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/internals/core.process_compiled_include.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/internals/core.process_compiled_include.php	(revision 3278)
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Replace nocache-tags by results of the corresponding non-cacheable
+ * functions and return it
+ *
+ * @param string $compiled_tpl
+ * @param string $cached_source
+ * @return string
+ */
+
+function smarty_core_process_compiled_include($params, &$smarty)
+{
+    $_cache_including = $smarty->_cache_including;
+    $smarty->_cache_including = true;
+
+    $_return = $params['results'];
+
+    foreach ($smarty->_cache_info['cache_serials'] as $_include_file_path=>$_cache_serial) {
+        $smarty->_include($_include_file_path, true);
+    }
+
+    foreach ($smarty->_cache_info['cache_serials'] as $_include_file_path=>$_cache_serial) {
+        $_return = preg_replace_callback('!(\{nocache\:('.$_cache_serial.')#(\d+)\})!s',
+                                         array(&$smarty, '_process_compiled_include_callback'),
+                                         $_return);
+    }
+    $smarty->_cache_including = $_cache_including;
+    return $_return;
+}
+
+?>
Index: /tags/2.0.2/include/smarty/libs/internals/core.read_cache_file.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/internals/core.read_cache_file.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/internals/core.read_cache_file.php	(revision 3278)
@@ -0,0 +1,101 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * read a cache file, determine if it needs to be
+ * regenerated or not
+ *
+ * @param string $tpl_file
+ * @param string $cache_id
+ * @param string $compile_id
+ * @param string $results
+ * @return boolean
+ */
+
+//  $tpl_file, $cache_id, $compile_id, &$results
+
+function smarty_core_read_cache_file(&$params, &$smarty)
+{
+    static  $content_cache = array();
+
+    if ($smarty->force_compile) {
+        // force compile enabled, always regenerate
+        return false;
+    }
+
+    if (isset($content_cache[$params['tpl_file'].','.$params['cache_id'].','.$params['compile_id']])) {
+        list($params['results'], $smarty->_cache_info) = $content_cache[$params['tpl_file'].','.$params['cache_id'].','.$params['compile_id']];
+        return true;
+    }
+
+    if (!empty($smarty->cache_handler_func)) {
+        // use cache_handler function
+        call_user_func_array($smarty->cache_handler_func,
+                             array('read', &$smarty, &$params['results'], $params['tpl_file'], $params['cache_id'], $params['compile_id'], null));
+    } else {
+        // use local cache file
+        $_auto_id = $smarty->_get_auto_id($params['cache_id'], $params['compile_id']);
+        $_cache_file = $smarty->_get_auto_filename($smarty->cache_dir, $params['tpl_file'], $_auto_id);
+        $params['results'] = $smarty->_read_file($_cache_file);
+    }
+
+    if (empty($params['results'])) {
+        // nothing to parse (error?), regenerate cache
+        return false;
+    }
+
+    $_contents = $params['results'];
+    $_info_start = strpos($_contents, "\n") + 1;
+    $_info_len = (int)substr($_contents, 0, $_info_start - 1);
+    $_cache_info = unserialize(substr($_contents, $_info_start, $_info_len));
+    $params['results'] = substr($_contents, $_info_start + $_info_len);
+
+    if ($smarty->caching == 2 && isset ($_cache_info['expires'])){
+        // caching by expiration time
+        if ($_cache_info['expires'] > -1 && (time() > $_cache_info['expires'])) {
+            // cache expired, regenerate
+            return false;
+        }
+    } else {
+        // caching by lifetime
+        if ($smarty->cache_lifetime > -1 && (time() - $_cache_info['timestamp'] > $smarty->cache_lifetime)) {
+            // cache expired, regenerate
+            return false;
+        }
+    }
+
+    if ($smarty->compile_check) {
+        $_params = array('get_source' => false, 'quiet'=>true);
+        foreach (array_keys($_cache_info['template']) as $_template_dep) {
+            $_params['resource_name'] = $_template_dep;
+            if (!$smarty->_fetch_resource_info($_params) || $_cache_info['timestamp'] < $_params['resource_timestamp']) {
+                // template file has changed, regenerate cache
+                return false;
+            }
+        }
+
+        if (isset($_cache_info['config'])) {
+            $_params = array('resource_base_path' => $smarty->config_dir, 'get_source' => false, 'quiet'=>true);
+            foreach (array_keys($_cache_info['config']) as $_config_dep) {
+                $_params['resource_name'] = $_config_dep;
+                if (!$smarty->_fetch_resource_info($_params) || $_cache_info['timestamp'] < $_params['resource_timestamp']) {
+                    // config file has changed, regenerate cache
+                    return false;
+                }
+            }
+        }
+    }
+
+    $content_cache[$params['tpl_file'].','.$params['cache_id'].','.$params['compile_id']] = array($params['results'], $_cache_info);
+
+    $smarty->_cache_info = $_cache_info;
+    return true;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/internals/core.rm_auto.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/internals/core.rm_auto.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/internals/core.rm_auto.php	(revision 3278)
@@ -0,0 +1,71 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * delete an automagically created file by name and id
+ *
+ * @param string $auto_base
+ * @param string $auto_source
+ * @param string $auto_id
+ * @param integer $exp_time
+ * @return boolean
+ */
+
+// $auto_base, $auto_source = null, $auto_id = null, $exp_time = null
+
+function smarty_core_rm_auto($params, &$smarty)
+{
+    if (!@is_dir($params['auto_base']))
+      return false;
+
+    if(!isset($params['auto_id']) && !isset($params['auto_source'])) {
+        $_params = array(
+            'dirname' => $params['auto_base'],
+            'level' => 0,
+            'exp_time' => $params['exp_time']
+        );
+        require_once(SMARTY_CORE_DIR . 'core.rmdir.php');
+        $_res = smarty_core_rmdir($_params, $smarty);
+    } else {
+        $_tname = $smarty->_get_auto_filename($params['auto_base'], $params['auto_source'], $params['auto_id']);
+
+        if(isset($params['auto_source'])) {
+            if (isset($params['extensions'])) {
+                $_res = false;
+                foreach ((array)$params['extensions'] as $_extension)
+                    $_res |= $smarty->_unlink($_tname.$_extension, $params['exp_time']);
+            } else {
+                $_res = $smarty->_unlink($_tname, $params['exp_time']);
+            }
+        } elseif ($smarty->use_sub_dirs) {
+            $_params = array(
+                'dirname' => $_tname,
+                'level' => 1,
+                'exp_time' => $params['exp_time']
+            );
+            require_once(SMARTY_CORE_DIR . 'core.rmdir.php');
+            $_res = smarty_core_rmdir($_params, $smarty);
+        } else {
+            // remove matching file names
+            $_handle = opendir($params['auto_base']);
+            $_res = true;
+            while (false !== ($_filename = readdir($_handle))) {
+                if($_filename == '.' || $_filename == '..') {
+                    continue;
+                } elseif (substr($params['auto_base'] . DIRECTORY_SEPARATOR . $_filename, 0, strlen($_tname)) == $_tname) {
+                    $_res &= (bool)$smarty->_unlink($params['auto_base'] . DIRECTORY_SEPARATOR . $_filename, $params['exp_time']);
+                }
+            }
+        }
+    }
+
+    return $_res;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/internals/core.rmdir.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/internals/core.rmdir.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/internals/core.rmdir.php	(revision 3278)
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * delete a dir recursively (level=0 -> keep root)
+ * WARNING: no tests, it will try to remove what you tell it!
+ *
+ * @param string $dirname
+ * @param integer $level
+ * @param integer $exp_time
+ * @return boolean
+ */
+
+//  $dirname, $level = 1, $exp_time = null
+
+function smarty_core_rmdir($params, &$smarty)
+{
+   if(!isset($params['level'])) { $params['level'] = 1; }
+   if(!isset($params['exp_time'])) { $params['exp_time'] = null; }
+
+   if($_handle = @opendir($params['dirname'])) {
+
+        while (false !== ($_entry = readdir($_handle))) {
+            if ($_entry != '.' && $_entry != '..') {
+                if (@is_dir($params['dirname'] . DIRECTORY_SEPARATOR . $_entry)) {
+                    $_params = array(
+                        'dirname' => $params['dirname'] . DIRECTORY_SEPARATOR . $_entry,
+                        'level' => $params['level'] + 1,
+                        'exp_time' => $params['exp_time']
+                    );
+                    smarty_core_rmdir($_params, $smarty);
+                }
+                else {
+                    $smarty->_unlink($params['dirname'] . DIRECTORY_SEPARATOR . $_entry, $params['exp_time']);
+                }
+            }
+        }
+        closedir($_handle);
+   }
+
+   if ($params['level']) {
+       return @rmdir($params['dirname']);
+   }
+   return (bool)$_handle;
+
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/internals/core.run_insert_handler.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/internals/core.run_insert_handler.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/internals/core.run_insert_handler.php	(revision 3278)
@@ -0,0 +1,71 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Handle insert tags
+ *
+ * @param array $args
+ * @return string
+ */
+function smarty_core_run_insert_handler($params, &$smarty)
+{
+
+    require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
+    if ($smarty->debugging) {
+        $_params = array();
+        $_debug_start_time = smarty_core_get_microtime($_params, $smarty);
+    }
+
+    if ($smarty->caching) {
+        $_arg_string = serialize($params['args']);
+        $_name = $params['args']['name'];
+        if (!isset($smarty->_cache_info['insert_tags'][$_name])) {
+            $smarty->_cache_info['insert_tags'][$_name] = array('insert',
+                                                             $_name,
+                                                             $smarty->_plugins['insert'][$_name][1],
+                                                             $smarty->_plugins['insert'][$_name][2],
+                                                             !empty($params['args']['script']) ? true : false);
+        }
+        return $smarty->_smarty_md5."{insert_cache $_arg_string}".$smarty->_smarty_md5;
+    } else {
+        if (isset($params['args']['script'])) {
+            $_params = array('resource_name' => $smarty->_dequote($params['args']['script']));
+            require_once(SMARTY_CORE_DIR . 'core.get_php_resource.php');
+            if(!smarty_core_get_php_resource($_params, $smarty)) {
+                return false;
+            }
+
+            if ($_params['resource_type'] == 'file') {
+                $smarty->_include($_params['php_resource'], true);
+            } else {
+                $smarty->_eval($_params['php_resource']);
+            }
+            unset($params['args']['script']);
+        }
+
+        $_funcname = $smarty->_plugins['insert'][$params['args']['name']][0];
+        $_content = $_funcname($params['args'], $smarty);
+        if ($smarty->debugging) {
+            $_params = array();
+            require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
+            $smarty->_smarty_debug_info[] = array('type'      => 'insert',
+                                                'filename'  => 'insert_'.$params['args']['name'],
+                                                'depth'     => $smarty->_inclusion_depth,
+                                                'exec_time' => smarty_core_get_microtime($_params, $smarty) - $_debug_start_time);
+        }
+
+        if (!empty($params['args']["assign"])) {
+            $smarty->assign($params['args']["assign"], $_content);
+        } else {
+            return $_content;
+        }
+    }
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/internals/core.smarty_include_php.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/internals/core.smarty_include_php.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/internals/core.smarty_include_php.php	(revision 3278)
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * called for included php files within templates
+ *
+ * @param string $smarty_file
+ * @param string $smarty_assign variable to assign the included template's
+ *               output into
+ * @param boolean $smarty_once uses include_once if this is true
+ * @param array $smarty_include_vars associative array of vars from
+ *              {include file="blah" var=$var}
+ */
+
+//  $file, $assign, $once, $_smarty_include_vars
+
+function smarty_core_smarty_include_php($params, &$smarty)
+{
+    $_params = array('resource_name' => $params['smarty_file']);
+    require_once(SMARTY_CORE_DIR . 'core.get_php_resource.php');
+    smarty_core_get_php_resource($_params, $smarty);
+    $_smarty_resource_type = $_params['resource_type'];
+    $_smarty_php_resource = $_params['php_resource'];
+
+    if (!empty($params['smarty_assign'])) {
+        ob_start();
+        if ($_smarty_resource_type == 'file') {
+            $smarty->_include($_smarty_php_resource, $params['smarty_once'], $params['smarty_include_vars']);
+        } else {
+            $smarty->_eval($_smarty_php_resource, $params['smarty_include_vars']);
+        }
+        $smarty->assign($params['smarty_assign'], ob_get_contents());
+        ob_end_clean();
+    } else {
+        if ($_smarty_resource_type == 'file') {
+            $smarty->_include($_smarty_php_resource, $params['smarty_once'], $params['smarty_include_vars']);
+        } else {
+            $smarty->_eval($_smarty_php_resource, $params['smarty_include_vars']);
+        }
+    }
+}
+
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/internals/core.write_cache_file.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/internals/core.write_cache_file.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/internals/core.write_cache_file.php	(revision 3278)
@@ -0,0 +1,96 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Prepend the cache information to the cache file
+ * and write it
+ *
+ * @param string $tpl_file
+ * @param string $cache_id
+ * @param string $compile_id
+ * @param string $results
+ * @return true|null
+ */
+
+ // $tpl_file, $cache_id, $compile_id, $results
+
+function smarty_core_write_cache_file($params, &$smarty)
+{
+
+    // put timestamp in cache header
+    $smarty->_cache_info['timestamp'] = time();
+    if ($smarty->cache_lifetime > -1){
+        // expiration set
+        $smarty->_cache_info['expires'] = $smarty->_cache_info['timestamp'] + $smarty->cache_lifetime;
+    } else {
+        // cache will never expire
+        $smarty->_cache_info['expires'] = -1;
+    }
+
+    // collapse nocache.../nocache-tags
+    if (preg_match_all('!\{(/?)nocache\:[0-9a-f]{32}#\d+\}!', $params['results'], $match, PREG_PATTERN_ORDER)) {
+        // remove everything between every pair of outermost noache.../nocache-tags
+        // and replace it by a single nocache-tag
+        // this new nocache-tag will be replaced by dynamic contents in
+        // smarty_core_process_compiled_includes() on a cache-read
+        
+        $match_count = count($match[0]);
+        $results = preg_split('!(\{/?nocache\:[0-9a-f]{32}#\d+\})!', $params['results'], -1, PREG_SPLIT_DELIM_CAPTURE);
+        
+        $level = 0;
+        $j = 0;
+        for ($i=0, $results_count = count($results); $i < $results_count && $j < $match_count; $i++) {
+            if ($results[$i] == $match[0][$j]) {
+                // nocache tag
+                if ($match[1][$j]) { // closing tag
+                    $level--;
+                    unset($results[$i]);
+                } else { // opening tag
+                    if ($level++ > 0) unset($results[$i]);
+                }
+                $j++;
+            } elseif ($level > 0) {
+                unset($results[$i]);
+            }
+        }
+        $params['results'] = implode('', $results);
+    }
+    $smarty->_cache_info['cache_serials'] = $smarty->_cache_serials;
+
+    // prepend the cache header info into cache file
+    $_cache_info = serialize($smarty->_cache_info);
+    $params['results'] = strlen($_cache_info) . "\n" . $_cache_info . $params['results'];
+
+    if (!empty($smarty->cache_handler_func)) {
+        // use cache_handler function
+        call_user_func_array($smarty->cache_handler_func,
+                             array('write', &$smarty, &$params['results'], $params['tpl_file'], $params['cache_id'], $params['compile_id'], $smarty->_cache_info['expires']));
+    } else {
+        // use local cache file
+
+        if(!@is_writable($smarty->cache_dir)) {
+            // cache_dir not writable, see if it exists
+            if(!@is_dir($smarty->cache_dir)) {
+                $smarty->trigger_error('the $cache_dir \'' . $smarty->cache_dir . '\' does not exist, or is not a directory.', E_USER_ERROR);
+                return false;
+            }
+            $smarty->trigger_error('unable to write to $cache_dir \'' . realpath($smarty->cache_dir) . '\'. Be sure $cache_dir is writable by the web server user.', E_USER_ERROR);
+            return false;
+        }
+
+        $_auto_id = $smarty->_get_auto_id($params['cache_id'], $params['compile_id']);
+        $_cache_file = $smarty->_get_auto_filename($smarty->cache_dir, $params['tpl_file'], $_auto_id);
+        $_params = array('filename' => $_cache_file, 'contents' => $params['results'], 'create_dirs' => true);
+        require_once(SMARTY_CORE_DIR . 'core.write_file.php');
+        smarty_core_write_file($_params, $smarty);
+        return true;
+    }
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/internals/core.write_compiled_include.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/internals/core.write_compiled_include.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/internals/core.write_compiled_include.php	(revision 3278)
@@ -0,0 +1,91 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Extract non-cacheable parts out of compiled template and write it
+ *
+ * @param string $compile_path
+ * @param string $template_compiled
+ * @return boolean
+ */
+
+function smarty_core_write_compiled_include($params, &$smarty)
+{
+    $_tag_start = 'if \(\$this->caching && \!\$this->_cache_including\)\: echo \'\{nocache\:('.$params['cache_serial'].')#(\d+)\}\'; endif;';
+    $_tag_end   = 'if \(\$this->caching && \!\$this->_cache_including\)\: echo \'\{/nocache\:(\\2)#(\\3)\}\'; endif;';
+
+    preg_match_all('!('.$_tag_start.'(.*)'.$_tag_end.')!Us',
+                   $params['compiled_content'], $_match_source, PREG_SET_ORDER);
+    
+    // no nocache-parts found: done
+    if (count($_match_source)==0) return;
+
+    // convert the matched php-code to functions
+    $_include_compiled =  "<?php /* Smarty version ".$smarty->_version.", created on ".strftime("%Y-%m-%d %H:%M:%S")."\n";
+    $_include_compiled .= "         compiled from " . strtr(urlencode($params['resource_name']), array('%2F'=>'/', '%3A'=>':')) . " */\n\n";
+
+    $_compile_path = $params['include_file_path'];
+
+    $smarty->_cache_serials[$_compile_path] = $params['cache_serial'];
+    $_include_compiled .= "\$this->_cache_serials['".$_compile_path."'] = '".$params['cache_serial']."';\n\n?>";
+
+    $_include_compiled .= $params['plugins_code'];
+    $_include_compiled .= "<?php";
+
+    $this_varname = ((double)phpversion() >= 5.0) ? '_smarty' : 'this';
+    for ($_i = 0, $_for_max = count($_match_source); $_i < $_for_max; $_i++) {
+        $_match =& $_match_source[$_i];
+        $source = $_match[4];
+        if ($this_varname == '_smarty') {
+            /* rename $this to $_smarty in the sourcecode */
+            $tokens = token_get_all('<?php ' . $_match[4]);
+
+            /* remove trailing <?php */
+            $open_tag = '';
+            while ($tokens) {
+                $token = array_shift($tokens);
+                if (is_array($token)) {
+                    $open_tag .= $token[1];
+                } else {
+                    $open_tag .= $token;
+                }
+                if ($open_tag == '<?php ') break;
+            }
+
+            for ($i=0, $count = count($tokens); $i < $count; $i++) {
+                if (is_array($tokens[$i])) {
+                    if ($tokens[$i][0] == T_VARIABLE && $tokens[$i][1] == '$this') {
+                        $tokens[$i] = '$' . $this_varname;
+                    } else {
+                        $tokens[$i] = $tokens[$i][1];
+                    }                   
+                }
+            }
+            $source = implode('', $tokens);
+        }
+
+        /* add function to compiled include */
+        $_include_compiled .= "
+function _smarty_tplfunc_$_match[2]_$_match[3](&\$$this_varname)
+{
+$source
+}
+
+";
+    }
+    $_include_compiled .= "\n\n?>\n";
+
+    $_params = array('filename' => $_compile_path,
+                     'contents' => $_include_compiled, 'create_dirs' => true);
+
+    require_once(SMARTY_CORE_DIR . 'core.write_file.php');
+    smarty_core_write_file($_params, $smarty);
+    return true;
+}
+
+
+?>
Index: /tags/2.0.2/include/smarty/libs/internals/core.write_compiled_resource.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/internals/core.write_compiled_resource.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/internals/core.write_compiled_resource.php	(revision 3278)
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * write the compiled resource
+ *
+ * @param string $compile_path
+ * @param string $compiled_content
+ * @return true
+ */
+function smarty_core_write_compiled_resource($params, &$smarty)
+{
+    if(!@is_writable($smarty->compile_dir)) {
+        // compile_dir not writable, see if it exists
+        if(!@is_dir($smarty->compile_dir)) {
+            $smarty->trigger_error('the $compile_dir \'' . $smarty->compile_dir . '\' does not exist, or is not a directory.', E_USER_ERROR);
+            return false;
+        }
+        $smarty->trigger_error('unable to write to $compile_dir \'' . realpath($smarty->compile_dir) . '\'. Be sure $compile_dir is writable by the web server user.', E_USER_ERROR);
+        return false;
+    }
+
+    $_params = array('filename' => $params['compile_path'], 'contents' => $params['compiled_content'], 'create_dirs' => true);
+    require_once(SMARTY_CORE_DIR . 'core.write_file.php');
+    smarty_core_write_file($_params, $smarty);
+    return true;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/internals/core.write_file.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/internals/core.write_file.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/internals/core.write_file.php	(revision 3278)
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * write out a file to disk
+ *
+ * @param string $filename
+ * @param string $contents
+ * @param boolean $create_dirs
+ * @return boolean
+ */
+function smarty_core_write_file($params, &$smarty)
+{
+    $_dirname = dirname($params['filename']);
+
+    if ($params['create_dirs']) {
+        $_params = array('dir' => $_dirname);
+        require_once(SMARTY_CORE_DIR . 'core.create_dir_structure.php');
+        smarty_core_create_dir_structure($_params, $smarty);
+    }
+
+    // write to tmp file, then rename it to avoid file locking race condition
+    $_tmp_file = tempnam($_dirname, 'wrt');
+
+    if (!($fd = @fopen($_tmp_file, 'wb'))) {
+        $_tmp_file = $_dirname . DIRECTORY_SEPARATOR . uniqid('wrt');
+        if (!($fd = @fopen($_tmp_file, 'wb'))) {
+            $smarty->trigger_error("problem writing temporary file '$_tmp_file'");
+            return false;
+        }
+    }
+
+    fwrite($fd, $params['contents']);
+    fclose($fd);
+
+    if (DIRECTORY_SEPARATOR == '\\' || !@rename($_tmp_file, $params['filename'])) {
+        // On platforms and filesystems that cannot overwrite with rename() 
+        // delete the file before renaming it -- because windows always suffers
+        // this, it is short-circuited to avoid the initial rename() attempt
+        @unlink($params['filename']);
+        @rename($_tmp_file, $params['filename']);
+    }
+    @chmod($params['filename'], $smarty->_file_perms);
+
+    return true;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/plugins/block.textformat.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/plugins/block.textformat.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/plugins/block.textformat.php	(revision 3278)
@@ -0,0 +1,103 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Smarty {textformat}{/textformat} block plugin
+ *
+ * Type:     block function<br>
+ * Name:     textformat<br>
+ * Purpose:  format text a certain way with preset styles
+ *           or custom wrap/indent settings<br>
+ * @link http://smarty.php.net/manual/en/language.function.textformat.php {textformat}
+ *       (Smarty online manual)
+ * @param array
+ * <pre>
+ * Params:   style: string (email)
+ *           indent: integer (0)
+ *           wrap: integer (80)
+ *           wrap_char string ("\n")
+ *           indent_char: string (" ")
+ *           wrap_boundary: boolean (true)
+ * </pre>
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @param string contents of the block
+ * @param Smarty clever simulation of a method
+ * @return string string $content re-formatted
+ */
+function smarty_block_textformat($params, $content, &$smarty)
+{
+    if (is_null($content)) {
+        return;
+    }
+
+    $style = null;
+    $indent = 0;
+    $indent_first = 0;
+    $indent_char = ' ';
+    $wrap = 80;
+    $wrap_char = "\n";
+    $wrap_cut = false;
+    $assign = null;
+    
+    foreach ($params as $_key => $_val) {
+        switch ($_key) {
+            case 'style':
+            case 'indent_char':
+            case 'wrap_char':
+            case 'assign':
+                $$_key = (string)$_val;
+                break;
+
+            case 'indent':
+            case 'indent_first':
+            case 'wrap':
+                $$_key = (int)$_val;
+                break;
+
+            case 'wrap_cut':
+                $$_key = (bool)$_val;
+                break;
+
+            default:
+                $smarty->trigger_error("textformat: unknown attribute '$_key'");
+        }
+    }
+
+    if ($style == 'email') {
+        $wrap = 72;
+    }
+
+    // split into paragraphs
+    $_paragraphs = preg_split('![\r\n][\r\n]!',$content);
+    $_output = '';
+
+    for($_x = 0, $_y = count($_paragraphs); $_x < $_y; $_x++) {
+        if ($_paragraphs[$_x] == '') {
+            continue;
+        }
+        // convert mult. spaces & special chars to single space
+        $_paragraphs[$_x] = preg_replace(array('!\s+!','!(^\s+)|(\s+$)!'), array(' ',''), $_paragraphs[$_x]);
+        // indent first line
+        if($indent_first > 0) {
+            $_paragraphs[$_x] = str_repeat($indent_char, $indent_first) . $_paragraphs[$_x];
+        }
+        // wordwrap sentences
+        $_paragraphs[$_x] = wordwrap($_paragraphs[$_x], $wrap - $indent, $wrap_char, $wrap_cut);
+        // indent lines
+        if($indent > 0) {
+            $_paragraphs[$_x] = preg_replace('!^!m', str_repeat($indent_char, $indent), $_paragraphs[$_x]);
+        }
+    }
+    $_output = implode($wrap_char . $wrap_char, $_paragraphs);
+
+    return $assign ? $smarty->assign($assign, $_output) : $_output;
+
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/plugins/compiler.assign.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/plugins/compiler.assign.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/plugins/compiler.assign.php	(revision 3278)
@@ -0,0 +1,40 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Smarty {assign} compiler function plugin
+ *
+ * Type:     compiler function<br>
+ * Name:     assign<br>
+ * Purpose:  assign a value to a template variable
+ * @link http://smarty.php.net/manual/en/language.custom.functions.php#LANGUAGE.FUNCTION.ASSIGN {assign}
+ *       (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com> (initial author)
+ * @author messju mohr <messju at lammfellpuschen dot de> (conversion to compiler function)
+ * @param string containing var-attribute and value-attribute
+ * @param Smarty_Compiler
+ */
+function smarty_compiler_assign($tag_attrs, &$compiler)
+{
+    $_params = $compiler->_parse_attrs($tag_attrs);
+
+    if (!isset($_params['var'])) {
+        $compiler->_syntax_error("assign: missing 'var' parameter", E_USER_WARNING);
+        return;
+    }
+
+    if (!isset($_params['value'])) {
+        $compiler->_syntax_error("assign: missing 'value' parameter", E_USER_WARNING);
+        return;
+    }
+
+    return "\$this->assign({$_params['var']}, {$_params['value']});";
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/plugins/function.assign_debug_info.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/plugins/function.assign_debug_info.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/plugins/function.assign_debug_info.php	(revision 3278)
@@ -0,0 +1,40 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Smarty {assign_debug_info} function plugin
+ *
+ * Type:     function<br>
+ * Name:     assign_debug_info<br>
+ * Purpose:  assign debug info to the template<br>
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @param array unused in this plugin, this plugin uses {@link Smarty::$_config},
+ *              {@link Smarty::$_tpl_vars} and {@link Smarty::$_smarty_debug_info}
+ * @param Smarty
+ */
+function smarty_function_assign_debug_info($params, &$smarty)
+{
+    $assigned_vars = $smarty->_tpl_vars;
+    ksort($assigned_vars);
+    if (@is_array($smarty->_config[0])) {
+        $config_vars = $smarty->_config[0];
+        ksort($config_vars);
+        $smarty->assign("_debug_config_keys", array_keys($config_vars));
+        $smarty->assign("_debug_config_vals", array_values($config_vars));
+    }
+    
+    $included_templates = $smarty->_smarty_debug_info;
+    
+    $smarty->assign("_debug_keys", array_keys($assigned_vars));
+    $smarty->assign("_debug_vals", array_values($assigned_vars));
+    
+    $smarty->assign("_debug_tpls", $included_templates);
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/plugins/function.config_load.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/plugins/function.config_load.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/plugins/function.config_load.php	(revision 3278)
@@ -0,0 +1,142 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Smarty {config_load} function plugin
+ *
+ * Type:     function<br>
+ * Name:     config_load<br>
+ * Purpose:  load config file vars
+ * @link http://smarty.php.net/manual/en/language.function.config.load.php {config_load}
+ *       (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @author messju mohr <messju at lammfellpuschen dot de> (added use of resources)
+ * @param array Format:
+ * <pre>
+ * array('file' => required config file name,
+ *       'section' => optional config file section to load
+ *       'scope' => local/parent/global
+ *       'global' => overrides scope, setting to parent if true)
+ * </pre>
+ * @param Smarty
+ */
+function smarty_function_config_load($params, &$smarty)
+{
+        if ($smarty->debugging) {
+            $_params = array();
+            require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
+            $_debug_start_time = smarty_core_get_microtime($_params, $smarty);
+        }
+
+        $_file = isset($params['file']) ? $smarty->_dequote($params['file']) : null;
+        $_section = isset($params['section']) ? $smarty->_dequote($params['section']) : null;
+        $_scope = isset($params['scope']) ? $smarty->_dequote($params['scope']) : 'global';
+        $_global = isset($params['global']) ? $smarty->_dequote($params['global']) : false;
+
+        if (!isset($_file) || strlen($_file) == 0) {
+            $smarty->trigger_error("missing 'file' attribute in config_load tag", E_USER_ERROR, __FILE__, __LINE__);
+        }
+
+        if (isset($_scope)) {
+            if ($_scope != 'local' &&
+                $_scope != 'parent' &&
+                $_scope != 'global') {
+                $smarty->trigger_error("invalid 'scope' attribute value", E_USER_ERROR, __FILE__, __LINE__);
+            }
+        } else {
+            if ($_global) {
+                $_scope = 'parent';
+            } else {
+                $_scope = 'local';
+            }
+        }
+
+        $_params = array('resource_name' => $_file,
+                         'resource_base_path' => $smarty->config_dir,
+                         'get_source' => false);
+        $smarty->_parse_resource_name($_params);
+        $_file_path = $_params['resource_type'] . ':' . $_params['resource_name'];
+        if (isset($_section))
+            $_compile_file = $smarty->_get_compile_path($_file_path.'|'.$_section);
+        else
+            $_compile_file = $smarty->_get_compile_path($_file_path);
+
+        if($smarty->force_compile || !file_exists($_compile_file)) {
+            $_compile = true;
+        } elseif ($smarty->compile_check) {
+            $_params = array('resource_name' => $_file,
+                             'resource_base_path' => $smarty->config_dir,
+                             'get_source' => false);
+            $_compile = $smarty->_fetch_resource_info($_params) &&
+                $_params['resource_timestamp'] > filemtime($_compile_file);
+        } else {
+            $_compile = false;
+        }
+
+        if($_compile) {
+            // compile config file
+            if(!is_object($smarty->_conf_obj)) {
+                require_once SMARTY_DIR . $smarty->config_class . '.class.php';
+                $smarty->_conf_obj = new $smarty->config_class();
+                $smarty->_conf_obj->overwrite = $smarty->config_overwrite;
+                $smarty->_conf_obj->booleanize = $smarty->config_booleanize;
+                $smarty->_conf_obj->read_hidden = $smarty->config_read_hidden;
+                $smarty->_conf_obj->fix_newlines = $smarty->config_fix_newlines;
+            }
+
+            $_params = array('resource_name' => $_file,
+                             'resource_base_path' => $smarty->config_dir,
+                             $_params['get_source'] = true);
+            if (!$smarty->_fetch_resource_info($_params)) {
+                return;
+            }
+            $smarty->_conf_obj->set_file_contents($_file, $_params['source_content']);
+            $_config_vars = array_merge($smarty->_conf_obj->get($_file),
+                    $smarty->_conf_obj->get($_file, $_section));
+            if(function_exists('var_export')) {
+                $_output = '<?php $_config_vars = ' . var_export($_config_vars, true) . '; ?>';
+            } else {
+                $_output = '<?php $_config_vars = unserialize(\'' . strtr(serialize($_config_vars),array('\''=>'\\\'', '\\'=>'\\\\')) . '\'); ?>';
+            }
+            $_params = (array('compile_path' => $_compile_file, 'compiled_content' => $_output, 'resource_timestamp' => $_params['resource_timestamp']));
+            require_once(SMARTY_CORE_DIR . 'core.write_compiled_resource.php');
+            smarty_core_write_compiled_resource($_params, $smarty);
+        } else {
+            include($_compile_file);
+        }
+
+        if ($smarty->caching) {
+            $smarty->_cache_info['config'][$_file] = true;
+        }
+
+        $smarty->_config[0]['vars'] = @array_merge($smarty->_config[0]['vars'], $_config_vars);
+        $smarty->_config[0]['files'][$_file] = true;
+
+        if ($_scope == 'parent') {
+                $smarty->_config[1]['vars'] = @array_merge($smarty->_config[1]['vars'], $_config_vars);
+                $smarty->_config[1]['files'][$_file] = true;
+        } else if ($_scope == 'global') {
+            for ($i = 1, $for_max = count($smarty->_config); $i < $for_max; $i++) {
+                $smarty->_config[$i]['vars'] = @array_merge($smarty->_config[$i]['vars'], $_config_vars);
+                $smarty->_config[$i]['files'][$_file] = true;
+            }
+        }
+
+        if ($smarty->debugging) {
+            $_params = array();
+            require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
+            $smarty->_smarty_debug_info[] = array('type'      => 'config',
+                                                'filename'  => $_file.' ['.$_section.'] '.$_scope,
+                                                'depth'     => $smarty->_inclusion_depth,
+                                                'exec_time' => smarty_core_get_microtime($_params, $smarty) - $_debug_start_time);
+        }
+
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/plugins/function.counter.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/plugins/function.counter.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/plugins/function.counter.php	(revision 3278)
@@ -0,0 +1,80 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {counter} function plugin
+ *
+ * Type:     function<br>
+ * Name:     counter<br>
+ * Purpose:  print out a counter value
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @link http://smarty.php.net/manual/en/language.function.counter.php {counter}
+ *       (Smarty online manual)
+ * @param array parameters
+ * @param Smarty
+ * @return string|null
+ */
+function smarty_function_counter($params, &$smarty)
+{
+    static $counters = array();
+
+    $name = (isset($params['name'])) ? $params['name'] : 'default';
+    if (!isset($counters[$name])) {
+        $counters[$name] = array(
+            'start'=>1,
+            'skip'=>1,
+            'direction'=>'up',
+            'count'=>1
+            );
+    }
+    $counter =& $counters[$name];
+
+    if (isset($params['start'])) {
+        $counter['start'] = $counter['count'] = (int)$params['start'];
+    }
+
+    if (!empty($params['assign'])) {
+        $counter['assign'] = $params['assign'];
+    }
+
+    if (isset($counter['assign'])) {
+        $smarty->assign($counter['assign'], $counter['count']);
+    }
+    
+    if (isset($params['print'])) {
+        $print = (bool)$params['print'];
+    } else {
+        $print = empty($counter['assign']);
+    }
+
+    if ($print) {
+        $retval = $counter['count'];
+    } else {
+        $retval = null;
+    }
+
+    if (isset($params['skip'])) {
+        $counter['skip'] = $params['skip'];
+    }
+    
+    if (isset($params['direction'])) {
+        $counter['direction'] = $params['direction'];
+    }
+
+    if ($counter['direction'] == "down")
+        $counter['count'] -= $counter['skip'];
+    else
+        $counter['count'] += $counter['skip'];
+    
+    return $retval;
+    
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/plugins/function.cycle.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/plugins/function.cycle.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/plugins/function.cycle.php	(revision 3278)
@@ -0,0 +1,102 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Smarty {cycle} function plugin
+ *
+ * Type:     function<br>
+ * Name:     cycle<br>
+ * Date:     May 3, 2002<br>
+ * Purpose:  cycle through given values<br>
+ * Input:
+ *         - name = name of cycle (optional)
+ *         - values = comma separated list of values to cycle,
+ *                    or an array of values to cycle
+ *                    (this can be left out for subsequent calls)
+ *         - reset = boolean - resets given var to true
+ *         - print = boolean - print var or not. default is true
+ *         - advance = boolean - whether or not to advance the cycle
+ *         - delimiter = the value delimiter, default is ","
+ *         - assign = boolean, assigns to template var instead of
+ *                    printed.
+ *
+ * Examples:<br>
+ * <pre>
+ * {cycle values="#eeeeee,#d0d0d0d"}
+ * {cycle name=row values="one,two,three" reset=true}
+ * {cycle name=row}
+ * </pre>
+ * @link http://smarty.php.net/manual/en/language.function.cycle.php {cycle}
+ *       (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @author credit to Mark Priatel <mpriatel@rogers.com>
+ * @author credit to Gerard <gerard@interfold.com>
+ * @author credit to Jason Sweat <jsweat_php@yahoo.com>
+ * @version  1.3
+ * @param array
+ * @param Smarty
+ * @return string|null
+ */
+function smarty_function_cycle($params, &$smarty)
+{
+    static $cycle_vars;
+    
+    $name = (empty($params['name'])) ? 'default' : $params['name'];
+    $print = (isset($params['print'])) ? (bool)$params['print'] : true;
+    $advance = (isset($params['advance'])) ? (bool)$params['advance'] : true;
+    $reset = (isset($params['reset'])) ? (bool)$params['reset'] : false;
+            
+    if (!in_array('values', array_keys($params))) {
+        if(!isset($cycle_vars[$name]['values'])) {
+            $smarty->trigger_error("cycle: missing 'values' parameter");
+            return;
+        }
+    } else {
+        if(isset($cycle_vars[$name]['values'])
+            && $cycle_vars[$name]['values'] != $params['values'] ) {
+            $cycle_vars[$name]['index'] = 0;
+        }
+        $cycle_vars[$name]['values'] = $params['values'];
+    }
+
+    $cycle_vars[$name]['delimiter'] = (isset($params['delimiter'])) ? $params['delimiter'] : ',';
+    
+    if(is_array($cycle_vars[$name]['values'])) {
+        $cycle_array = $cycle_vars[$name]['values'];
+    } else {
+        $cycle_array = explode($cycle_vars[$name]['delimiter'],$cycle_vars[$name]['values']);
+    }
+    
+    if(!isset($cycle_vars[$name]['index']) || $reset ) {
+        $cycle_vars[$name]['index'] = 0;
+    }
+    
+    if (isset($params['assign'])) {
+        $print = false;
+        $smarty->assign($params['assign'], $cycle_array[$cycle_vars[$name]['index']]);
+    }
+        
+    if($print) {
+        $retval = $cycle_array[$cycle_vars[$name]['index']];
+    } else {
+        $retval = null;
+    }
+
+    if($advance) {
+        if ( $cycle_vars[$name]['index'] >= count($cycle_array) -1 ) {
+            $cycle_vars[$name]['index'] = 0;
+        } else {
+            $cycle_vars[$name]['index']++;
+        }
+    }
+    
+    return $retval;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/plugins/function.debug.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/plugins/function.debug.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/plugins/function.debug.php	(revision 3278)
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {debug} function plugin
+ *
+ * Type:     function<br>
+ * Name:     debug<br>
+ * Date:     July 1, 2002<br>
+ * Purpose:  popup debug window
+ * @link http://smarty.php.net/manual/en/language.function.debug.php {debug}
+ *       (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @version  1.0
+ * @param array
+ * @param Smarty
+ * @return string output from {@link Smarty::_generate_debug_output()}
+ */
+function smarty_function_debug($params, &$smarty)
+{
+    if (isset($params['output'])) {
+        $smarty->assign('_smarty_debug_output', $params['output']);
+    }
+    require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php');
+    return smarty_core_display_debug_console(null, $smarty);
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/plugins/function.eval.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/plugins/function.eval.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/plugins/function.eval.php	(revision 3278)
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {eval} function plugin
+ *
+ * Type:     function<br>
+ * Name:     eval<br>
+ * Purpose:  evaluate a template variable as a template<br>
+ * @link http://smarty.php.net/manual/en/language.function.eval.php {eval}
+ *       (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @param array
+ * @param Smarty
+ */
+function smarty_function_eval($params, &$smarty)
+{
+
+    if (!isset($params['var'])) {
+        $smarty->trigger_error("eval: missing 'var' parameter");
+        return;
+    }
+
+    if($params['var'] == '') {
+        return;
+    }
+
+    $smarty->_compile_source('evaluated template', $params['var'], $_var_compiled);
+
+    ob_start();
+    $smarty->_eval('?>' . $_var_compiled);
+    $_contents = ob_get_contents();
+    ob_end_clean();
+
+    if (!empty($params['assign'])) {
+        $smarty->assign($params['assign'], $_contents);
+    } else {
+        return $_contents;
+    }
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/plugins/function.fetch.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/plugins/function.fetch.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/plugins/function.fetch.php	(revision 3278)
@@ -0,0 +1,221 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {fetch} plugin
+ *
+ * Type:     function<br>
+ * Name:     fetch<br>
+ * Purpose:  fetch file, web or ftp data and display results
+ * @link http://smarty.php.net/manual/en/language.function.fetch.php {fetch}
+ *       (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @param array
+ * @param Smarty
+ * @return string|null if the assign parameter is passed, Smarty assigns the
+ *                     result to a template variable
+ */
+function smarty_function_fetch($params, &$smarty)
+{
+    if (empty($params['file'])) {
+        $smarty->_trigger_fatal_error("[plugin] parameter 'file' cannot be empty");
+        return;
+    }
+
+    $content = '';
+    if ($smarty->security && !preg_match('!^(http|ftp)://!i', $params['file'])) {
+        $_params = array('resource_type' => 'file', 'resource_name' => $params['file']);
+        require_once(SMARTY_CORE_DIR . 'core.is_secure.php');
+        if(!smarty_core_is_secure($_params, $smarty)) {
+            $smarty->_trigger_fatal_error('[plugin] (secure mode) fetch \'' . $params['file'] . '\' is not allowed');
+            return;
+        }
+        
+        // fetch the file
+        if($fp = @fopen($params['file'],'r')) {
+            while(!feof($fp)) {
+                $content .= fgets ($fp,4096);
+            }
+            fclose($fp);
+        } else {
+            $smarty->_trigger_fatal_error('[plugin] fetch cannot read file \'' . $params['file'] . '\'');
+            return;
+        }
+    } else {
+        // not a local file
+        if(preg_match('!^http://!i',$params['file'])) {
+            // http fetch
+            if($uri_parts = parse_url($params['file'])) {
+                // set defaults
+                $host = $server_name = $uri_parts['host'];
+                $timeout = 30;
+                $accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*";
+                $agent = "Smarty Template Engine ".$smarty->_version;
+                $referer = "";
+                $uri = !empty($uri_parts['path']) ? $uri_parts['path'] : '/';
+                $uri .= !empty($uri_parts['query']) ? '?' . $uri_parts['query'] : '';
+                $_is_proxy = false;
+                if(empty($uri_parts['port'])) {
+                    $port = 80;
+                } else {
+                    $port = $uri_parts['port'];
+                }
+                if(!empty($uri_parts['user'])) {
+                    $user = $uri_parts['user'];
+                }
+                if(!empty($uri_parts['pass'])) {
+                    $pass = $uri_parts['pass'];
+                }
+                // loop through parameters, setup headers
+                foreach($params as $param_key => $param_value) {
+                    switch($param_key) {
+                        case "file":
+                        case "assign":
+                        case "assign_headers":
+                            break;
+                        case "user":
+                            if(!empty($param_value)) {
+                                $user = $param_value;
+                            }
+                            break;
+                        case "pass":
+                            if(!empty($param_value)) {
+                                $pass = $param_value;
+                            }
+                            break;
+                        case "accept":
+                            if(!empty($param_value)) {
+                                $accept = $param_value;
+                            }
+                            break;
+                        case "header":
+                            if(!empty($param_value)) {
+                                if(!preg_match('![\w\d-]+: .+!',$param_value)) {
+                                    $smarty->_trigger_fatal_error("[plugin] invalid header format '".$param_value."'");
+                                    return;
+                                } else {
+                                    $extra_headers[] = $param_value;
+                                }
+                            }
+                            break;
+                        case "proxy_host":
+                            if(!empty($param_value)) {
+                                $proxy_host = $param_value;
+                            }
+                            break;
+                        case "proxy_port":
+                            if(!preg_match('!\D!', $param_value)) {
+                                $proxy_port = (int) $param_value;
+                            } else {
+                                $smarty->_trigger_fatal_error("[plugin] invalid value for attribute '".$param_key."'");
+                                return;
+                            }
+                            break;
+                        case "agent":
+                            if(!empty($param_value)) {
+                                $agent = $param_value;
+                            }
+                            break;
+                        case "referer":
+                            if(!empty($param_value)) {
+                                $referer = $param_value;
+                            }
+                            break;
+                        case "timeout":
+                            if(!preg_match('!\D!', $param_value)) {
+                                $timeout = (int) $param_value;
+                            } else {
+                                $smarty->_trigger_fatal_error("[plugin] invalid value for attribute '".$param_key."'");
+                                return;
+                            }
+                            break;
+                        default:
+                            $smarty->_trigger_fatal_error("[plugin] unrecognized attribute '".$param_key."'");
+                            return;
+                    }
+                }
+                if(!empty($proxy_host) && !empty($proxy_port)) {
+                    $_is_proxy = true;
+                    $fp = fsockopen($proxy_host,$proxy_port,$errno,$errstr,$timeout);
+                } else {
+                    $fp = fsockopen($server_name,$port,$errno,$errstr,$timeout);
+                }
+
+                if(!$fp) {
+                    $smarty->_trigger_fatal_error("[plugin] unable to fetch: $errstr ($errno)");
+                    return;
+                } else {
+                    if($_is_proxy) {
+                        fputs($fp, 'GET ' . $params['file'] . " HTTP/1.0\r\n");
+                    } else {
+                        fputs($fp, "GET $uri HTTP/1.0\r\n");
+                    }
+                    if(!empty($host)) {
+                        fputs($fp, "Host: $host\r\n");
+                    }
+                    if(!empty($accept)) {
+                        fputs($fp, "Accept: $accept\r\n");
+                    }
+                    if(!empty($agent)) {
+                        fputs($fp, "User-Agent: $agent\r\n");
+                    }
+                    if(!empty($referer)) {
+                        fputs($fp, "Referer: $referer\r\n");
+                    }
+                    if(isset($extra_headers) && is_array($extra_headers)) {
+                        foreach($extra_headers as $curr_header) {
+                            fputs($fp, $curr_header."\r\n");
+                        }
+                    }
+                    if(!empty($user) && !empty($pass)) {
+                        fputs($fp, "Authorization: BASIC ".base64_encode("$user:$pass")."\r\n");
+                    }
+
+                    fputs($fp, "\r\n");
+                    while(!feof($fp)) {
+                        $content .= fgets($fp,4096);
+                    }
+                    fclose($fp);
+                    $csplit = split("\r\n\r\n",$content,2);
+
+                    $content = $csplit[1];
+
+                    if(!empty($params['assign_headers'])) {
+                        $smarty->assign($params['assign_headers'],split("\r\n",$csplit[0]));
+                    }
+                }
+            } else {
+                $smarty->_trigger_fatal_error("[plugin] unable to parse URL, check syntax");
+                return;
+            }
+        } else {
+            // ftp fetch
+            if($fp = @fopen($params['file'],'r')) {
+                while(!feof($fp)) {
+                    $content .= fgets ($fp,4096);
+                }
+                fclose($fp);
+            } else {
+                $smarty->_trigger_fatal_error('[plugin] fetch cannot read file \'' . $params['file'] .'\'');
+                return;
+            }
+        }
+
+    }
+
+
+    if (!empty($params['assign'])) {
+        $smarty->assign($params['assign'],$content);
+    } else {
+        return $content;
+    }
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/plugins/function.html_checkboxes.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/plugins/function.html_checkboxes.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/plugins/function.html_checkboxes.php	(revision 3278)
@@ -0,0 +1,143 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {html_checkboxes} function plugin
+ *
+ * File:       function.html_checkboxes.php<br>
+ * Type:       function<br>
+ * Name:       html_checkboxes<br>
+ * Date:       24.Feb.2003<br>
+ * Purpose:    Prints out a list of checkbox input types<br>
+ * Input:<br>
+ *           - name       (optional) - string default "checkbox"
+ *           - values     (required) - array
+ *           - options    (optional) - associative array
+ *           - checked    (optional) - array default not set
+ *           - separator  (optional) - ie <br> or &nbsp;
+ *           - output     (optional) - the output next to each checkbox
+ *           - assign     (optional) - assign the output as an array to this variable
+ * Examples:
+ * <pre>
+ * {html_checkboxes values=$ids output=$names}
+ * {html_checkboxes values=$ids name='box' separator='<br>' output=$names}
+ * {html_checkboxes values=$ids checked=$checked separator='<br>' output=$names}
+ * </pre>
+ * @link http://smarty.php.net/manual/en/language.function.html.checkboxes.php {html_checkboxes}
+ *      (Smarty online manual)
+ * @author     Christopher Kvarme <christopher.kvarme@flashjab.com>
+ * @author credits to Monte Ohrt <monte at ohrt dot com>
+ * @version    1.0
+ * @param array
+ * @param Smarty
+ * @return string
+ * @uses smarty_function_escape_special_chars()
+ */
+function smarty_function_html_checkboxes($params, &$smarty)
+{
+    require_once $smarty->_get_plugin_filepath('shared','escape_special_chars');
+
+    $name = 'checkbox';
+    $values = null;
+    $options = null;
+    $selected = null;
+    $separator = '';
+    $labels = true;
+    $output = null;
+
+    $extra = '';
+
+    foreach($params as $_key => $_val) {
+        switch($_key) {
+            case 'name':
+            case 'separator':
+                $$_key = $_val;
+                break;
+
+            case 'labels':
+                $$_key = (bool)$_val;
+                break;
+
+            case 'options':
+                $$_key = (array)$_val;
+                break;
+
+            case 'values':
+            case 'output':
+                $$_key = array_values((array)$_val);
+                break;
+
+            case 'checked':
+            case 'selected':
+                $selected = array_map('strval', array_values((array)$_val));
+                break;
+
+            case 'checkboxes':
+                $smarty->trigger_error('html_checkboxes: the use of the "checkboxes" attribute is deprecated, use "options" instead', E_USER_WARNING);
+                $options = (array)$_val;
+                break;
+
+            case 'assign':
+                break;
+
+            default:
+                if(!is_array($_val)) {
+                    $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"';
+                } else {
+                    $smarty->trigger_error("html_checkboxes: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
+                }
+                break;
+        }
+    }
+
+    if (!isset($options) && !isset($values))
+        return ''; /* raise error here? */
+
+    settype($selected, 'array');
+    $_html_result = array();
+
+    if (isset($options)) {
+
+        foreach ($options as $_key=>$_val)
+            $_html_result[] = smarty_function_html_checkboxes_output($name, $_key, $_val, $selected, $extra, $separator, $labels);
+
+
+    } else {
+        foreach ($values as $_i=>$_key) {
+            $_val = isset($output[$_i]) ? $output[$_i] : '';
+            $_html_result[] = smarty_function_html_checkboxes_output($name, $_key, $_val, $selected, $extra, $separator, $labels);
+        }
+
+    }
+
+    if(!empty($params['assign'])) {
+        $smarty->assign($params['assign'], $_html_result);
+    } else {
+        return implode("\n",$_html_result);
+    }
+
+}
+
+function smarty_function_html_checkboxes_output($name, $value, $output, $selected, $extra, $separator, $labels) {
+    $_output = '';
+    if ($labels) $_output .= '<label>';
+    $_output .= '<input type="checkbox" name="'
+        . smarty_function_escape_special_chars($name) . '[]" value="'
+        . smarty_function_escape_special_chars($value) . '"';
+
+    if (in_array((string)$value, $selected)) {
+        $_output .= ' checked="checked"';
+    }
+    $_output .= $extra . ' />' . $output;
+    if ($labels) $_output .= '</label>';
+    $_output .=  $separator;
+
+    return $_output;
+}
+
+?>
Index: /tags/2.0.2/include/smarty/libs/plugins/function.html_image.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/plugins/function.html_image.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/plugins/function.html_image.php	(revision 3278)
@@ -0,0 +1,142 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {html_image} function plugin
+ *
+ * Type:     function<br>
+ * Name:     html_image<br>
+ * Date:     Feb 24, 2003<br>
+ * Purpose:  format HTML tags for the image<br>
+ * Input:<br>
+ *         - file = file (and path) of image (required)
+ *         - height = image height (optional, default actual height)
+ *         - width = image width (optional, default actual width)
+ *         - basedir = base directory for absolute paths, default
+ *                     is environment variable DOCUMENT_ROOT
+ *         - path_prefix = prefix for path output (optional, default empty)
+ *
+ * Examples: {html_image file="/images/masthead.gif"}
+ * Output:   <img src="/images/masthead.gif" width=400 height=23>
+ * @link http://smarty.php.net/manual/en/language.function.html.image.php {html_image}
+ *      (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @author credits to Duda <duda@big.hu> - wrote first image function
+ *           in repository, helped with lots of functionality
+ * @version  1.0
+ * @param array
+ * @param Smarty
+ * @return string
+ * @uses smarty_function_escape_special_chars()
+ */
+function smarty_function_html_image($params, &$smarty)
+{
+    require_once $smarty->_get_plugin_filepath('shared','escape_special_chars');
+    
+    $alt = '';
+    $file = '';
+    $height = '';
+    $width = '';
+    $extra = '';
+    $prefix = '';
+    $suffix = '';
+    $path_prefix = '';
+    $server_vars = ($smarty->request_use_auto_globals) ? $_SERVER : $GLOBALS['HTTP_SERVER_VARS'];
+    $basedir = isset($server_vars['DOCUMENT_ROOT']) ? $server_vars['DOCUMENT_ROOT'] : '';
+    foreach($params as $_key => $_val) {
+        switch($_key) {
+            case 'file':
+            case 'height':
+            case 'width':
+            case 'dpi':
+            case 'path_prefix':
+            case 'basedir':
+                $$_key = $_val;
+                break;
+
+            case 'alt':
+                if(!is_array($_val)) {
+                    $$_key = smarty_function_escape_special_chars($_val);
+                } else {
+                    $smarty->trigger_error("html_image: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
+                }
+                break;
+
+            case 'link':
+            case 'href':
+                $prefix = '<a href="' . $_val . '">';
+                $suffix = '</a>';
+                break;
+
+            default:
+                if(!is_array($_val)) {
+                    $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"';
+                } else {
+                    $smarty->trigger_error("html_image: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
+                }
+                break;
+        }
+    }
+
+    if (empty($file)) {
+        $smarty->trigger_error("html_image: missing 'file' parameter", E_USER_NOTICE);
+        return;
+    }
+
+    if (substr($file,0,1) == '/') {
+        $_image_path = $basedir . $file;
+    } else {
+        $_image_path = $file;
+    }
+    
+    if(!isset($params['width']) || !isset($params['height'])) {
+        if(!$_image_data = @getimagesize($_image_path)) {
+            if(!file_exists($_image_path)) {
+                $smarty->trigger_error("html_image: unable to find '$_image_path'", E_USER_NOTICE);
+                return;
+            } else if(!is_readable($_image_path)) {
+                $smarty->trigger_error("html_image: unable to read '$_image_path'", E_USER_NOTICE);
+                return;
+            } else {
+                $smarty->trigger_error("html_image: '$_image_path' is not a valid image file", E_USER_NOTICE);
+                return;
+            }
+        }
+        if ($smarty->security &&
+            ($_params = array('resource_type' => 'file', 'resource_name' => $_image_path)) &&
+            (require_once(SMARTY_CORE_DIR . 'core.is_secure.php')) &&
+            (!smarty_core_is_secure($_params, $smarty)) ) {
+            $smarty->trigger_error("html_image: (secure) '$_image_path' not in secure directory", E_USER_NOTICE);
+        }        
+        
+        if(!isset($params['width'])) {
+            $width = $_image_data[0];
+        }
+        if(!isset($params['height'])) {
+            $height = $_image_data[1];
+        }
+
+    }
+
+    if(isset($params['dpi'])) {
+        if(strstr($server_vars['HTTP_USER_AGENT'], 'Mac')) {
+            $dpi_default = 72;
+        } else {
+            $dpi_default = 96;
+        }
+        $_resize = $dpi_default/$params['dpi'];
+        $width = round($width * $_resize);
+        $height = round($height * $_resize);
+    }
+
+    return $prefix . '<img src="'.$path_prefix.$file.'" alt="'.$alt.'" width="'.$width.'" height="'.$height.'"'.$extra.' />' . $suffix;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/plugins/function.html_options.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/plugins/function.html_options.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/plugins/function.html_options.php	(revision 3278)
@@ -0,0 +1,122 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {html_options} function plugin
+ *
+ * Type:     function<br>
+ * Name:     html_options<br>
+ * Input:<br>
+ *           - name       (optional) - string default "select"
+ *           - values     (required if no options supplied) - array
+ *           - options    (required if no values supplied) - associative array
+ *           - selected   (optional) - string default not set
+ *           - output     (required if not options supplied) - array
+ * Purpose:  Prints the list of <option> tags generated from
+ *           the passed parameters
+ * @link http://smarty.php.net/manual/en/language.function.html.options.php {html_image}
+ *      (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @param array
+ * @param Smarty
+ * @return string
+ * @uses smarty_function_escape_special_chars()
+ */
+function smarty_function_html_options($params, &$smarty)
+{
+    require_once $smarty->_get_plugin_filepath('shared','escape_special_chars');
+    
+    $name = null;
+    $values = null;
+    $options = null;
+    $selected = array();
+    $output = null;
+    
+    $extra = '';
+    
+    foreach($params as $_key => $_val) {
+        switch($_key) {
+            case 'name':
+                $$_key = (string)$_val;
+                break;
+            
+            case 'options':
+                $$_key = (array)$_val;
+                break;
+                
+            case 'values':
+            case 'output':
+                $$_key = array_values((array)$_val);
+                break;
+
+            case 'selected':
+                $$_key = array_map('strval', array_values((array)$_val));
+                break;
+                
+            default:
+                if(!is_array($_val)) {
+                    $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"';
+                } else {
+                    $smarty->trigger_error("html_options: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
+                }
+                break;
+        }
+    }
+
+    if (!isset($options) && !isset($values))
+        return ''; /* raise error here? */
+
+    $_html_result = '';
+
+    if (isset($options)) {
+        
+        foreach ($options as $_key=>$_val)
+            $_html_result .= smarty_function_html_options_optoutput($_key, $_val, $selected);
+
+    } else {
+        
+        foreach ($values as $_i=>$_key) {
+            $_val = isset($output[$_i]) ? $output[$_i] : '';
+            $_html_result .= smarty_function_html_options_optoutput($_key, $_val, $selected);
+        }
+
+    }
+
+    if(!empty($name)) {
+        $_html_result = '<select name="' . $name . '"' . $extra . '>' . "\n" . $_html_result . '</select>' . "\n";
+    }
+
+    return $_html_result;
+
+}
+
+function smarty_function_html_options_optoutput($key, $value, $selected) {
+    if(!is_array($value)) {
+        $_html_result = '<option label="' . smarty_function_escape_special_chars($value) . '" value="' .
+            smarty_function_escape_special_chars($key) . '"';
+        if (in_array((string)$key, $selected))
+            $_html_result .= ' selected="selected"';
+        $_html_result .= '>' . smarty_function_escape_special_chars($value) . '</option>' . "\n";
+    } else {
+        $_html_result = smarty_function_html_options_optgroup($key, $value, $selected);
+    }
+    return $_html_result;
+}
+
+function smarty_function_html_options_optgroup($key, $values, $selected) {
+    $optgroup_html = '<optgroup label="' . smarty_function_escape_special_chars($key) . '">' . "\n";
+    foreach ($values as $key => $value) {
+        $optgroup_html .= smarty_function_html_options_optoutput($key, $value, $selected);
+    }
+    $optgroup_html .= "</optgroup>\n";
+    return $optgroup_html;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/plugins/function.html_radios.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/plugins/function.html_radios.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/plugins/function.html_radios.php	(revision 3278)
@@ -0,0 +1,156 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {html_radios} function plugin
+ *
+ * File:       function.html_radios.php<br>
+ * Type:       function<br>
+ * Name:       html_radios<br>
+ * Date:       24.Feb.2003<br>
+ * Purpose:    Prints out a list of radio input types<br>
+ * Input:<br>
+ *           - name       (optional) - string default "radio"
+ *           - values     (required) - array
+ *           - options    (optional) - associative array
+ *           - checked    (optional) - array default not set
+ *           - separator  (optional) - ie <br> or &nbsp;
+ *           - output     (optional) - the output next to each radio button
+ *           - assign     (optional) - assign the output as an array to this variable
+ * Examples:
+ * <pre>
+ * {html_radios values=$ids output=$names}
+ * {html_radios values=$ids name='box' separator='<br>' output=$names}
+ * {html_radios values=$ids checked=$checked separator='<br>' output=$names}
+ * </pre>
+ * @link http://smarty.php.net/manual/en/language.function.html.radios.php {html_radios}
+ *      (Smarty online manual)
+ * @author     Christopher Kvarme <christopher.kvarme@flashjab.com>
+ * @author credits to Monte Ohrt <monte at ohrt dot com>
+ * @version    1.0
+ * @param array
+ * @param Smarty
+ * @return string
+ * @uses smarty_function_escape_special_chars()
+ */
+function smarty_function_html_radios($params, &$smarty)
+{
+    require_once $smarty->_get_plugin_filepath('shared','escape_special_chars');
+   
+    $name = 'radio';
+    $values = null;
+    $options = null;
+    $selected = null;
+    $separator = '';
+    $labels = true;
+    $label_ids = false;
+    $output = null;
+    $extra = '';
+
+    foreach($params as $_key => $_val) {
+        switch($_key) {
+            case 'name':
+            case 'separator':
+                $$_key = (string)$_val;
+                break;
+
+            case 'checked':
+            case 'selected':
+                if(is_array($_val)) {
+                    $smarty->trigger_error('html_radios: the "' . $_key . '" attribute cannot be an array', E_USER_WARNING);
+                } else {
+                    $selected = (string)$_val;
+                }
+                break;
+
+            case 'labels':
+            case 'label_ids':
+                $$_key = (bool)$_val;
+                break;
+
+            case 'options':
+                $$_key = (array)$_val;
+                break;
+
+            case 'values':
+            case 'output':
+                $$_key = array_values((array)$_val);
+                break;
+
+            case 'radios':
+                $smarty->trigger_error('html_radios: the use of the "radios" attribute is deprecated, use "options" instead', E_USER_WARNING);
+                $options = (array)$_val;
+                break;
+
+            case 'assign':
+                break;
+
+            default:
+                if(!is_array($_val)) {
+                    $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"';
+                } else {
+                    $smarty->trigger_error("html_radios: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
+                }
+                break;
+        }
+    }
+
+    if (!isset($options) && !isset($values))
+        return ''; /* raise error here? */
+
+    $_html_result = array();
+
+    if (isset($options)) {
+
+        foreach ($options as $_key=>$_val)
+            $_html_result[] = smarty_function_html_radios_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids);
+
+    } else {
+
+        foreach ($values as $_i=>$_key) {
+            $_val = isset($output[$_i]) ? $output[$_i] : '';
+            $_html_result[] = smarty_function_html_radios_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids);
+        }
+
+    }
+
+    if(!empty($params['assign'])) {
+        $smarty->assign($params['assign'], $_html_result);
+    } else {
+        return implode("\n",$_html_result);
+    }
+
+}
+
+function smarty_function_html_radios_output($name, $value, $output, $selected, $extra, $separator, $labels, $label_ids) {
+    $_output = '';
+    if ($labels) {
+      if($label_ids) {
+          $_id = smarty_function_escape_special_chars(preg_replace('![^\w\-\.]!', '_', $name . '_' . $value));
+          $_output .= '<label for="' . $_id . '">';
+      } else {
+          $_output .= '<label>';           
+      }
+   }
+   $_output .= '<input type="radio" name="'
+        . smarty_function_escape_special_chars($name) . '" value="'
+        . smarty_function_escape_special_chars($value) . '"';
+
+   if ($labels && $label_ids) $_output .= ' id="' . $_id . '"';
+
+    if ((string)$value==$selected) {
+        $_output .= ' checked="checked"';
+    }
+    $_output .= $extra . ' />' . $output;
+    if ($labels) $_output .= '</label>';
+    $_output .=  $separator;
+
+    return $_output;
+}
+
+?>
Index: /tags/2.0.2/include/smarty/libs/plugins/function.html_select_date.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/plugins/function.html_select_date.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/plugins/function.html_select_date.php	(revision 3278)
@@ -0,0 +1,331 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Smarty {html_select_date} plugin
+ *
+ * Type:     function<br>
+ * Name:     html_select_date<br>
+ * Purpose:  Prints the dropdowns for date selection.
+ *
+ * ChangeLog:<br>
+ *           - 1.0 initial release
+ *           - 1.1 added support for +/- N syntax for begin
+ *                and end year values. (Monte)
+ *           - 1.2 added support for yyyy-mm-dd syntax for
+ *                time value. (Jan Rosier)
+ *           - 1.3 added support for choosing format for
+ *                month values (Gary Loescher)
+ *           - 1.3.1 added support for choosing format for
+ *                day values (Marcus Bointon)
+ *           - 1.3.2 support negative timestamps, force year
+ *             dropdown to include given date unless explicitly set (Monte)
+ *           - 1.3.4 fix behaviour of 0000-00-00 00:00:00 dates to match that
+ *             of 0000-00-00 dates (cybot, boots)
+ * @link http://smarty.php.net/manual/en/language.function.html.select.date.php {html_select_date}
+ *      (Smarty online manual)
+ * @version 1.3.4
+ * @author Andrei Zmievski
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @param array
+ * @param Smarty
+ * @return string
+ */
+function smarty_function_html_select_date($params, &$smarty)
+{
+    require_once $smarty->_get_plugin_filepath('shared','escape_special_chars');
+    require_once $smarty->_get_plugin_filepath('shared','make_timestamp');
+    require_once $smarty->_get_plugin_filepath('function','html_options');
+    /* Default values. */
+    $prefix          = "Date_";
+    $start_year      = strftime("%Y");
+    $end_year        = $start_year;
+    $display_days    = true;
+    $display_months  = true;
+    $display_years   = true;
+    $month_format    = "%B";
+    /* Write months as numbers by default  GL */
+    $month_value_format = "%m";
+    $day_format      = "%02d";
+    /* Write day values using this format MB */
+    $day_value_format = "%d";
+    $year_as_text    = false;
+    /* Display years in reverse order? Ie. 2000,1999,.... */
+    $reverse_years   = false;
+    /* Should the select boxes be part of an array when returned from PHP?
+       e.g. setting it to "birthday", would create "birthday[Day]",
+       "birthday[Month]" & "birthday[Year]". Can be combined with prefix */
+    $field_array     = null;
+    /* <select size>'s of the different <select> tags.
+       If not set, uses default dropdown. */
+    $day_size        = null;
+    $month_size      = null;
+    $year_size       = null;
+    /* Unparsed attributes common to *ALL* the <select>/<input> tags.
+       An example might be in the template: all_extra ='class ="foo"'. */
+    $all_extra       = null;
+    /* Separate attributes for the tags. */
+    $day_extra       = null;
+    $month_extra     = null;
+    $year_extra      = null;
+    /* Order in which to display the fields.
+       "D" -> day, "M" -> month, "Y" -> year. */
+    $field_order     = 'MDY';
+    /* String printed between the different fields. */
+    $field_separator = "\n";
+    $time = time();
+    $all_empty       = null;
+    $day_empty       = null;
+    $month_empty     = null;
+    $year_empty      = null;
+    $extra_attrs     = '';
+
+    foreach ($params as $_key=>$_value) {
+        switch ($_key) {
+            case 'prefix':
+            case 'time':
+            case 'start_year':
+            case 'end_year':
+            case 'month_format':
+            case 'day_format':
+            case 'day_value_format':
+            case 'field_array':
+            case 'day_size':
+            case 'month_size':
+            case 'year_size':
+            case 'all_extra':
+            case 'day_extra':
+            case 'month_extra':
+            case 'year_extra':
+            case 'field_order':
+            case 'field_separator':
+            case 'month_value_format':
+            case 'month_empty':
+            case 'day_empty':
+            case 'year_empty':
+                $$_key = (string)$_value;
+                break;
+
+            case 'all_empty':
+                $$_key = (string)$_value;
+                $day_empty = $month_empty = $year_empty = $all_empty;
+                break;
+
+            case 'display_days':
+            case 'display_months':
+            case 'display_years':
+            case 'year_as_text':
+            case 'reverse_years':
+                $$_key = (bool)$_value;
+                break;
+
+            default:
+                if(!is_array($_value)) {
+                    $extra_attrs .= ' '.$_key.'="'.smarty_function_escape_special_chars($_value).'"';
+                } else {
+                    $smarty->trigger_error("html_select_date: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
+                }
+                break;
+        }
+    }
+
+    if (preg_match('!^-\d+$!', $time)) {
+        // negative timestamp, use date()
+        $time = date('Y-m-d', $time);
+    }
+    // If $time is not in format yyyy-mm-dd
+    if (preg_match('/^(\d{0,4}-\d{0,2}-\d{0,2})/', $time, $found)) {
+        $time = $found[1];
+    } else {
+        // use smarty_make_timestamp to get an unix timestamp and
+        // strftime to make yyyy-mm-dd
+        $time = strftime('%Y-%m-%d', smarty_make_timestamp($time));
+    }
+    // Now split this in pieces, which later can be used to set the select
+    $time = explode("-", $time);
+
+    // make syntax "+N" or "-N" work with start_year and end_year
+    if (preg_match('!^(\+|\-)\s*(\d+)$!', $end_year, $match)) {
+        if ($match[1] == '+') {
+            $end_year = strftime('%Y') + $match[2];
+        } else {
+            $end_year = strftime('%Y') - $match[2];
+        }
+    }
+    if (preg_match('!^(\+|\-)\s*(\d+)$!', $start_year, $match)) {
+        if ($match[1] == '+') {
+            $start_year = strftime('%Y') + $match[2];
+        } else {
+            $start_year = strftime('%Y') - $match[2];
+        }
+    }
+    if (strlen($time[0]) > 0) {
+        if ($start_year > $time[0] && !isset($params['start_year'])) {
+            // force start year to include given date if not explicitly set
+            $start_year = $time[0];
+        }
+        if($end_year < $time[0] && !isset($params['end_year'])) {
+            // force end year to include given date if not explicitly set
+            $end_year = $time[0];
+        }
+    }
+
+    $field_order = strtoupper($field_order);
+
+    $html_result = $month_result = $day_result = $year_result = "";
+
+    $field_separator_count = -1;
+    if ($display_months) {
+    	$field_separator_count++;
+        $month_names = array();
+        $month_values = array();
+        if(isset($month_empty)) {
+            $month_names[''] = $month_empty;
+            $month_values[''] = '';
+        }
+        for ($i = 1; $i <= 12; $i++) {
+            $month_names[$i] = strftime($month_format, mktime(0, 0, 0, $i, 1, 2000));
+            $month_values[$i] = strftime($month_value_format, mktime(0, 0, 0, $i, 1, 2000));
+        }
+
+        $month_result .= '<select name=';
+        if (null !== $field_array){
+            $month_result .= '"' . $field_array . '[' . $prefix . 'Month]"';
+        } else {
+            $month_result .= '"' . $prefix . 'Month"';
+        }
+        if (null !== $month_size){
+            $month_result .= ' size="' . $month_size . '"';
+        }
+        if (null !== $month_extra){
+            $month_result .= ' ' . $month_extra;
+        }
+        if (null !== $all_extra){
+            $month_result .= ' ' . $all_extra;
+        }
+        $month_result .= $extra_attrs . '>'."\n";
+
+        $month_result .= smarty_function_html_options(array('output'     => $month_names,
+                                                            'values'     => $month_values,
+                                                            'selected'   => (int)$time[1] ? strftime($month_value_format, mktime(0, 0, 0, (int)$time[1], 1, 2000)) : '',
+                                                            'print_result' => false),
+                                                      $smarty);
+        $month_result .= '</select>';
+    }
+
+    if ($display_days) {
+    	$field_separator_count++;
+        $days = array();
+        if (isset($day_empty)) {
+            $days[''] = $day_empty;
+            $day_values[''] = '';
+        }
+        for ($i = 1; $i <= 31; $i++) {
+            $days[] = sprintf($day_format, $i);
+            $day_values[] = sprintf($day_value_format, $i);
+        }
+
+        $day_result .= '<select name=';
+        if (null !== $field_array){
+            $day_result .= '"' . $field_array . '[' . $prefix . 'Day]"';
+        } else {
+            $day_result .= '"' . $prefix . 'Day"';
+        }
+        if (null !== $day_size){
+            $day_result .= ' size="' . $day_size . '"';
+        }
+        if (null !== $all_extra){
+            $day_result .= ' ' . $all_extra;
+        }
+        if (null !== $day_extra){
+            $day_result .= ' ' . $day_extra;
+        }
+        $day_result .= $extra_attrs . '>'."\n";
+        $day_result .= smarty_function_html_options(array('output'     => $days,
+                                                          'values'     => $day_values,
+                                                          'selected'   => $time[2],
+                                                          'print_result' => false),
+                                                    $smarty);
+        $day_result .= '</select>';
+    }
+
+    if ($display_years) {
+    	$field_separator_count++;
+        if (null !== $field_array){
+            $year_name = $field_array . '[' . $prefix . 'Year]';
+        } else {
+            $year_name = $prefix . 'Year';
+        }
+        if ($year_as_text) {
+            $year_result .= '<input type="text" name="' . $year_name . '" value="' . $time[0] . '" size="4" maxlength="4"';
+            if (null !== $all_extra){
+                $year_result .= ' ' . $all_extra;
+            }
+            if (null !== $year_extra){
+                $year_result .= ' ' . $year_extra;
+            }
+            $year_result .= ' />';
+        } else {
+            $years = range((int)$start_year, (int)$end_year);
+            if ($reverse_years) {
+                rsort($years, SORT_NUMERIC);
+            } else {
+                sort($years, SORT_NUMERIC);
+            }
+            $yearvals = $years;
+            if(isset($year_empty)) {
+                array_unshift($years, $year_empty);
+                array_unshift($yearvals, '');
+            }
+            $year_result .= '<select name="' . $year_name . '"';
+            if (null !== $year_size){
+                $year_result .= ' size="' . $year_size . '"';
+            }
+            if (null !== $all_extra){
+                $year_result .= ' ' . $all_extra;
+            }
+            if (null !== $year_extra){
+                $year_result .= ' ' . $year_extra;
+            }
+            $year_result .= $extra_attrs . '>'."\n";
+            $year_result .= smarty_function_html_options(array('output' => $years,
+                                                               'values' => $yearvals,
+                                                               'selected'   => $time[0],
+                                                               'print_result' => false),
+                                                         $smarty);
+            $year_result .= '</select>';
+        }
+    }
+
+    // Loop thru the field_order field
+    for ($i = 0; $i <= 2; $i++){
+        $c = substr($field_order, $i, 1);
+        switch ($c){
+            case 'D':
+                $html_result .= $day_result;
+                break;
+
+            case 'M':
+                $html_result .= $month_result;
+                break;
+
+            case 'Y':
+                $html_result .= $year_result;
+                break;
+        }
+        // Add the field seperator
+        if($i < $field_separator_count) {
+            $html_result .= $field_separator;
+        }
+    }
+
+    return $html_result;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/plugins/function.html_select_time.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/plugins/function.html_select_time.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/plugins/function.html_select_time.php	(revision 3278)
@@ -0,0 +1,194 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {html_select_time} function plugin
+ *
+ * Type:     function<br>
+ * Name:     html_select_time<br>
+ * Purpose:  Prints the dropdowns for time selection
+ * @link http://smarty.php.net/manual/en/language.function.html.select.time.php {html_select_time}
+ *          (Smarty online manual)
+ * @author Roberto Berto <roberto@berto.net>
+ * @credits Monte Ohrt <monte AT ohrt DOT com>
+ * @param array
+ * @param Smarty
+ * @return string
+ * @uses smarty_make_timestamp()
+ */
+function smarty_function_html_select_time($params, &$smarty)
+{
+    require_once $smarty->_get_plugin_filepath('shared','make_timestamp');
+    require_once $smarty->_get_plugin_filepath('function','html_options');
+    /* Default values. */
+    $prefix             = "Time_";
+    $time               = time();
+    $display_hours      = true;
+    $display_minutes    = true;
+    $display_seconds    = true;
+    $display_meridian   = true;
+    $use_24_hours       = true;
+    $minute_interval    = 1;
+    $second_interval    = 1;
+    /* Should the select boxes be part of an array when returned from PHP?
+       e.g. setting it to "birthday", would create "birthday[Hour]",
+       "birthday[Minute]", "birthday[Seconds]" & "birthday[Meridian]".
+       Can be combined with prefix. */
+    $field_array        = null;
+    $all_extra          = null;
+    $hour_extra         = null;
+    $minute_extra       = null;
+    $second_extra       = null;
+    $meridian_extra     = null;
+
+    foreach ($params as $_key=>$_value) {
+        switch ($_key) {
+            case 'prefix':
+            case 'time':
+            case 'field_array':
+            case 'all_extra':
+            case 'hour_extra':
+            case 'minute_extra':
+            case 'second_extra':
+            case 'meridian_extra':
+                $$_key = (string)$_value;
+                break;
+
+            case 'display_hours':
+            case 'display_minutes':
+            case 'display_seconds':
+            case 'display_meridian':
+            case 'use_24_hours':
+                $$_key = (bool)$_value;
+                break;
+
+            case 'minute_interval':
+            case 'second_interval':
+                $$_key = (int)$_value;
+                break;
+
+            default:
+                $smarty->trigger_error("[html_select_time] unknown parameter $_key", E_USER_WARNING);
+        }
+    }
+
+    $time = smarty_make_timestamp($time);
+
+    $html_result = '';
+
+    if ($display_hours) {
+        $hours       = $use_24_hours ? range(0, 23) : range(1, 12);
+        $hour_fmt = $use_24_hours ? '%H' : '%I';
+        for ($i = 0, $for_max = count($hours); $i < $for_max; $i++)
+            $hours[$i] = sprintf('%02d', $hours[$i]);
+        $html_result .= '<select name=';
+        if (null !== $field_array) {
+            $html_result .= '"' . $field_array . '[' . $prefix . 'Hour]"';
+        } else {
+            $html_result .= '"' . $prefix . 'Hour"';
+        }
+        if (null !== $hour_extra){
+            $html_result .= ' ' . $hour_extra;
+        }
+        if (null !== $all_extra){
+            $html_result .= ' ' . $all_extra;
+        }
+        $html_result .= '>'."\n";
+        $html_result .= smarty_function_html_options(array('output'          => $hours,
+                                                           'values'          => $hours,
+                                                           'selected'      => strftime($hour_fmt, $time),
+                                                           'print_result' => false),
+                                                     $smarty);
+        $html_result .= "</select>\n";
+    }
+
+    if ($display_minutes) {
+        $all_minutes = range(0, 59);
+        for ($i = 0, $for_max = count($all_minutes); $i < $for_max; $i+= $minute_interval)
+            $minutes[] = sprintf('%02d', $all_minutes[$i]);
+        $selected = intval(floor(strftime('%M', $time) / $minute_interval) * $minute_interval);
+        $html_result .= '<select name=';
+        if (null !== $field_array) {
+            $html_result .= '"' . $field_array . '[' . $prefix . 'Minute]"';
+        } else {
+            $html_result .= '"' . $prefix . 'Minute"';
+        }
+        if (null !== $minute_extra){
+            $html_result .= ' ' . $minute_extra;
+        }
+        if (null !== $all_extra){
+            $html_result .= ' ' . $all_extra;
+        }
+        $html_result .= '>'."\n";
+        
+        $html_result .= smarty_function_html_options(array('output'          => $minutes,
+                                                           'values'          => $minutes,
+                                                           'selected'      => $selected,
+                                                           'print_result' => false),
+                                                     $smarty);
+        $html_result .= "</select>\n";
+    }
+
+    if ($display_seconds) {
+        $all_seconds = range(0, 59);
+        for ($i = 0, $for_max = count($all_seconds); $i < $for_max; $i+= $second_interval)
+            $seconds[] = sprintf('%02d', $all_seconds[$i]);
+        $selected = intval(floor(strftime('%S', $time) / $second_interval) * $second_interval);
+        $html_result .= '<select name=';
+        if (null !== $field_array) {
+            $html_result .= '"' . $field_array . '[' . $prefix . 'Second]"';
+        } else {
+            $html_result .= '"' . $prefix . 'Second"';
+        }
+        
+        if (null !== $second_extra){
+            $html_result .= ' ' . $second_extra;
+        }
+        if (null !== $all_extra){
+            $html_result .= ' ' . $all_extra;
+        }
+        $html_result .= '>'."\n";
+        
+        $html_result .= smarty_function_html_options(array('output'          => $seconds,
+                                                           'values'          => $seconds,
+                                                           'selected'      => $selected,
+                                                           'print_result' => false),
+                                                     $smarty);
+        $html_result .= "</select>\n";
+    }
+
+    if ($display_meridian && !$use_24_hours) {
+        $html_result .= '<select name=';
+        if (null !== $field_array) {
+            $html_result .= '"' . $field_array . '[' . $prefix . 'Meridian]"';
+        } else {
+            $html_result .= '"' . $prefix . 'Meridian"';
+        }
+        
+        if (null !== $meridian_extra){
+            $html_result .= ' ' . $meridian_extra;
+        }
+        if (null !== $all_extra){
+            $html_result .= ' ' . $all_extra;
+        }
+        $html_result .= '>'."\n";
+        
+        $html_result .= smarty_function_html_options(array('output'          => array('AM', 'PM'),
+                                                           'values'          => array('am', 'pm'),
+                                                           'selected'      => strtolower(strftime('%p', $time)),
+                                                           'print_result' => false),
+                                                     $smarty);
+        $html_result .= "</select>\n";
+    }
+
+    return $html_result;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/plugins/function.html_table.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/plugins/function.html_table.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/plugins/function.html_table.php	(revision 3278)
@@ -0,0 +1,177 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {html_table} function plugin
+ *
+ * Type:     function<br>
+ * Name:     html_table<br>
+ * Date:     Feb 17, 2003<br>
+ * Purpose:  make an html table from an array of data<br>
+ * Input:<br>
+ *         - loop = array to loop through
+ *         - cols = number of columns, comma separated list of column names
+ *                  or array of column names
+ *         - rows = number of rows
+ *         - table_attr = table attributes
+ *         - th_attr = table heading attributes (arrays are cycled)
+ *         - tr_attr = table row attributes (arrays are cycled)
+ *         - td_attr = table cell attributes (arrays are cycled)
+ *         - trailpad = value to pad trailing cells with
+ *         - caption = text for caption element 
+ *         - vdir = vertical direction (default: "down", means top-to-bottom)
+ *         - hdir = horizontal direction (default: "right", means left-to-right)
+ *         - inner = inner loop (default "cols": print $loop line by line,
+ *                   $loop will be printed column by column otherwise)
+ *
+ *
+ * Examples:
+ * <pre>
+ * {table loop=$data}
+ * {table loop=$data cols=4 tr_attr='"bgcolor=red"'}
+ * {table loop=$data cols="first,second,third" tr_attr=$colors}
+ * </pre>
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @author credit to Messju Mohr <messju at lammfellpuschen dot de>
+ * @author credit to boots <boots dot smarty at yahoo dot com>
+ * @version  1.1
+ * @link http://smarty.php.net/manual/en/language.function.html.table.php {html_table}
+ *          (Smarty online manual)
+ * @param array
+ * @param Smarty
+ * @return string
+ */
+function smarty_function_html_table($params, &$smarty)
+{
+    $table_attr = 'border="1"';
+    $tr_attr = '';
+    $th_attr = '';
+    $td_attr = '';
+    $cols = $cols_count = 3;
+    $rows = 3;
+    $trailpad = '&nbsp;';
+    $vdir = 'down';
+    $hdir = 'right';
+    $inner = 'cols';
+    $caption = '';
+
+    if (!isset($params['loop'])) {
+        $smarty->trigger_error("html_table: missing 'loop' parameter");
+        return;
+    }
+
+    foreach ($params as $_key=>$_value) {
+        switch ($_key) {
+            case 'loop':
+                $$_key = (array)$_value;
+                break;
+
+            case 'cols':
+                if (is_array($_value) && !empty($_value)) {
+                    $cols = $_value;
+                    $cols_count = count($_value);
+                } elseif (!is_numeric($_value) && is_string($_value) && !empty($_value)) {
+                    $cols = explode(',', $_value);
+                    $cols_count = count($cols);
+                } elseif (!empty($_value)) {
+                    $cols_count = (int)$_value;
+                } else {
+                    $cols_count = $cols;
+                }
+                break;
+
+            case 'rows':
+                $$_key = (int)$_value;
+                break;
+
+            case 'table_attr':
+            case 'trailpad':
+            case 'hdir':
+            case 'vdir':
+            case 'inner':
+            case 'caption':
+                $$_key = (string)$_value;
+                break;
+
+            case 'tr_attr':
+            case 'td_attr':
+            case 'th_attr':
+                $$_key = $_value;
+                break;
+        }
+    }
+
+    $loop_count = count($loop);
+    if (empty($params['rows'])) {
+        /* no rows specified */
+        $rows = ceil($loop_count/$cols_count);
+    } elseif (empty($params['cols'])) {
+        if (!empty($params['rows'])) {
+            /* no cols specified, but rows */
+            $cols_count = ceil($loop_count/$rows);
+        }
+    }
+
+    $output = "<table $table_attr>\n";
+
+    if (!empty($caption)) {
+        $output .= '<caption>' . $caption . "</caption>\n";
+    }
+
+    if (is_array($cols)) {
+        $cols = ($hdir == 'right') ? $cols : array_reverse($cols);
+        $output .= "<thead><tr>\n";
+
+        for ($r=0; $r<$cols_count; $r++) {
+            $output .= '<th' . smarty_function_html_table_cycle('th', $th_attr, $r) . '>';
+            $output .= $cols[$r];
+            $output .= "</th>\n";
+        }
+        $output .= "</tr></thead>\n";
+    }
+
+    $output .= "<tbody>\n";
+    for ($r=0; $r<$rows; $r++) {
+        $output .= "<tr" . smarty_function_html_table_cycle('tr', $tr_attr, $r) . ">\n";
+        $rx =  ($vdir == 'down') ? $r*$cols_count : ($rows-1-$r)*$cols_count;
+
+        for ($c=0; $c<$cols_count; $c++) {
+            $x =  ($hdir == 'right') ? $rx+$c : $rx+$cols_count-1-$c;
+            if ($inner!='cols') {
+                /* shuffle x to loop over rows*/
+                $x = floor($x/$cols_count) + ($x%$cols_count)*$rows;
+            }
+
+            if ($x<$loop_count) {
+                $output .= "<td" . smarty_function_html_table_cycle('td', $td_attr, $c) . ">" . $loop[$x] . "</td>\n";
+            } else {
+                $output .= "<td" . smarty_function_html_table_cycle('td', $td_attr, $c) . ">$trailpad</td>\n";
+            }
+        }
+        $output .= "</tr>\n";
+    }
+    $output .= "</tbody>\n";
+    $output .= "</table>\n";
+    
+    return $output;
+}
+
+function smarty_function_html_table_cycle($name, $var, $no) {
+    if(!is_array($var)) {
+        $ret = $var;
+    } else {
+        $ret = $var[$no % count($var)];
+    }
+    
+    return ($ret) ? ' '.$ret : '';
+}
+
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/plugins/function.mailto.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/plugins/function.mailto.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/plugins/function.mailto.php	(revision 3278)
@@ -0,0 +1,165 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {mailto} function plugin
+ *
+ * Type:     function<br>
+ * Name:     mailto<br>
+ * Date:     May 21, 2002
+ * Purpose:  automate mailto address link creation, and optionally
+ *           encode them.<br>
+ * Input:<br>
+ *         - address = e-mail address
+ *         - text = (optional) text to display, default is address
+ *         - encode = (optional) can be one of:
+ *                * none : no encoding (default)
+ *                * javascript : encode with javascript
+ *                * javascript_charcode : encode with javascript charcode
+ *                * hex : encode with hexidecimal (no javascript)
+ *         - cc = (optional) address(es) to carbon copy
+ *         - bcc = (optional) address(es) to blind carbon copy
+ *         - subject = (optional) e-mail subject
+ *         - newsgroups = (optional) newsgroup(s) to post to
+ *         - followupto = (optional) address(es) to follow up to
+ *         - extra = (optional) extra tags for the href link
+ *
+ * Examples:
+ * <pre>
+ * {mailto address="me@domain.com"}
+ * {mailto address="me@domain.com" encode="javascript"}
+ * {mailto address="me@domain.com" encode="hex"}
+ * {mailto address="me@domain.com" subject="Hello to you!"}
+ * {mailto address="me@domain.com" cc="you@domain.com,they@domain.com"}
+ * {mailto address="me@domain.com" extra='class="mailto"'}
+ * </pre>
+ * @link http://smarty.php.net/manual/en/language.function.mailto.php {mailto}
+ *          (Smarty online manual)
+ * @version  1.2
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @author   credits to Jason Sweat (added cc, bcc and subject functionality)
+ * @param    array
+ * @param    Smarty
+ * @return   string
+ */
+function smarty_function_mailto($params, &$smarty)
+{
+    $extra = '';
+
+    if (empty($params['address'])) {
+        $smarty->trigger_error("mailto: missing 'address' parameter");
+        return;
+    } else {
+        $address = $params['address'];
+    }
+
+    $text = $address;
+
+    // netscape and mozilla do not decode %40 (@) in BCC field (bug?)
+    // so, don't encode it.
+    $search = array('%40', '%2C');
+    $replace  = array('@', ',');
+    $mail_parms = array();
+    foreach ($params as $var=>$value) {
+        switch ($var) {
+            case 'cc':
+            case 'bcc':
+            case 'followupto':
+                if (!empty($value))
+                    $mail_parms[] = $var.'='.str_replace($search,$replace,rawurlencode($value));
+                break;
+                
+            case 'subject':
+            case 'newsgroups':
+                $mail_parms[] = $var.'='.rawurlencode($value);
+                break;
+
+            case 'extra':
+            case 'text':
+                $$var = $value;
+
+            default:
+        }
+    }
+
+    $mail_parm_vals = '';
+    for ($i=0; $i<count($mail_parms); $i++) {
+        $mail_parm_vals .= (0==$i) ? '?' : '&';
+        $mail_parm_vals .= $mail_parms[$i];
+    }
+    $address .= $mail_parm_vals;
+
+    $encode = (empty($params['encode'])) ? 'none' : $params['encode'];
+    if (!in_array($encode,array('javascript','javascript_charcode','hex','none')) ) {
+        $smarty->trigger_error("mailto: 'encode' parameter must be none, javascript or hex");
+        return;
+    }
+
+    if ($encode == 'javascript' ) {
+        $string = 'document.write(\'<a href="mailto:'.$address.'" '.$extra.'>'.$text.'</a>\');';
+
+        $js_encode = '';
+        for ($x=0; $x < strlen($string); $x++) {
+            $js_encode .= '%' . bin2hex($string[$x]);
+        }
+
+        return '<script type="text/javascript">eval(unescape(\''.$js_encode.'\'))</script>';
+
+    } elseif ($encode == 'javascript_charcode' ) {
+        $string = '<a href="mailto:'.$address.'" '.$extra.'>'.$text.'</a>';
+
+        for($x = 0, $y = strlen($string); $x < $y; $x++ ) {
+            $ord[] = ord($string[$x]);   
+        }
+
+        $_ret = "<script type=\"text/javascript\" language=\"javascript\">\n";
+        $_ret .= "<!--\n";
+        $_ret .= "{document.write(String.fromCharCode(";
+        $_ret .= implode(',',$ord);
+        $_ret .= "))";
+        $_ret .= "}\n";
+        $_ret .= "//-->\n";
+        $_ret .= "</script>\n";
+        
+        return $_ret;
+        
+        
+    } elseif ($encode == 'hex') {
+
+        preg_match('!^(.*)(\?.*)$!',$address,$match);
+        if(!empty($match[2])) {
+            $smarty->trigger_error("mailto: hex encoding does not work with extra attributes. Try javascript.");
+            return;
+        }
+        $address_encode = '';
+        for ($x=0; $x < strlen($address); $x++) {
+            if(preg_match('!\w!',$address[$x])) {
+                $address_encode .= '%' . bin2hex($address[$x]);
+            } else {
+                $address_encode .= $address[$x];
+            }
+        }
+        $text_encode = '';
+        for ($x=0; $x < strlen($text); $x++) {
+            $text_encode .= '&#x' . bin2hex($text[$x]).';';
+        }
+
+        $mailto = "&#109;&#97;&#105;&#108;&#116;&#111;&#58;";
+        return '<a href="'.$mailto.$address_encode.'" '.$extra.'>'.$text_encode.'</a>';
+
+    } else {
+        // no encoding
+        return '<a href="mailto:'.$address.'" '.$extra.'>'.$text.'</a>';
+
+    }
+
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/plugins/function.math.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/plugins/function.math.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/plugins/function.math.php	(revision 3278)
@@ -0,0 +1,84 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {math} function plugin
+ *
+ * Type:     function<br>
+ * Name:     math<br>
+ * Purpose:  handle math computations in template<br>
+ * @link http://smarty.php.net/manual/en/language.function.math.php {math}
+ *          (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param array
+ * @param Smarty
+ * @return string
+ */
+function smarty_function_math($params, &$smarty)
+{
+    // be sure equation parameter is present
+    if (empty($params['equation'])) {
+        $smarty->trigger_error("math: missing equation parameter");
+        return;
+    }
+
+    $equation = $params['equation'];
+
+    // make sure parenthesis are balanced
+    if (substr_count($equation,"(") != substr_count($equation,")")) {
+        $smarty->trigger_error("math: unbalanced parenthesis");
+        return;
+    }
+
+    // match all vars in equation, make sure all are passed
+    preg_match_all("!(?:0x[a-fA-F0-9]+)|([a-zA-Z][a-zA-Z0-9_]+)!",$equation, $match);
+    $allowed_funcs = array('int','abs','ceil','cos','exp','floor','log','log10',
+                           'max','min','pi','pow','rand','round','sin','sqrt','srand','tan');
+    
+    foreach($match[1] as $curr_var) {
+        if ($curr_var && !in_array($curr_var, array_keys($params)) && !in_array($curr_var, $allowed_funcs)) {
+            $smarty->trigger_error("math: function call $curr_var not allowed");
+            return;
+        }
+    }
+
+    foreach($params as $key => $val) {
+        if ($key != "equation" && $key != "format" && $key != "assign") {
+            // make sure value is not empty
+            if (strlen($val)==0) {
+                $smarty->trigger_error("math: parameter $key is empty");
+                return;
+            }
+            if (!is_numeric($val)) {
+                $smarty->trigger_error("math: parameter $key: is not numeric");
+                return;
+            }
+            $equation = preg_replace("/\b$key\b/", " \$params['$key'] ", $equation);
+        }
+    }
+
+    eval("\$smarty_math_result = ".$equation.";");
+
+    if (empty($params['format'])) {
+        if (empty($params['assign'])) {
+            return $smarty_math_result;
+        } else {
+            $smarty->assign($params['assign'],$smarty_math_result);
+        }
+    } else {
+        if (empty($params['assign'])){
+            printf($params['format'],$smarty_math_result);
+        } else {
+            $smarty->assign($params['assign'],sprintf($params['format'],$smarty_math_result));
+        }
+    }
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/plugins/function.popup.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/plugins/function.popup.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/plugins/function.popup.php	(revision 3278)
@@ -0,0 +1,119 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {popup} function plugin
+ *
+ * Type:     function<br>
+ * Name:     popup<br>
+ * Purpose:  make text pop up in windows via overlib
+ * @link http://smarty.php.net/manual/en/language.function.popup.php {popup}
+ *          (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param array
+ * @param Smarty
+ * @return string
+ */
+function smarty_function_popup($params, &$smarty)
+{
+    $append = '';
+    foreach ($params as $_key=>$_value) {
+        switch ($_key) {
+            case 'text':
+            case 'trigger':
+            case 'function':
+            case 'inarray':
+                $$_key = (string)$_value;
+                if ($_key == 'function' || $_key == 'inarray')
+                    $append .= ',' . strtoupper($_key) . ",'$_value'";
+                break;
+
+            case 'caption':
+            case 'closetext':
+            case 'status':
+                $append .= ',' . strtoupper($_key) . ",'" . str_replace("'","\'",$_value) . "'";
+                break;
+
+            case 'fgcolor':
+            case 'bgcolor':
+            case 'textcolor':
+            case 'capcolor':
+            case 'closecolor':
+            case 'textfont':
+            case 'captionfont':
+            case 'closefont':
+            case 'fgbackground':
+            case 'bgbackground':
+            case 'caparray':
+            case 'capicon':
+            case 'background':
+            case 'frame':
+                $append .= ',' . strtoupper($_key) . ",'$_value'";
+                break;
+
+            case 'textsize':
+            case 'captionsize':
+            case 'closesize':
+            case 'width':
+            case 'height':
+            case 'border':
+            case 'offsetx':
+            case 'offsety':
+            case 'snapx':
+            case 'snapy':
+            case 'fixx':
+            case 'fixy':
+            case 'padx':
+            case 'pady':
+            case 'timeout':
+            case 'delay':
+                $append .= ',' . strtoupper($_key) . ",$_value";
+                break;
+
+            case 'sticky':
+            case 'left':
+            case 'right':
+            case 'center':
+            case 'above':
+            case 'below':
+            case 'noclose':
+            case 'autostatus':
+            case 'autostatuscap':
+            case 'fullhtml':
+            case 'hauto':
+            case 'vauto':
+            case 'mouseoff':
+            case 'followmouse':
+            case 'closeclick':
+                if ($_value) $append .= ',' . strtoupper($_key);
+                break;
+
+            default:
+                $smarty->trigger_error("[popup] unknown parameter $_key", E_USER_WARNING);
+        }
+    }
+
+    if (empty($text) && !isset($inarray) && empty($function)) {
+        $smarty->trigger_error("overlib: attribute 'text' or 'inarray' or 'function' required");
+        return false;
+    }
+
+    if (empty($trigger)) { $trigger = "onmouseover"; }
+
+    $retval = $trigger . '="return overlib(\''.preg_replace(array("!'!","![\r\n]!"),array("\'",'\r'),$text).'\'';
+    $retval .= $append . ');"';
+    if ($trigger == 'onmouseover')
+       $retval .= ' onmouseout="nd();"';
+
+
+    return $retval;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/plugins/function.popup_init.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/plugins/function.popup_init.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/plugins/function.popup_init.php	(revision 3278)
@@ -0,0 +1,40 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {popup_init} function plugin
+ *
+ * Type:     function<br>
+ * Name:     popup_init<br>
+ * Purpose:  initialize overlib
+ * @link http://smarty.php.net/manual/en/language.function.popup.init.php {popup_init}
+ *          (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param array
+ * @param Smarty
+ * @return string
+ */
+function smarty_function_popup_init($params, &$smarty)
+{
+    $zindex = 1000;
+    
+    if (!empty($params['zindex'])) {
+        $zindex = $params['zindex'];
+    }
+    
+    if (!empty($params['src'])) {
+        return '<div id="overDiv" style="position:absolute; visibility:hidden; z-index:'.$zindex.';"></div>' . "\n"
+         . '<script type="text/javascript" language="JavaScript" src="'.$params['src'].'"></script>' . "\n";
+    } else {
+        $smarty->trigger_error("popup_init: missing src parameter");
+    }
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/plugins/modifier.capitalize.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/plugins/modifier.capitalize.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/plugins/modifier.capitalize.php	(revision 3278)
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty capitalize modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     capitalize<br>
+ * Purpose:  capitalize words in the string
+ * @link http://smarty.php.net/manual/en/language.modifiers.php#LANGUAGE.MODIFIER.CAPITALIZE
+ *      capitalize (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @return string
+ */
+function smarty_modifier_capitalize($string, $uc_digits = false)
+{
+    smarty_modifier_capitalize_ucfirst(null, $uc_digits);
+    return preg_replace_callback('!\'?\b\w(\w|\')*\b!', 'smarty_modifier_capitalize_ucfirst', $string);
+}
+
+function smarty_modifier_capitalize_ucfirst($string, $uc_digits = null)
+{
+    static $_uc_digits = false;
+    
+    if(isset($uc_digits)) {
+        $_uc_digits = $uc_digits;
+        return;
+    }
+    
+    if(substr($string[0],0,1) != "'" && !preg_match("!\d!",$string[0]) || $_uc_digits)
+        return ucfirst($string[0]);
+    else
+        return $string[0];
+}
+
+
+?>
Index: /tags/2.0.2/include/smarty/libs/plugins/modifier.cat.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/plugins/modifier.cat.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/plugins/modifier.cat.php	(revision 3278)
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty cat modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     cat<br>
+ * Date:     Feb 24, 2003
+ * Purpose:  catenate a value to a variable
+ * Input:    string to catenate
+ * Example:  {$var|cat:"foo"}
+ * @link http://smarty.php.net/manual/en/language.modifier.cat.php cat
+ *          (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @version 1.0
+ * @param string
+ * @param string
+ * @return string
+ */
+function smarty_modifier_cat($string, $cat)
+{
+    return $string . $cat;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/plugins/modifier.count_characters.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/plugins/modifier.count_characters.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/plugins/modifier.count_characters.php	(revision 3278)
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty count_characters modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     count_characteres<br>
+ * Purpose:  count the number of characters in a text
+ * @link http://smarty.php.net/manual/en/language.modifier.count.characters.php
+ *          count_characters (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @param boolean include whitespace in the character count
+ * @return integer
+ */
+function smarty_modifier_count_characters($string, $include_spaces = false)
+{
+    if ($include_spaces)
+       return(strlen($string));
+
+    return preg_match_all("/[^\s]/",$string, $match);
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/plugins/modifier.count_paragraphs.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/plugins/modifier.count_paragraphs.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/plugins/modifier.count_paragraphs.php	(revision 3278)
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty count_paragraphs modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     count_paragraphs<br>
+ * Purpose:  count the number of paragraphs in a text
+ * @link http://smarty.php.net/manual/en/language.modifier.count.paragraphs.php
+ *          count_paragraphs (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @return integer
+ */
+function smarty_modifier_count_paragraphs($string)
+{
+    // count \r or \n characters
+    return count(preg_split('/[\r\n]+/', $string));
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/plugins/modifier.count_sentences.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/plugins/modifier.count_sentences.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/plugins/modifier.count_sentences.php	(revision 3278)
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty count_sentences modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     count_sentences
+ * Purpose:  count the number of sentences in a text
+ * @link http://smarty.php.net/manual/en/language.modifier.count.paragraphs.php
+ *          count_sentences (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @return integer
+ */
+function smarty_modifier_count_sentences($string)
+{
+    // find periods with a word before but not after.
+    return preg_match_all('/[^\s]\.(?!\w)/', $string, $match);
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/plugins/modifier.count_words.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/plugins/modifier.count_words.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/plugins/modifier.count_words.php	(revision 3278)
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty count_words modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     count_words<br>
+ * Purpose:  count the number of words in a text
+ * @link http://smarty.php.net/manual/en/language.modifier.count.words.php
+ *          count_words (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @return integer
+ */
+function smarty_modifier_count_words($string)
+{
+    // split text by ' ',\r,\n,\f,\t
+    $split_array = preg_split('/\s+/',$string);
+    // count matches that contain alphanumerics
+    $word_count = preg_grep('/[a-zA-Z0-9\\x80-\\xff]/', $split_array);
+
+    return count($word_count);
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/plugins/modifier.date_format.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/plugins/modifier.date_format.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/plugins/modifier.date_format.php	(revision 3278)
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Include the {@link shared.make_timestamp.php} plugin
+ */
+require_once $smarty->_get_plugin_filepath('shared', 'make_timestamp');
+/**
+ * Smarty date_format modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     date_format<br>
+ * Purpose:  format datestamps via strftime<br>
+ * Input:<br>
+ *         - string: input date string
+ *         - format: strftime format for output
+ *         - default_date: default date if $string is empty
+ * @link http://smarty.php.net/manual/en/language.modifier.date.format.php
+ *          date_format (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @param string
+ * @param string
+ * @return string|void
+ * @uses smarty_make_timestamp()
+ */
+function smarty_modifier_date_format($string, $format = '%b %e, %Y', $default_date = '')
+{
+    if ($string != '') {
+        $timestamp = smarty_make_timestamp($string);
+    } elseif ($default_date != '') {
+        $timestamp = smarty_make_timestamp($default_date);
+    } else {
+        return;
+    }
+    if (DIRECTORY_SEPARATOR == '\\') {
+        $_win_from = array('%D',       '%h', '%n', '%r',          '%R',    '%t', '%T');
+        $_win_to   = array('%m/%d/%y', '%b', "\n", '%I:%M:%S %p', '%H:%M', "\t", '%H:%M:%S');
+        if (strpos($format, '%e') !== false) {
+            $_win_from[] = '%e';
+            $_win_to[]   = sprintf('%\' 2d', date('j', $timestamp));
+        }
+        if (strpos($format, '%l') !== false) {
+            $_win_from[] = '%l';
+            $_win_to[]   = sprintf('%\' 2d', date('h', $timestamp));
+        }
+        $format = str_replace($_win_from, $_win_to, $format);
+    }
+    return strftime($format, $timestamp);
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/plugins/modifier.debug_print_var.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/plugins/modifier.debug_print_var.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/plugins/modifier.debug_print_var.php	(revision 3278)
@@ -0,0 +1,90 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty debug_print_var modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     debug_print_var<br>
+ * Purpose:  formats variable contents for display in the console
+ * @link http://smarty.php.net/manual/en/language.modifier.debug.print.var.php
+ *          debug_print_var (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param array|object
+ * @param integer
+ * @param integer
+ * @return string
+ */
+function smarty_modifier_debug_print_var($var, $depth = 0, $length = 40)
+{
+    $_replace = array(
+        "\n" => '<i>\n</i>',
+        "\r" => '<i>\r</i>',
+        "\t" => '<i>\t</i>'
+    );
+
+    switch (gettype($var)) {
+        case 'array' :
+            $results = '<b>Array (' . count($var) . ')</b>';
+            foreach ($var as $curr_key => $curr_val) {
+                $results .= '<br>' . str_repeat('&nbsp;', $depth * 2)
+                    . '<b>' . strtr($curr_key, $_replace) . '</b> =&gt; '
+                    . smarty_modifier_debug_print_var($curr_val, ++$depth, $length);
+                    $depth--;
+            }
+            break;
+        case 'object' :
+            $object_vars = get_object_vars($var);
+            $results = '<b>' . get_class($var) . ' Object (' . count($object_vars) . ')</b>';
+            foreach ($object_vars as $curr_key => $curr_val) {
+                $results .= '<br>' . str_repeat('&nbsp;', $depth * 2)
+                    . '<b> -&gt;' . strtr($curr_key, $_replace) . '</b> = '
+                    . smarty_modifier_debug_print_var($curr_val, ++$depth, $length);
+                    $depth--;
+            }
+            break;
+        case 'boolean' :
+        case 'NULL' :
+        case 'resource' :
+            if (true === $var) {
+                $results = 'true';
+            } elseif (false === $var) {
+                $results = 'false';
+            } elseif (null === $var) {
+                $results = 'null';
+            } else {
+                $results = htmlspecialchars((string) $var);
+            }
+            $results = '<i>' . $results . '</i>';
+            break;
+        case 'integer' :
+        case 'float' :
+            $results = htmlspecialchars((string) $var);
+            break;
+        case 'string' :
+            $results = strtr($var, $_replace);
+            if (strlen($var) > $length ) {
+                $results = substr($var, 0, $length - 3) . '...';
+            }
+            $results = htmlspecialchars('"' . $results . '"');
+            break;
+        case 'unknown type' :
+        default :
+            $results = strtr((string) $var, $_replace);
+            if (strlen($results) > $length ) {
+                $results = substr($results, 0, $length - 3) . '...';
+            }
+            $results = htmlspecialchars($results);
+    }
+
+    return $results;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/plugins/modifier.default.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/plugins/modifier.default.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/plugins/modifier.default.php	(revision 3278)
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty default modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     default<br>
+ * Purpose:  designate default value for empty variables
+ * @link http://smarty.php.net/manual/en/language.modifier.default.php
+ *          default (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @param string
+ * @return string
+ */
+function smarty_modifier_default($string, $default = '')
+{
+    if (!isset($string) || $string === '')
+        return $default;
+    else
+        return $string;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/plugins/modifier.escape.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/plugins/modifier.escape.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/plugins/modifier.escape.php	(revision 3278)
@@ -0,0 +1,93 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty escape modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     escape<br>
+ * Purpose:  Escape the string according to escapement type
+ * @link http://smarty.php.net/manual/en/language.modifier.escape.php
+ *          escape (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @param html|htmlall|url|quotes|hex|hexentity|javascript
+ * @return string
+ */
+function smarty_modifier_escape($string, $esc_type = 'html', $char_set = 'ISO-8859-1')
+{
+    switch ($esc_type) {
+        case 'html':
+            return htmlspecialchars($string, ENT_QUOTES, $char_set);
+
+        case 'htmlall':
+            return htmlentities($string, ENT_QUOTES, $char_set);
+
+        case 'url':
+            return rawurlencode($string);
+
+        case 'urlpathinfo':
+            return str_replace('%2F','/',rawurlencode($string));
+            
+        case 'quotes':
+            // escape unescaped single quotes
+            return preg_replace("%(?<!\\\\)'%", "\\'", $string);
+
+        case 'hex':
+            // escape every character into hex
+            $return = '';
+            for ($x=0; $x < strlen($string); $x++) {
+                $return .= '%' . bin2hex($string[$x]);
+            }
+            return $return;
+            
+        case 'hexentity':
+            $return = '';
+            for ($x=0; $x < strlen($string); $x++) {
+                $return .= '&#x' . bin2hex($string[$x]) . ';';
+            }
+            return $return;
+
+        case 'decentity':
+            $return = '';
+            for ($x=0; $x < strlen($string); $x++) {
+                $return .= '&#' . ord($string[$x]) . ';';
+            }
+            return $return;
+
+        case 'javascript':
+            // escape quotes and backslashes, newlines, etc.
+            return strtr($string, array('\\'=>'\\\\',"'"=>"\\'",'"'=>'\\"',"\r"=>'\\r',"\n"=>'\\n','</'=>'<\/'));
+            
+        case 'mail':
+            // safe way to display e-mail address on a web page
+            return str_replace(array('@', '.'),array(' [AT] ', ' [DOT] '), $string);
+            
+        case 'nonstd':
+           // escape non-standard chars, such as ms document quotes
+           $_res = '';
+           for($_i = 0, $_len = strlen($string); $_i < $_len; $_i++) {
+               $_ord = ord(substr($string, $_i, 1));
+               // non-standard char, escape it
+               if($_ord >= 126){
+                   $_res .= '&#' . $_ord . ';';
+               }
+               else {
+                   $_res .= substr($string, $_i, 1);
+               }
+           }
+           return $_res;
+
+        default:
+            return $string;
+    }
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/plugins/modifier.indent.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/plugins/modifier.indent.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/plugins/modifier.indent.php	(revision 3278)
@@ -0,0 +1,28 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty indent modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     indent<br>
+ * Purpose:  indent lines of text
+ * @link http://smarty.php.net/manual/en/language.modifier.indent.php
+ *          indent (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @param integer
+ * @param string
+ * @return string
+ */
+function smarty_modifier_indent($string,$chars=4,$char=" ")
+{
+    return preg_replace('!^!m',str_repeat($char,$chars),$string);
+}
+
+?>
Index: /tags/2.0.2/include/smarty/libs/plugins/modifier.lower.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/plugins/modifier.lower.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/plugins/modifier.lower.php	(revision 3278)
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty lower modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     lower<br>
+ * Purpose:  convert string to lowercase
+ * @link http://smarty.php.net/manual/en/language.modifier.lower.php
+ *          lower (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @return string
+ */
+function smarty_modifier_lower($string)
+{
+    return strtolower($string);
+}
+
+?>
Index: /tags/2.0.2/include/smarty/libs/plugins/modifier.nl2br.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/plugins/modifier.nl2br.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/plugins/modifier.nl2br.php	(revision 3278)
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty plugin
+ *
+ * Type:     modifier<br>
+ * Name:     nl2br<br>
+ * Date:     Feb 26, 2003
+ * Purpose:  convert \r\n, \r or \n to <<br>>
+ * Input:<br>
+ *         - contents = contents to replace
+ *         - preceed_test = if true, includes preceeding break tags
+ *           in replacement
+ * Example:  {$text|nl2br}
+ * @link http://smarty.php.net/manual/en/language.modifier.nl2br.php
+ *          nl2br (Smarty online manual)
+ * @version  1.0
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @return string
+ */
+function smarty_modifier_nl2br($string)
+{
+    return nl2br($string);
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/plugins/modifier.regex_replace.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/plugins/modifier.regex_replace.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/plugins/modifier.regex_replace.php	(revision 3278)
@@ -0,0 +1,48 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty regex_replace modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     regex_replace<br>
+ * Purpose:  regular expression search/replace
+ * @link http://smarty.php.net/manual/en/language.modifier.regex.replace.php
+ *          regex_replace (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @param string|array
+ * @param string|array
+ * @return string
+ */
+function smarty_modifier_regex_replace($string, $search, $replace)
+{
+    if(is_array($search)) {
+      foreach($search as $idx => $s)
+        $search[$idx] = _smarty_regex_replace_check($s);
+    } else {
+      $search = _smarty_regex_replace_check($search);
+    }       
+
+    return preg_replace($search, $replace, $string);
+}
+
+function _smarty_regex_replace_check($search)
+{
+    if (($pos = strpos($search,"\0")) !== false)
+      $search = substr($search,0,$pos);
+    if (preg_match('!([a-zA-Z\s]+)$!s', $search, $match) && (strpos($match[1], 'e') !== false)) {
+        /* remove eval-modifier from $search */
+        $search = substr($search, 0, -strlen($match[1])) . preg_replace('![e\s]+!', '', $match[1]);
+    }
+    return $search;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/plugins/modifier.replace.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/plugins/modifier.replace.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/plugins/modifier.replace.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty replace modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     replace<br>
+ * Purpose:  simple search/replace
+ * @link http://smarty.php.net/manual/en/language.modifier.replace.php
+ *          replace (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @param string
+ * @param string
+ * @return string
+ */
+function smarty_modifier_replace($string, $search, $replace)
+{
+    return str_replace($search, $replace, $string);
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/plugins/modifier.spacify.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/plugins/modifier.spacify.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/plugins/modifier.spacify.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty spacify modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     spacify<br>
+ * Purpose:  add spaces between characters in a string
+ * @link http://smarty.php.net/manual/en/language.modifier.spacify.php
+ *          spacify (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @param string
+ * @return string
+ */
+function smarty_modifier_spacify($string, $spacify_char = ' ')
+{
+    return implode($spacify_char,
+                   preg_split('//', $string, -1, PREG_SPLIT_NO_EMPTY));
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/plugins/modifier.string_format.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/plugins/modifier.string_format.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/plugins/modifier.string_format.php	(revision 3278)
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty string_format modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     string_format<br>
+ * Purpose:  format strings via sprintf
+ * @link http://smarty.php.net/manual/en/language.modifier.string.format.php
+ *          string_format (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @param string
+ * @return string
+ */
+function smarty_modifier_string_format($string, $format)
+{
+    return sprintf($format, $string);
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/plugins/modifier.strip.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/plugins/modifier.strip.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/plugins/modifier.strip.php	(revision 3278)
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty strip modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     strip<br>
+ * Purpose:  Replace all repeated spaces, newlines, tabs
+ *           with a single space or supplied replacement string.<br>
+ * Example:  {$var|strip} {$var|strip:"&nbsp;"}
+ * Date:     September 25th, 2002
+ * @link http://smarty.php.net/manual/en/language.modifier.strip.php
+ *          strip (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @version  1.0
+ * @param string
+ * @param string
+ * @return string
+ */
+function smarty_modifier_strip($text, $replace = ' ')
+{
+    return preg_replace('!\s+!', $replace, $text);
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/plugins/modifier.strip_tags.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/plugins/modifier.strip_tags.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/plugins/modifier.strip_tags.php	(revision 3278)
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty strip_tags modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     strip_tags<br>
+ * Purpose:  strip html tags from text
+ * @link http://smarty.php.net/manual/en/language.modifier.strip.tags.php
+ *          strip_tags (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @param boolean
+ * @return string
+ */
+function smarty_modifier_strip_tags($string, $replace_with_space = true)
+{
+    if ($replace_with_space)
+        return preg_replace('!<[^>]*?>!', ' ', $string);
+    else
+        return strip_tags($string);
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/plugins/modifier.truncate.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/plugins/modifier.truncate.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/plugins/modifier.truncate.php	(revision 3278)
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty truncate modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     truncate<br>
+ * Purpose:  Truncate a string to a certain length if necessary,
+ *           optionally splitting in the middle of a word, and
+ *           appending the $etc string or inserting $etc into the middle.
+ * @link http://smarty.php.net/manual/en/language.modifier.truncate.php
+ *          truncate (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @param integer
+ * @param string
+ * @param boolean
+ * @param boolean
+ * @return string
+ */
+function smarty_modifier_truncate($string, $length = 80, $etc = '...',
+                                  $break_words = false, $middle = false)
+{
+    if ($length == 0)
+        return '';
+
+    if (strlen($string) > $length) {
+        $length -= min($length, strlen($etc));
+        if (!$break_words && !$middle) {
+            $string = preg_replace('/\s+?(\S+)?$/', '', substr($string, 0, $length+1));
+        }
+        if(!$middle) {
+            return substr($string, 0, $length) . $etc;
+        } else {
+            return substr($string, 0, $length/2) . $etc . substr($string, -$length/2);
+        }
+    } else {
+        return $string;
+    }
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/plugins/modifier.upper.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/plugins/modifier.upper.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/plugins/modifier.upper.php	(revision 3278)
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty upper modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     upper<br>
+ * Purpose:  convert string to uppercase
+ * @link http://smarty.php.net/manual/en/language.modifier.upper.php
+ *          upper (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @return string
+ */
+function smarty_modifier_upper($string)
+{
+    return strtoupper($string);
+}
+
+?>
Index: /tags/2.0.2/include/smarty/libs/plugins/modifier.wordwrap.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/plugins/modifier.wordwrap.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/plugins/modifier.wordwrap.php	(revision 3278)
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty wordwrap modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     wordwrap<br>
+ * Purpose:  wrap a string of text at a given length
+ * @link http://smarty.php.net/manual/en/language.modifier.wordwrap.php
+ *          wordwrap (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @param integer
+ * @param string
+ * @param boolean
+ * @return string
+ */
+function smarty_modifier_wordwrap($string,$length=80,$break="\n",$cut=false)
+{
+    return wordwrap($string,$length,$break,$cut);
+}
+
+?>
Index: /tags/2.0.2/include/smarty/libs/plugins/outputfilter.trimwhitespace.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/plugins/outputfilter.trimwhitespace.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/plugins/outputfilter.trimwhitespace.php	(revision 3278)
@@ -0,0 +1,75 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Smarty trimwhitespace outputfilter plugin
+ *
+ * File:     outputfilter.trimwhitespace.php<br>
+ * Type:     outputfilter<br>
+ * Name:     trimwhitespace<br>
+ * Date:     Jan 25, 2003<br>
+ * Purpose:  trim leading white space and blank lines from
+ *           template source after it gets interpreted, cleaning
+ *           up code and saving bandwidth. Does not affect
+ *           <<PRE>></PRE> and <SCRIPT></SCRIPT> blocks.<br>
+ * Install:  Drop into the plugin directory, call
+ *           <code>$smarty->load_filter('output','trimwhitespace');</code>
+ *           from application.
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @author Contributions from Lars Noschinski <lars@usenet.noschinski.de>
+ * @version  1.3
+ * @param string
+ * @param Smarty
+ */
+function smarty_outputfilter_trimwhitespace($source, &$smarty)
+{
+    // Pull out the script blocks
+    preg_match_all("!<script[^>]*?>.*?</script>!is", $source, $match);
+    $_script_blocks = $match[0];
+    $source = preg_replace("!<script[^>]*?>.*?</script>!is",
+                           '@@@SMARTY:TRIM:SCRIPT@@@', $source);
+
+    // Pull out the pre blocks
+    preg_match_all("!<pre[^>]*?>.*?</pre>!is", $source, $match);
+    $_pre_blocks = $match[0];
+    $source = preg_replace("!<pre[^>]*?>.*?</pre>!is",
+                           '@@@SMARTY:TRIM:PRE@@@', $source);
+    
+    // Pull out the textarea blocks
+    preg_match_all("!<textarea[^>]*?>.*?</textarea>!is", $source, $match);
+    $_textarea_blocks = $match[0];
+    $source = preg_replace("!<textarea[^>]*?>.*?</textarea>!is",
+                           '@@@SMARTY:TRIM:TEXTAREA@@@', $source);
+
+    // remove all leading spaces, tabs and carriage returns NOT
+    // preceeded by a php close tag.
+    $source = trim(preg_replace('/((?<!\?>)\n)[\s]+/m', '\1', $source));
+
+    // replace textarea blocks
+    smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:TEXTAREA@@@",$_textarea_blocks, $source);
+
+    // replace pre blocks
+    smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:PRE@@@",$_pre_blocks, $source);
+
+    // replace script blocks
+    smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:SCRIPT@@@",$_script_blocks, $source);
+
+    return $source;
+}
+
+function smarty_outputfilter_trimwhitespace_replace($search_str, $replace, &$subject) {
+    $_len = strlen($search_str);
+    $_pos = 0;
+    for ($_i=0, $_count=count($replace); $_i<$_count; $_i++)
+        if (($_pos=strpos($subject, $search_str, $_pos))!==false)
+            $subject = substr_replace($subject, $replace[$_i], $_pos, $_len);
+        else
+            break;
+
+}
+
+?>
Index: /tags/2.0.2/include/smarty/libs/plugins/shared.escape_special_chars.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/plugins/shared.escape_special_chars.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/plugins/shared.escape_special_chars.php	(revision 3278)
@@ -0,0 +1,31 @@
+<?php
+/**
+ * Smarty shared plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * escape_special_chars common function
+ *
+ * Function: smarty_function_escape_special_chars<br>
+ * Purpose:  used by other smarty functions to escape
+ *           special chars except for already escaped ones
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @return string
+ */
+function smarty_function_escape_special_chars($string)
+{
+    if(!is_array($string)) {
+        $string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string);
+        $string = htmlspecialchars($string);
+        $string = str_replace(array('%%%SMARTY_START%%%','%%%SMARTY_END%%%'), array('&',';'), $string);
+    }
+    return $string;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/smarty/libs/plugins/shared.make_timestamp.php
===================================================================
--- /tags/2.0.2/include/smarty/libs/plugins/shared.make_timestamp.php	(revision 3278)
+++ /tags/2.0.2/include/smarty/libs/plugins/shared.make_timestamp.php	(revision 3278)
@@ -0,0 +1,46 @@
+<?php
+/**
+ * Smarty shared plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Function: smarty_make_timestamp<br>
+ * Purpose:  used by other smarty functions to make a timestamp
+ *           from a string.
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @return string
+ */
+function smarty_make_timestamp($string)
+{
+    if(empty($string)) {
+        // use "now":
+        $time = time();
+
+    } elseif (preg_match('/^\d{14}$/', $string)) {
+        // it is mysql timestamp format of YYYYMMDDHHMMSS?            
+        $time = mktime(substr($string, 8, 2),substr($string, 10, 2),substr($string, 12, 2),
+                       substr($string, 4, 2),substr($string, 6, 2),substr($string, 0, 4));
+        
+    } elseif (is_numeric($string)) {
+        // it is a numeric string, we handle it as timestamp
+        $time = (int)$string;
+        
+    } else {
+        // strtotime should handle it
+        $time = strtotime($string);
+        if ($time == -1 || $time === false) {
+            // strtotime() was not able to parse $string, use "now":
+            $time = time();
+        }
+    }
+    return $time;
+
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /tags/2.0.2/include/template.class.php
===================================================================
--- /tags/2.0.2/include/template.class.php	(revision 3278)
+++ /tags/2.0.2/include/template.class.php	(revision 3278)
@@ -0,0 +1,491 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+
+require_once(PHPWG_ROOT_PATH.'include/smarty/libs/Smarty.class.php');
+
+// migrate lang:XXX
+//    sed "s/{lang:\([^}]\+\)}/{\'\1\'|@translate}/g" my_template.tpl
+// migrate change root level vars {XXX}
+//    sed "s/{pwg_root}/{ROOT_URL}/g" my_template.tpl
+// migrate change root level vars {XXX}
+//    sed "s/{\([a-zA-Z_]\+\)}/{$\1}/g" my_template.tpl
+// migrate all
+//    cat my_template.tpl | sed "s/{lang:\([^}]\+\)}/{\'\1\'|@translate}/g" | sed "s/{pwg_root}/{ROOT_URL}/g" | sed "s/{\([a-zA-Z_]\+\)}/{$\1}/g"
+
+
+class Template {
+
+  var $smarty;
+
+  var $output = '';
+
+  // Hash of filenames for each template handle.
+  var $files = array();
+
+  // Template extents filenames for each template handle.
+  var $extents = array();
+
+  // used by html_head smarty block to add content before </head>
+  var $html_head_elements = array();
+
+  function Template($root = ".", $theme= "")
+  {
+    global $conf, $lang_info;
+
+    $this->smarty = new Smarty;
+    $this->smarty->debugging = $conf['debug_template'];
+    $this->smarty->compile_check=$conf['template_compile_check'];
+
+    $compile_dir = $conf['local_data_dir'].'/templates_c';
+    mkgetdir( $compile_dir );
+
+    $this->smarty->compile_dir = $compile_dir;
+
+    $this->smarty->assign_by_ref( 'pwg', new PwgTemplateAdapter() );
+    $this->smarty->register_modifier( 'translate', array('Template', 'mod_translate') );
+    $this->smarty->register_modifier( 'explode', array('Template', 'mod_explode') );
+    $this->smarty->register_modifier( 'get_extent', array(&$this, 'get_extent') );
+    $this->smarty->register_block('html_head', array(&$this, 'block_html_head') );
+    $this->smarty->register_function('known_script', array(&$this, 'func_known_script') );
+    $this->smarty->register_prefilter( array('Template', 'prefilter_white_space') );
+    if ( $conf['compiled_template_cache_language'] )
+    {
+      $this->smarty->register_prefilter( array('Template', 'prefilter_language') );
+    }
+
+    if ( !empty($theme) )
+    {
+      include($root.'/theme/'.$theme.'/themeconf.inc.php');
+      $this->smarty->assign('themeconf', $themeconf);
+    }
+
+    $this->smarty->assign('lang_info', $lang_info);
+
+    $this->set_template_dir($root);
+
+    if (!defined('IN_ADMIN') and isset($conf['extents_for_templates']))
+    {
+      $tpl_extents = unserialize($conf['extents_for_templates']);
+      $this->set_extents($tpl_extents, './template-extension/', true);
+    }
+  }
+
+  /**
+   * Sets the template root directory for this Template object.
+   */
+  function set_template_dir($dir)
+  {
+    $this->smarty->template_dir = $dir;
+
+    $real_dir = realpath($dir);
+    $compile_id = crc32( $real_dir===false ? $dir : $real_dir);
+    $this->smarty->compile_id = base_convert($compile_id, 10, 36 );
+  }
+
+  /**
+   * Gets the template root directory for this Template object.
+   */
+  function get_template_dir()
+  {
+    return $this->smarty->template_dir;
+  }
+
+  /**
+   * Deletes all compiled templates.
+   */
+  function delete_compiled_templates()
+  {
+      $save_compile_id = $this->smarty->compile_id;
+      $this->smarty->compile_id = null;
+      $this->smarty->clear_compiled_tpl();
+      $this->smarty->compile_id = $save_compile_id;
+      file_put_contents($this->smarty->compile_dir.'/index.htm', 'Not allowed!');
+  }
+
+  function get_themeconf($val)
+  {
+    $tc = $this->smarty->get_template_vars('themeconf');
+    return isset($tc[$val]) ? $tc[$val] : '';
+  }
+
+  /**
+   * Sets the template filename for handle.
+   */
+  function set_filename($handle, $filename)
+  {
+    return $this->set_filenames( array($handle=>$filename) );
+  }
+
+  /**
+   * Sets the template filenames for handles. $filename_array should be a
+   * hash of handle => filename pairs.
+   */
+  function set_filenames($filename_array)
+  {
+    if (!is_array($filename_array))
+    {
+      return false;
+    }
+    reset($filename_array);
+    while(list($handle, $filename) = each($filename_array))
+    {
+      if (is_null($filename))
+      {
+        unset($this->files[$handle]);
+      }
+      else
+      {
+        $this->files[$handle] = $this->get_extent($filename, $handle);
+      }
+    }
+    return true;
+  }
+
+  /**
+   * Sets template extention filename for handles.
+   */
+  function set_extent($filename, $param, $dir='', $overwrite=true)
+  {
+    return $this->set_extents(array($filename => $param), $dir, $overwrite);
+  }
+
+  /**
+   * Sets template extentions filenames for handles.
+   * $filename_array should be an hash of filename => array( handle, param) or filename => handle
+   */
+  function set_extents($filename_array, $dir='', $overwrite=true)
+  {
+    if (!is_array($filename_array))
+    {
+      return false;
+    }
+    foreach ($filename_array as $filename => $value)
+    {
+      if (is_array($value))
+      {
+        $handle = $value[0];
+        $param = $value[1];
+        $tpl = $value[2];
+      }
+      elseif (is_string($value))
+      {
+        $handle = $value;
+        $param = 'N/A';
+        $tpl = 'N/A';
+      }
+      else
+      {
+        return false;
+      }
+
+      if ((stripos(implode('',array_keys($_GET)), '/'.$param) !== false or $param == 'N/A')
+        and (preg_match('/'.preg_quote($tpl,'/').'$/', $this->get_template_dir()) or $tpl == 'N/A')
+        and (!isset($this->extents[$handle]) or $overwrite)
+        and file_exists($dir . $filename))
+      {
+        $this->extents[$handle] = realpath($dir . $filename);
+      }
+    }
+    return true;
+  }
+
+  /** return template extension if exists  */
+  function get_extent($filename='', $handle='')
+  {
+    if (isset($this->extents[$handle]))
+    {
+      $filename = $this->extents[$handle];
+    }
+    return $filename;
+  }
+
+  /** see smarty assign http://www.smarty.net/manual/en/api.assign.php */
+  function assign($tpl_var, $value = null)
+  {
+    $this->smarty->assign( $tpl_var, $value );
+  }
+
+  /**
+   * Inserts the uncompiled code for $handle as the value of $varname in the
+   * root-level. This can be used to effectively include a template in the
+   * middle of another template.
+   * This is equivalent to assign($varname, $this->parse($handle, true))
+   */
+  function assign_var_from_handle($varname, $handle)
+  {
+    $this->assign($varname, $this->parse($handle, true));
+    return true;
+  }
+
+  /** see smarty append http://www.smarty.net/manual/en/api.append.php */
+  function append($tpl_var, $value=null, $merge=false)
+  {
+    $this->smarty->append( $tpl_var, $value, $merge );
+  }
+
+  /**
+   * Root-level variable concatenation. Appends a  string to an existing
+   * variable assignment with the same name.
+   */
+  function concat($tpl_var, $value)
+  {
+    $old_val = & $this->smarty->get_template_vars($tpl_var);
+    if ( isset($old_val) )
+    {
+      $old_val .= $value;
+    }
+    else
+    {
+      $this->assign($tpl_var, $value);
+    }
+  }
+
+  /** see smarty append http://www.smarty.net/manual/en/api.clear_assign.php */
+  function clear_assign($tpl_var)
+  {
+    $this->smarty->clear_assign( $tpl_var );
+  }
+
+  /** see smarty get_template_vars http://www.smarty.net/manual/en/api.get_template_vars.php */
+  function &get_template_vars($name=null)
+  {
+    return $this->smarty->get_template_vars( $name );
+  }
+
+
+  /**
+   * Load the file for the handle, eventually compile the file and run the compiled
+   * code. This will add the output to the results or return the result if $return
+   * is true.
+   */
+  function parse($handle, $return=false)
+  {
+    if ( !isset($this->files[$handle]) )
+    {
+      fatal_error("Template->parse(): Couldn't load template file for handle $handle");
+    }
+
+    $this->smarty->assign( 'ROOT_URL', get_root_url() );
+    $this->smarty->assign( 'TAG_INPUT_ENABLED',
+      ((is_adviser()) ? 'disabled="disabled" onclick="return false;"' : ''));
+
+    global $conf, $lang_info;
+    if ( $conf['compiled_template_cache_language'] and isset($lang_info['code']) )
+    {
+      $save_compile_id = $this->smarty->compile_id;
+      $this->smarty->compile_id .= '.'.$lang_info['code'];
+    }
+
+    $v = $this->smarty->fetch($this->files[$handle], null, null, false);
+
+    if (isset ($save_compile_id) )
+    {
+      $this->smarty->compile_id = $save_compile_id;
+    }
+
+    if ($return)
+    {
+      return $v;
+    }
+    $this->output .= $v;
+  }
+
+  /**
+   * Load the file for the handle, eventually compile the file and run the compiled
+   * code. This will print out the results of executing the template.
+   */
+  function pparse($handle)
+  {
+    $this->parse($handle, false);
+    $this->flush();
+  }
+
+  function flush()
+  {
+    if ( count($this->html_head_elements) )
+    {
+      $search = "\n</head>";
+      $pos = strpos( $this->output, $search );
+      if ($pos !== false)
+      {
+        $this->output = substr_replace( $this->output, "\n".implode( "\n", $this->html_head_elements ), $pos, 0 );
+      } //else maybe error or warning ?
+      $this->html_head_elements = array();
+    }
+    echo $this->output;
+    $this->output='';
+  }
+
+  /** flushes the output */
+  function p()
+  {
+    $this->flush();
+
+    if ($this->smarty->debugging)
+    {
+      global $t2;
+      $this->smarty->assign(
+        array(
+        'AAAA_DEBUG_TOTAL_TIME__' => get_elapsed_time($t2, get_moment())
+        )
+        );
+      require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php');
+      echo smarty_core_display_debug_console(null, $this->smarty);
+    }
+  }
+
+  /**
+   * translate variable modifier - translates a text to the currently loaded
+   * language
+   */
+  static function mod_translate($text)
+  {
+    return l10n($text);
+  }
+
+  /**
+   * explode variable modifier - similar to php explode
+   * 'Yes;No'|@explode:';' -> array('Yes', 'No')
+   */
+  static function mod_explode($text, $delimiter=',')
+  {
+    return explode($delimiter, $text);
+  }
+
+  /**
+   * This smarty "html_head" block allows to add content just before
+   * </head> element in the output after the head has been parsed. This is
+   * handy in order to respect strict standards when <style> and <link>
+   * html elements must appear in the <head> element
+   */
+  function block_html_head($params, $content, &$smarty, &$repeat)
+  {
+    $content = trim($content);
+    if ( !empty($content) )
+    { // second call
+      $this->html_head_elements[] = $content;
+    }
+  }
+
+ /**
+   * This smarty "known_script" functions allows to insert well known java scripts
+   * such as prototype, jquery, etc... only once. Examples:
+   * {known_script id="jquery" src="{$ROOT_URL}template-common/lib/jquery.packed.js"}
+   */
+  function func_known_script($params, &$smarty )
+  {
+    if (!isset($params['id']))
+    {
+        $smarty->trigger_error("known_script: missing 'id' parameter");
+        return;
+    }
+    $id = $params['id'];
+    if (! isset( $this->known_scripts[$id] ) )
+    {
+      if (!isset($params['src']))
+      {
+          $smarty->trigger_error("known_script: missing 'src' parameter");
+          return;
+      }
+      $this->known_scripts[$id] = $params['src'];
+      $content = '<script type="text/javascript" src="'.$params['src'].'"></script>';
+      if (isset($params['now']) and $params['now'] and empty($this->output) )
+      {
+        return $content;
+      }
+      $repeat = false;
+      $this->block_html_head(null, $content, $smarty, $repeat);
+    }
+  }
+
+  static function prefilter_white_space($source, &$smarty)
+  {
+    $ld = $smarty->left_delimiter;
+    $rd = $smarty->right_delimiter;
+    $ldq = preg_quote($ld, '#');
+    $rdq = preg_quote($rd, '#');
+
+    $regex = array();
+    $tags = array('if', 'foreach', 'section');
+    foreach($tags as $tag)
+    {
+      array_push($regex, "#^[ \t]+($ldq$tag"."[^$ld$rd]*$rdq)\s*$#m");
+      array_push($regex, "#^[ \t]+($ldq/$tag$rdq)\s*$#m");
+    }
+    $tags = array('include', 'else', 'html_head');
+    foreach($tags as $tag)
+    {
+      array_push($regex, "#^[ \t]+($ldq$tag"."[^$ld$rd]*$rdq)\s*$#m");
+    }
+    $source = preg_replace( $regex, "$1", $source);
+    return $source;
+  }
+
+  /**
+   * Smarty prefilter to allow caching (whenever possible) language strings
+   * from templates.
+   */
+  static function prefilter_language($source, &$smarty)
+  {
+    global $lang;
+    $ldq = preg_quote($smarty->left_delimiter, '~');
+    $rdq = preg_quote($smarty->right_delimiter, '~');
+
+    $regex = "~$ldq *\'([^'$]+)\'\|@translate *$rdq~";
+    $source = preg_replace( $regex.'e', 'isset($lang[\'$1\']) ? $lang[\'$1\'] : \'$0\'', $source);
+
+    $regex = "~$ldq *\'([^'$]+)\'\|@translate\|~";
+    $source = preg_replace( $regex.'e', 'isset($lang[\'$1\']) ? \'{\'.var_export($lang[\'$1\'],true).\'|\' : \'$0\'', $source);
+
+    $regex = "~($ldq *assign +var=.+ +value=)\'([^'$]+)\'\|@translate~e";
+    $source = preg_replace( $regex, 'isset($lang[\'$2\']) ? \'$1\'.var_export($lang[\'$2\'],true) : \'$0\'', $source);
+
+    return $source;
+  }
+}
+
+/**
+ * This class contains basic functions that can be called directly from the
+ * templates in the form $pwg->l10n('edit')
+ */
+class PwgTemplateAdapter
+{
+  function l10n($text)
+  {
+    return l10n($text);
+  }
+
+  function l10n_dec($s, $p, $v)
+  {
+    return l10n_dec($s, $p, $v);
+  }
+
+  function sprintf()
+  {
+    $args = func_get_args();
+    return call_user_func_array('sprintf',  $args );
+  }
+}
+
+?>
Index: /tags/2.0.2/include/user.inc.php
===================================================================
--- /tags/2.0.2/include/user.inc.php	(revision 3278)
+++ /tags/2.0.2/include/user.inc.php	(revision 3278)
@@ -0,0 +1,70 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// by default we start with guest
+$user['id'] = $conf['guest_id'];
+
+if (isset($_COOKIE[session_name()]))
+{
+  session_start();
+  if (isset($_GET['act']) and $_GET['act'] == 'logout')
+  { // logout
+    logout_user();
+    redirect(make_index_url());
+  }
+  elseif (!empty($_SESSION['pwg_uid']))
+  {
+    $user['id'] = $_SESSION['pwg_uid'];
+  }
+}
+
+// Now check the auto-login
+if ( $user['id']==$conf['guest_id'] )
+{
+  auto_login();
+}
+
+if (session_id()=="")
+{
+  session_start();
+}
+
+// using Apache authentication override the above user search
+if ($conf['apache_authentication'] and isset($_SERVER['REMOTE_USER']))
+{
+  if (!($user['id'] = get_userid($_SERVER['REMOTE_USER'])))
+  {
+    register_user($_SERVER['REMOTE_USER'], '', '', false);
+    $user['id'] = get_userid($_SERVER['REMOTE_USER']);
+  }
+}
+
+$user = build_user( $user['id'],
+          ( defined('IN_ADMIN') and IN_ADMIN ) ? false : true // use cache ?
+         );
+if ($conf['browser_language'] and (is_a_guest() or is_generic()) )
+{
+  get_browser_language($user['language']);
+}
+trigger_action('user_init', $user);
+?>
Index: /tags/2.0.2/include/ws_core.inc.php
===================================================================
--- /tags/2.0.2/include/ws_core.inc.php	(revision 3278)
+++ /tags/2.0.2/include/ws_core.inc.php	(revision 3278)
@@ -0,0 +1,579 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+/**** WEB SERVICE CORE CLASSES************************************************
+ * PwgServer - main object - the link between web service methods, request
+ *  handler and response encoder
+ * PwgRequestHandler - base class for handlers
+ * PwgResponseEncoder - base class for response encoders
+ * PwgError, PwgNamedArray, PwgNamedStruct - can be used by web service functions
+ * as return values
+ */
+
+
+define( 'WS_PARAM_ACCEPT_ARRAY',  0x010000 );
+define( 'WS_PARAM_FORCE_ARRAY',   0x030000 );
+define( 'WS_PARAM_OPTIONAL',      0x040000 );
+
+define( 'WS_ERR_INVALID_METHOD',  501 );
+define( 'WS_ERR_MISSING_PARAM',   1002 );
+define( 'WS_ERR_INVALID_PARAM',   1003 );
+
+define( 'WS_XML_ATTRIBUTES', 'attributes_xml_');
+define( 'WS_XML_CONTENT', 'content_xml_');
+
+/**
+ * PwgError object can be returned from any web service function implementation.
+ */
+class PwgError
+{
+  private $_code;
+  private $_codeText;
+
+  function PwgError($code, $codeText)
+  {
+    if ($code>=400 and $code<600)
+    {
+      set_status_header($code, $codeText);
+    }
+
+    $this->_code = $code;
+    $this->_codeText = $codeText;
+  }
+
+  function code() { return $this->_code; }
+  function message() { return $this->_codeText; }
+}
+
+/**
+ * Simple wrapper around an array (keys are consecutive integers starting at 0).
+ * Provides naming clues for xml output (xml attributes vs. xml child elements?)
+ * Usually returned by web service function implementation.
+ */
+class PwgNamedArray
+{
+  /*private*/ var $_content;
+  /*private*/ var $_itemName;
+  /*private*/ var $_xmlAttributes;
+
+  /**
+   * Constructs a named array
+   * @param arr array (keys must be consecutive integers starting at 0)
+   * @param itemName string xml element name for values of arr (e.g. image)
+   * @param xmlAttributes array of sub-item attributes that will be encoded as
+   *      xml attributes instead of xml child elements
+   */
+  function PwgNamedArray($arr, $itemName, $xmlAttributes=array() )
+  {
+    $this->_content = $arr;
+    $this->_itemName = $itemName;
+    $this->_xmlAttributes = array_flip($xmlAttributes);
+  }
+}
+/**
+ * Simple wrapper around a "struct" (php array whose keys are not consecutive
+ * integers starting at 0). Provides naming clues for xml output (what is xml
+ * attributes and what is element)
+ */
+class PwgNamedStruct
+{
+  /*private*/ var $_content;
+  /*private*/ var $_name;
+  /*private*/ var $_xmlAttributes;
+
+  /**
+   * Constructs a named struct (usually returned by web service function
+   * implementation)
+   * @param name string - containing xml element name
+   * @param content array - the actual content (php array)
+   * @param xmlAttributes array - name of the keys in $content that will be
+   *    encoded as xml attributes (if null - automatically prefer xml attributes
+   *    whenever possible)
+   */
+  function PwgNamedStruct($name, $content, $xmlAttributes=null, $xmlElements=null )
+  {
+    $this->_name = $name;
+    $this->_content = $content;
+    if ( isset($xmlAttributes) )
+    {
+      $this->_xmlAttributes = array_flip($xmlAttributes);
+    }
+    else
+    {
+      $this->_xmlAttributes = array();
+      foreach ($this->_content as $key=>$value)
+      {
+        if (!empty($key) and (is_scalar($value) or is_null($value)) )
+        {
+          if ( empty($xmlElements) or !in_array($key,$xmlElements) )
+          {
+            $this->_xmlAttributes[$key]=1;
+          }
+        }
+      }
+    }
+  }
+}
+
+
+/**
+ * Abstract base class for request handlers.
+ */
+class PwgRequestHandler
+{
+  /** Virtual abstract method. Decodes the request (GET or POST) handles the
+   * method invocation as well as response sending.
+   */
+  function handleRequest(&$server) { assert(false); }
+}
+
+/**
+ *
+ * Base class for web service response encoder.
+ */
+class PwgResponseEncoder
+{
+  /** encodes the web service response to the appropriate output format
+   * @param response mixed the unencoded result of a service method call
+   */
+  function encodeResponse($response) { assert(false); }
+
+  /** default "Content-Type" http header for this kind of response format
+   */
+  function getContentType() { assert(false); }
+
+  /**
+   * returns true if the parameter is a 'struct' (php array type whose keys are
+   * NOT consecutive integers starting with 0)
+   */
+  static function is_struct(&$data)
+  {
+    if (is_array($data) )
+    {
+      if (range(0, count($data) - 1) !== array_keys($data) )
+      { # string keys, unordered, non-incremental keys, .. - whatever, make object
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /**
+   * removes all XML formatting from $response (named array, named structs, etc)
+   * usually called by every response encoder, except rest xml.
+   */
+  static function flattenResponse(&$response)
+  {
+    PwgResponseEncoder::_mergeAttributesAndContent($response);
+    PwgResponseEncoder::_removeNamedArray($response);
+    PwgResponseEncoder::_removeNamedStruct($response);
+    if (is_array($response))
+    { // need to call 2 times (first time might add new arrays)
+      array_walk_recursive($response, array('PwgResponseEncoder', '_remove_named_callback') );
+      array_walk_recursive($response, array('PwgResponseEncoder', '_remove_named_callback') );
+    }
+//print_r($response);
+    PwgResponseEncoder::_mergeAttributesAndContent($response);
+  }
+
+  private static function _remove_named_callback(&$value, $key)
+  {
+    do
+    {
+      $changed = 0;
+      $changed += PwgResponseEncoder::_removeNamedArray($value);
+      $changed += PwgResponseEncoder::_removeNamedStruct($value);
+  //    print_r('walk '.$key."<br/>\n");
+    }
+    while ($changed);
+  }
+
+  private static function _mergeAttributesAndContent(&$value)
+  {
+    if ( !is_array($value) )
+      return;
+/*    $first_key = '';
+    if (count($value)) { $ak = array_keys($value); $first_key = $ak[0]; }
+
+    print_r( '_mergeAttributesAndContent is_struct='.PwgResponseEncoder::is_struct($value)
+      .' count='.count($value)
+      .' first_key='.$first_key
+      ."<br/>\n"
+      );*/
+    $ret = 0;
+    if (PwgResponseEncoder::is_struct($value))
+    {
+      if ( isset($value[WS_XML_ATTRIBUTES]) )
+      {
+        $value = array_merge( $value, $value[WS_XML_ATTRIBUTES] );
+        unset( $value[WS_XML_ATTRIBUTES] );
+        $ret=1;
+      }
+      if ( isset($value[WS_XML_CONTENT]) )
+      {
+        $cont_processed = 0;
+        if ( count($value)==1 )
+        {
+          $value = $value[WS_XML_CONTENT];
+          $cont_processed=1;
+        }
+        else
+        {
+          if (PwgResponseEncoder::is_struct($value[WS_XML_CONTENT]))
+          {
+            $value = array_merge( $value, $value[WS_XML_CONTENT] );
+            unset( $value[WS_XML_CONTENT] );
+            $cont_processed=1;
+          }
+        }
+        $ret += $cont_processed;
+        if (!$cont_processed)
+        {
+          $value['_content'] = $value[WS_XML_CONTENT];
+          unset( $value[WS_XML_CONTENT] );
+          $ret++;
+        }
+      }
+    }
+
+    foreach ($value as $key=>$v)
+    {
+      if ( PwgResponseEncoder::_mergeAttributesAndContent($v) )
+      {
+        $value[$key]=$v;
+        $ret++;
+      }
+    }
+    return $ret;
+  }
+
+  private static function _removeNamedArray(&$value)
+  {
+    if ( strtolower( get_class($value) ) =='pwgnamedarray')
+    {
+      $value = $value->_content;
+      return 1;
+    }
+    return 0;
+  }
+
+  private static function _removeNamedStruct(&$value)
+  {
+    if ( strtolower( get_class($value) ) =='pwgnamedstruct')
+    {
+      if ( isset($value->_content['']) )
+      {
+        $unknown = $value->_content[''];
+        unset( $value->_content[''] );
+        $value->_content[$value->_name] = $unknown;
+      }
+      $value = $value->_content;
+      return 1;
+    }
+    return 0;
+  }
+}
+
+
+
+class PwgServer
+{
+  var $_requestHandler;
+  var $_requestFormat;
+  var $_responseEncoder;
+  var $_responseFormat;
+
+  var $_methods = array();
+
+  function PwgServer()
+  {
+  }
+
+  /**
+   *  Initializes the request handler.
+   */
+  function setHandler($requestFormat, &$requestHandler)
+  {
+    $this->_requestHandler = &$requestHandler;
+    $this->_requestFormat = $requestFormat;
+  }
+
+  /**
+   *  Initializes the request handler.
+   */
+  function setEncoder($responseFormat, &$encoder)
+  {
+    $this->_responseEncoder = &$encoder;
+    $this->_responseFormat = $responseFormat;
+  }
+
+  /**
+   * Runs the web service call (handler and response encoder should have been
+   * created)
+   */
+  function run()
+  {
+    if ( is_null($this->_responseEncoder) )
+    {
+      set_status_header(400);
+      @header("Content-Type: text/plain");
+      echo ("Cannot process your request. Unknown response format.
+Request format: ".@$this->_requestFormat." Response format: ".@$this->_responseFormat."\n");
+      var_export($this);
+      die(0);
+    }
+
+    if ( is_null($this->_requestHandler) )
+    {
+      $this->sendResponse( new PwgError(400, 'Unknown request format') );
+      return;
+    }
+
+    $this->addMethod('reflection.getMethodList',
+        array('PwgServer', 'ws_getMethodList'),
+        null, '' );
+    $this->addMethod('reflection.getMethodDetails',
+        array('PwgServer', 'ws_getMethodDetails'),
+        array('methodName'),'');
+
+    trigger_action('ws_add_methods', array(&$this) );
+    uksort( $this->_methods, 'strnatcmp' );
+    $this->_requestHandler->handleRequest($this);
+  }
+
+  /**
+   * Encodes a response and sends it back to the browser.
+   */
+  function sendResponse($response)
+  {
+    $encodedResponse = $this->_responseEncoder->encodeResponse($response);
+    $contentType = $this->_responseEncoder->getContentType();
+
+    @header('Content-Type: '.$contentType.'; charset='.get_pwg_charset());
+    print_r($encodedResponse);
+  }
+
+  /**
+   * Registers a web service method.
+   * @param methodName string - the name of the method as seen externally
+   * @param callback mixed - php method to be invoked internally
+   * @param params array - map of allowed parameter names with optional default
+   * values and parameter flags. Example of $params:
+   * array( 'param1' => array('default'=>523, 'flags'=>WS_PARAM_FORCE_ARRAY) ) .
+   * Possible parameter flags are:
+   * WS_PARAM_ALLOW_ARRAY - this parameter can be an array
+   * WS_PARAM_FORCE_ARRAY - if this parameter is scalar, force it to an array
+   *  before invoking the method
+   * @param description string - a description of the method.
+   */
+  function addMethod($methodName, $callback, $params=array(), $description, $include_file='')
+  {
+    if (!is_array($params))
+    {
+      $params = array();
+    }
+
+    if ( range(0, count($params) - 1) === array_keys($params) )
+    {
+      $params = array_flip($params);
+    }
+
+    foreach( $params as $param=>$options)
+    {
+      if ( !is_array($options) )
+      {
+        $params[$param] = array('flags'=>0);
+      }
+      else
+      {
+        $flags = isset($options['flags']) ? $options['flags'] : 0;
+        if ( array_key_exists('default', $options) )
+        {
+          $flags |= WS_PARAM_OPTIONAL;
+        }
+        if ( $flags & WS_PARAM_FORCE_ARRAY )
+        {
+          $flags |= WS_PARAM_ACCEPT_ARRAY;
+        }
+        $options['flags'] = $flags;
+        $params[$param] = $options;
+      }
+    }
+
+    $this->_methods[$methodName] = array(
+      'callback'    => $callback,
+      'description' => $description,
+      'signature'   => $params,
+      'include'     => $include_file,
+      );
+  }
+
+  function hasMethod($methodName)
+  {
+    return isset($this->_methods[$methodName]);
+  }
+
+  function getMethodDescription($methodName)
+  {
+    $desc = @$this->_methods[$methodName]['description'];
+    return isset($desc) ? $desc : '';
+  }
+
+  function getMethodSignature($methodName)
+  {
+    $signature = @$this->_methods[$methodName]['signature'];
+    return isset($signature) ? $signature : array();
+  }
+
+  /*static*/ function isPost()
+  {
+    return isset($HTTP_RAW_POST_DATA) or !empty($_POST);
+  }
+
+  /*static*/ function makeArrayParam(&$param)
+  {
+    if ( $param==null )
+    {
+      $param = array();
+    }
+    else
+    {
+      if (! is_array($param) )
+      {
+        $param = array($param);
+      }
+    }
+  }
+
+  /**
+   *  Invokes a registered method. Returns the return of the method (or
+   *  a PwgError object if the method is not found)
+   *  @param methodName string the name of the method to invoke
+   *  @param params array array of parameters to pass to the invoked method
+   */
+  function invoke($methodName, $params)
+  {
+    $method = @$this->_methods[$methodName];
+
+    if ( $method==null )
+    {
+      return new PwgError(WS_ERR_INVALID_METHOD, 'Method name "'.$methodName.'" is not valid');
+    }
+
+    // parameter check and data coercion !
+    $signature = $method['signature'];
+    $missing_params = array();
+    foreach($signature as $name=>$options)
+    {
+      $flags = $options['flags'];
+      if ( !array_key_exists($name, $params) )
+      {// parameter not provided in the request
+        if ( !($flags&WS_PARAM_OPTIONAL) )
+        {
+          $missing_params[] = $name;
+        }
+        else if ( array_key_exists('default',$options) )
+        {
+          $params[$name] = $options['default'];
+          if ( ($flags&WS_PARAM_FORCE_ARRAY) )
+          {
+            $this->makeArrayParam( $params[$name] );
+          }
+        }
+      }
+      else
+      {// parameter provided - do some basic checks
+        $the_param = $params[$name];
+        if ( is_array($the_param) and ($flags&WS_PARAM_ACCEPT_ARRAY)==0 )
+        {
+          return new PwgError(WS_ERR_INVALID_PARAM, $name.' must be scalar' );
+        }
+        if ( ($flags&WS_PARAM_FORCE_ARRAY) )
+        {
+          $this->makeArrayParam( $the_param );
+        }
+        if ( isset($options['maxValue']) and $the_param>$options['maxValue'])
+        {
+          $the_param = $options['maxValue'];
+        }
+        $params[$name] = $the_param;
+      }
+    }
+    if (count($missing_params))
+    {
+      return new PwgError(WS_ERR_MISSING_PARAM, 'Missing parameters: '.implode(',',$missing_params));
+    }
+    $result = trigger_event('ws_invoke_allowed', true, $methodName, $params);
+    if ( strtolower( get_class($result) )!='pwgerror')
+    {
+      if ( !empty($method['include']) )
+      {
+        include_once( $method['include'] );
+      }
+      $result = call_user_func_array($method['callback'], array($params, &$this) );
+    }
+    return $result;
+  }
+
+  /**
+   * WS reflection method implementation: lists all available methods
+   */
+  static function ws_getMethodList($params, &$service)
+  {
+    return array('methods' => new PwgNamedArray( array_keys($service->_methods),'method' ) );
+  }
+
+  /**
+   * WS reflection method implementation: gets information about a given method
+   */
+  static function ws_getMethodDetails($params, &$service)
+  {
+    $methodName = $params['methodName'];
+    if (!$service->hasMethod($methodName))
+    {
+      return new PwgError(WS_ERR_INVALID_PARAM,
+            'Requested method does not exist');
+    }
+    $res = array(
+      'name' => $methodName,
+      'description' => $service->getMethodDescription($methodName),
+      'params' => array(),
+    );
+    $signature = $service->getMethodSignature($methodName);
+    foreach ($signature as $name => $options)
+    {
+      $param_data = array(
+        'name' => $name,
+        'optional' => ($options['flags']&WS_PARAM_OPTIONAL)?true:false,
+        'acceptArray' => ($options['flags']&WS_PARAM_ACCEPT_ARRAY)?true:false,
+        );
+      if (isset($options['default']))
+      {
+        $param_data['defaultValue'] = $options['default'];
+      }
+      $res['params'][] = $param_data;
+    }
+    return $res;
+  }
+}
+?>
Index: /tags/2.0.2/include/ws_functions.inc.php
===================================================================
--- /tags/2.0.2/include/ws_functions.inc.php	(revision 3278)
+++ /tags/2.0.2/include/ws_functions.inc.php	(revision 3278)
@@ -0,0 +1,1746 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+/**** IMPLEMENTATION OF WEB SERVICE METHODS ***********************************/
+
+/**
+ * Event handler for method invocation security check. Should return a PwgError
+ * if the preconditions are not satifsied for method invocation.
+ */
+function ws_isInvokeAllowed($res, $methodName, $params)
+{
+  global $conf;
+
+  if ( strpos($methodName,'reflection.')===0 )
+  { // OK for reflection
+    return $res;
+  }
+
+  if ( !is_autorize_status(ACCESS_GUEST) and
+      strpos($methodName,'pwg.session.')!==0 )
+  {
+    return new PwgError(401, 'Access denied');
+  }
+
+  return $res;
+}
+
+/**
+ * returns a "standard" (for our web service) array of sql where clauses that
+ * filters the images (images table only)
+ */
+function ws_std_image_sql_filter( $params, $tbl_name='' )
+{
+  $clauses = array();
+  if ( is_numeric($params['f_min_rate']) )
+  {
+    $clauses[] = $tbl_name.'average_rate>'.$params['f_min_rate'];
+  }
+  if ( is_numeric($params['f_max_rate']) )
+  {
+    $clauses[] = $tbl_name.'average_rate<='.$params['f_max_rate'];
+  }
+  if ( is_numeric($params['f_min_hit']) )
+  {
+    $clauses[] = $tbl_name.'hit>'.$params['f_min_hit'];
+  }
+  if ( is_numeric($params['f_max_hit']) )
+  {
+    $clauses[] = $tbl_name.'hit<='.$params['f_max_hit'];
+  }
+  if ( isset($params['f_min_date_posted']) )
+  {
+    $clauses[] = $tbl_name."date_available>='".$params['f_min_date_posted']."'";
+  }
+  if ( isset($params['f_max_date_posted']) )
+  {
+    $clauses[] = $tbl_name."date_available<'".$params['f_max_date_posted']."'";
+  }
+  if ( isset($params['f_min_date_created']) )
+  {
+    $clauses[] = $tbl_name."date_creation>='".$params['f_min_date_created']."'";
+  }
+  if ( isset($params['f_max_date_created']) )
+  {
+    $clauses[] = $tbl_name."date_creation<'".$params['f_max_date_created']."'";
+  }
+  if ( is_numeric($params['f_min_ratio']) )
+  {
+    $clauses[] = $tbl_name.'width/'.$tbl_name.'height>'.$params['f_min_ratio'];
+  }
+  if ( is_numeric($params['f_max_ratio']) )
+  {
+    $clauses[] = $tbl_name.'width/'.$tbl_name.'height<='.$params['f_max_ratio'];
+  }
+  if ( $params['f_with_thumbnail'] )
+  {
+    $clauses[] = $tbl_name.'tn_ext IS NOT NULL';
+  }
+  return $clauses;
+}
+
+/**
+ * returns a "standard" (for our web service) ORDER BY sql clause for images
+ */
+function ws_std_image_sql_order( $params, $tbl_name='' )
+{
+  $ret = '';
+  if ( empty($params['order']) )
+  {
+    return $ret;
+  }
+  $matches = array();
+  preg_match_all('/([a-z_]+) *(?:(asc|desc)(?:ending)?)? *(?:, *|$)/i',
+    $params['order'], $matches);
+  for ($i=0; $i<count($matches[1]); $i++)
+  {
+    switch ($matches[1][$i])
+    {
+      case 'date_created':
+        $matches[1][$i] = 'date_creation'; break;
+      case 'date_posted':
+        $matches[1][$i] = 'date_available'; break;
+      case 'rand': case 'random':
+        $matches[1][$i] = 'RAND()'; break;
+    }
+    $sortable_fields = array('id', 'file', 'name', 'hit', 'average_rate',
+      'date_creation', 'date_available', 'RAND()' );
+    if ( in_array($matches[1][$i], $sortable_fields) )
+    {
+      if (!empty($ret))
+        $ret .= ', ';
+      if ($matches[1][$i] != 'RAND()' )
+      {
+        $ret .= $tbl_name;
+      }
+      $ret .= $matches[1][$i];
+      $ret .= ' '.$matches[2][$i];
+    }
+  }
+  return $ret;
+}
+
+/**
+ * returns an array map of urls (thumb/element) for image_row - to be returned
+ * in a standard way by different web service methods
+ */
+function ws_std_get_urls($image_row)
+{
+  $ret = array(
+    'tn_url' => get_thumbnail_url($image_row),
+    'element_url' => get_element_url($image_row)
+  );
+  global $user;
+  if ($user['enabled_high'] and $image_row['has_high'] )
+  {
+    $ret['high_url'] = get_high_url($image_row);
+  }
+  return $ret;
+}
+
+/**
+ * returns an array of image attributes that are to be encoded as xml attributes
+ * instead of xml elements
+ */
+function ws_std_get_image_xml_attributes()
+{
+  return array(
+    'id','tn_url','element_url','high_url', 'file','width','height','hit'
+    );
+}
+
+/**
+ * returns PWG version (web service method)
+ */
+function ws_getVersion($params, &$service)
+{
+  global $conf;
+  if ($conf['show_version'])
+    return PHPWG_VERSION;
+  else
+    return new PwgError(403, 'Forbidden');
+}
+
+function ws_caddie_add($params, &$service)
+{
+  if (!is_admin())
+  {
+    return new PwgError(401, 'Access denied');
+  }
+  $params['image_id'] = array_map( 'intval',$params['image_id'] );
+  if ( empty($params['image_id']) )
+  {
+    return new PwgError(WS_ERR_INVALID_PARAM, "Invalid image_id");
+  }
+  global $user;
+  $query = '
+SELECT id
+  FROM '.IMAGES_TABLE.' LEFT JOIN '.CADDIE_TABLE.' ON id=element_id AND user_id='.$user['id'].'
+  WHERE id IN ('.implode(',',$params['image_id']).')
+    AND element_id IS NULL';
+  $datas = array();
+  foreach ( array_from_query($query, 'id') as $id )
+  {
+    array_push($datas, array('element_id'=>$id, 'user_id'=>$user['id']) );
+  }
+  if (count($datas))
+  {
+    include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+    mass_inserts(CADDIE_TABLE, array('element_id','user_id'), $datas);
+  }
+  return count($datas);
+}
+
+/**
+ * returns images per category (web service method)
+ */
+function ws_categories_getImages($params, &$service)
+{
+  @include_once(PHPWG_ROOT_PATH.'include/functions_picture.inc.php');
+  global $user, $conf;
+
+  $images = array();
+
+  //------------------------------------------------- get the related categories
+  $where_clauses = array();
+  foreach($params['cat_id'] as $cat_id)
+  {
+    $cat_id = (int)$cat_id;
+    if ($cat_id<=0)
+      continue;
+    if ($params['recursive'])
+    {
+      $where_clauses[] = 'uppercats REGEXP \'(^|,)'.$cat_id.'(,|$)\'';
+    }
+    else
+    {
+      $where_clauses[] = 'id='.$cat_id;
+    }
+  }
+  if (!empty($where_clauses))
+  {
+    $where_clauses = array( '('.
+    implode('
+    OR ', $where_clauses) . ')'
+      );
+  }
+  $where_clauses[] = get_sql_condition_FandF(
+        array('forbidden_categories' => 'id'),
+        NULL, true
+      );
+
+  $query = '
+SELECT id, name, permalink, image_order
+  FROM '.CATEGORIES_TABLE.'
+  WHERE '. implode('
+    AND ', $where_clauses);
+  $result = pwg_query($query);
+  $cats = array();
+  while ($row = mysql_fetch_assoc($result))
+  {
+    $row['id'] = (int)$row['id'];
+    $cats[ $row['id'] ] = $row;
+  }
+
+  //-------------------------------------------------------- get the images
+  if ( !empty($cats) )
+  {
+    $where_clauses = ws_std_image_sql_filter( $params, 'i.' );
+    $where_clauses[] = 'category_id IN ('
+      .implode(',', array_keys($cats) )
+      .')';
+    $where_clauses[] = get_sql_condition_FandF( array(
+          'visible_images' => 'i.id'
+        ), null, true
+      );
+
+    $order_by = ws_std_image_sql_order($params, 'i.');
+    if ( empty($order_by)
+          and count($params['cat_id'])==1
+          and isset($cats[ $params['cat_id'][0] ]['image_order'])
+        )
+    {
+      $order_by = $cats[ $params['cat_id'][0] ]['image_order'];
+    }
+    $order_by = empty($order_by) ? $conf['order_by'] : 'ORDER BY '.$order_by;
+
+    $query = '
+SELECT i.*, GROUP_CONCAT(category_id) cat_ids
+  FROM '.IMAGES_TABLE.' i
+    INNER JOIN '.IMAGE_CATEGORY_TABLE.' ON i.id=image_id
+  WHERE '. implode('
+    AND ', $where_clauses).'
+GROUP BY i.id
+'.$order_by.'
+LIMIT '.(int)($params['per_page']*$params['page']).','.(int)$params['per_page'];
+
+    $result = pwg_query($query);
+    while ($row = mysql_fetch_assoc($result))
+    {
+      $image = array();
+      foreach ( array('id', 'width', 'height', 'hit') as $k )
+      {
+        if (isset($row[$k]))
+        {
+          $image[$k] = (int)$row[$k];
+        }
+      }
+      foreach ( array('file', 'name', 'comment') as $k )
+      {
+        $image[$k] = $row[$k];
+      }
+      $image = array_merge( $image, ws_std_get_urls($row) );
+
+      $image_cats = array();
+      foreach ( explode(',', $row['cat_ids']) as $cat_id )
+      {
+        $url = make_index_url(
+                array(
+                  'category' => $cats[$cat_id],
+                  )
+                );
+        $page_url = make_picture_url(
+                array(
+                  'category' => $cats[$cat_id],
+                  'image_id' => $row['id'],
+                  'image_file' => $row['file'],
+                  )
+                );
+        array_push( $image_cats,  array(
+              WS_XML_ATTRIBUTES => array (
+                  'id' => (int)$cat_id,
+                  'url' => $url,
+                  'page_url' => $page_url,
+                )
+            )
+          );
+      }
+
+      $image['categories'] = new PwgNamedArray(
+            $image_cats,'category', array('id','url','page_url')
+          );
+      array_push($images, $image);
+    }
+  }
+
+  return array( 'images' =>
+    array (
+      WS_XML_ATTRIBUTES =>
+        array(
+            'page' => $params['page'],
+            'per_page' => $params['per_page'],
+            'count' => count($images)
+          ),
+       WS_XML_CONTENT => new PwgNamedArray($images, 'image',
+          ws_std_get_image_xml_attributes() )
+      )
+    );
+}
+
+
+/**
+ * returns a list of categories (web service method)
+ */
+function ws_categories_getList($params, &$service)
+{
+  global $user,$conf;
+
+  $where = array();
+
+  if (!$params['recursive'])
+  {
+    if ($params['cat_id']>0)
+      $where[] = '(id_uppercat='.(int)($params['cat_id']).'
+    OR id='.(int)($params['cat_id']).')';
+    else
+      $where[] = 'id_uppercat IS NULL';
+  }
+  else if ($params['cat_id']>0)
+  {
+    $where[] = 'uppercats REGEXP \'(^|,)'.
+      (int)($params['cat_id'])
+      .'(,|$)\'';
+  }
+
+  if ($params['public'])
+  {
+    $where[] = 'status = "public"';
+    $where[] = 'visible = "true"';
+    $where[]= 'user_id='.$conf['guest_id'];
+  }
+  else
+  {
+    $where[]= 'user_id='.$user['id'];
+  }
+
+  $query = '
+SELECT id, name, permalink, uppercats, global_rank,
+    nb_images, count_images AS total_nb_images,
+    date_last, max_date_last, count_categories AS nb_categories
+  FROM '.CATEGORIES_TABLE.'
+   INNER JOIN '.USER_CACHE_CATEGORIES_TABLE.' ON id=cat_id
+  WHERE '. implode('
+    AND ', $where);
+
+  $result = pwg_query($query);
+
+  $cats = array();
+  while ($row = mysql_fetch_assoc($result))
+  {
+    $row['url'] = make_index_url(
+        array(
+          'category' => $row
+          )
+      );
+    foreach( array('id','nb_images','total_nb_images','nb_categories') as $key)
+    {
+      $row[$key] = (int)$row[$key];
+    }
+
+    array_push($cats, $row);
+  }
+  usort($cats, 'global_rank_compare');
+  return array(
+    'categories' => new PwgNamedArray(
+      $cats,
+      'category',
+      array(
+        'id',
+        'url',
+        'nb_images',
+        'total_nb_images',
+        'nb_categories',
+        'date_last',
+        'max_date_last',
+        )
+      )
+    );
+}
+
+/**
+ * returns the list of categories as you can see them in administration (web
+ * service method).
+ *
+ * Only admin can run this method and permissions are not taken into
+ * account.
+ */
+function ws_categories_getAdminList($params, &$service)
+{
+  if (!is_admin())
+  {
+    return new PwgError(401, 'Access denied');
+  }
+
+  $query = '
+SELECT
+    category_id,
+    COUNT(*) AS counter
+  FROM '.IMAGE_CATEGORY_TABLE.'
+  GROUP BY category_id
+;';
+  $nb_images_of = simple_hash_from_query($query, 'category_id', 'counter');
+
+  $query = '
+SELECT
+    id,
+    name,
+    uppercats,
+    global_rank
+  FROM '.CATEGORIES_TABLE.'
+;';
+  $result = pwg_query($query);
+  $cats = array();
+
+  while ($row = mysql_fetch_assoc($result))
+  {
+    $id = $row['id'];
+    $row['nb_images'] = isset($nb_images_of[$id]) ? $nb_images_of[$id] : 0;
+    array_push($cats, $row);
+  }
+
+  usort($cats, 'global_rank_compare');
+  return array(
+    'categories' => new PwgNamedArray(
+      $cats,
+      'category',
+      array(
+        'id',
+        'nb_images',
+        'name',
+        'uppercats',
+        'global_rank',
+        )
+      )
+    );
+}
+
+/**
+ * returns detailed information for an element (web service method)
+ */
+function ws_images_addComment($params, &$service)
+{
+  if (!$service->isPost())
+  {
+    return new PwgError(405, "This method requires HTTP POST");
+  }
+  $params['image_id'] = (int)$params['image_id'];
+  $query = '
+SELECT DISTINCT image_id
+  FROM '.IMAGE_CATEGORY_TABLE.' INNER JOIN '.CATEGORIES_TABLE.' ON category_id=id
+  WHERE commentable="true"
+    AND image_id='.$params['image_id'].
+    get_sql_condition_FandF(
+      array(
+        'forbidden_categories' => 'id',
+        'visible_categories' => 'id',
+        'visible_images' => 'image_id'
+      ),
+      ' AND'
+    );
+  if ( !mysql_num_rows( pwg_query( $query ) ) )
+  {
+    return new PwgError(WS_ERR_INVALID_PARAM, "Invalid image_id");
+  }
+
+  $comm = array(
+    'author' => trim( stripslashes($params['author']) ),
+    'content' => trim( stripslashes($params['content']) ),
+    'image_id' => $params['image_id'],
+   );
+
+  include_once(PHPWG_ROOT_PATH.'include/functions_comment.inc.php');
+
+  $comment_action = insert_user_comment(
+      $comm, $params['key'], $infos
+    );
+
+  switch ($comment_action)
+  {
+    case 'reject':
+      array_push($infos, l10n('comment_not_added') );
+      return new PwgError(403, implode("\n", $infos) );
+    case 'validate':
+    case 'moderate':
+      $ret = array(
+          'id' => $comm['id'],
+          'validation' => $comment_action=='validate',
+        );
+      return new PwgNamedStruct(
+          'comment',
+          $ret,
+          null, array()
+        );
+    default:
+      return new PwgError(500, "Unknown comment action ".$comment_action );
+  }
+}
+
+/**
+ * returns detailed information for an element (web service method)
+ */
+function ws_images_getInfo($params, &$service)
+{
+  @include_once(PHPWG_ROOT_PATH.'include/functions_picture.inc.php');
+  global $user, $conf;
+  $params['image_id'] = (int)$params['image_id'];
+  if ( $params['image_id']<=0 )
+  {
+    return new PwgError(WS_ERR_INVALID_PARAM, "Invalid image_id");
+  }
+
+  $query='
+SELECT * FROM '.IMAGES_TABLE.'
+  WHERE id='.$params['image_id'].
+    get_sql_condition_FandF(
+      array('visible_images' => 'id'),
+      ' AND'
+    ).'
+LIMIT 1';
+
+  $image_row = mysql_fetch_assoc(pwg_query($query));
+  if ($image_row==null)
+  {
+    return new PwgError(404, "image_id not found");
+  }
+  $image_row = array_merge( $image_row, ws_std_get_urls($image_row) );
+
+  //-------------------------------------------------------- related categories
+  $query = '
+SELECT id, name, permalink, uppercats, global_rank, commentable
+  FROM '.IMAGE_CATEGORY_TABLE.'
+    INNER JOIN '.CATEGORIES_TABLE.' ON category_id = id
+  WHERE image_id = '.$image_row['id'].
+  get_sql_condition_FandF(
+      array( 'forbidden_categories' => 'category_id' ),
+      ' AND'
+    ).'
+;';
+  $result = pwg_query($query);
+  $is_commentable = false;
+  $related_categories = array();
+  while ($row = mysql_fetch_assoc($result))
+  {
+    if ($row['commentable']=='true')
+    {
+      $is_commentable = true;
+    }
+    unset($row['commentable']);
+    $row['url'] = make_index_url(
+        array(
+          'category' => $row
+          )
+      );
+
+    $row['page_url'] = make_picture_url(
+        array(
+          'image_id' => $image_row['id'],
+          'image_file' => $image_row['file'],
+          'category' => $row
+          )
+      );
+    $row['id']=(int)$row['id'];
+    array_push($related_categories, $row);
+  }
+  usort($related_categories, 'global_rank_compare');
+  if ( empty($related_categories) )
+  {
+    return new PwgError(401, 'Access denied');
+  }
+
+  //-------------------------------------------------------------- related tags
+  $related_tags = get_common_tags( array($image_row['id']), -1 );
+  foreach( $related_tags as $i=>$tag)
+  {
+    $tag['url'] = make_index_url(
+        array(
+          'tags' => array($tag)
+          )
+      );
+    $tag['page_url'] = make_picture_url(
+        array(
+          'image_id' => $image_row['id'],
+          'image_file' => $image_row['file'],
+          'tags' => array($tag),
+          )
+      );
+    unset($tag['counter']);
+    $tag['id']=(int)$tag['id'];
+    $related_tags[$i]=$tag;
+  }
+  //------------------------------------------------------------- related rates
+  $query = '
+SELECT COUNT(rate) AS count
+     , ROUND(AVG(rate),2) AS average
+     , ROUND(STD(rate),2) AS stdev
+  FROM '.RATE_TABLE.'
+  WHERE element_id = '.$image_row['id'].'
+;';
+  $rating = mysql_fetch_assoc(pwg_query($query));
+  $rating['count'] = (int)$rating['count'];
+
+  //---------------------------------------------------------- related comments
+  $related_comments = array();
+
+  $where_comments = 'image_id = '.$image_row['id'];
+  if ( !is_admin() )
+  {
+    $where_comments .= '
+    AND validated="true"';
+  }
+
+  $query = '
+SELECT COUNT(id) nb_comments
+  FROM '.COMMENTS_TABLE.'
+  WHERE '.$where_comments;
+  list($nb_comments) = array_from_query($query, 'nb_comments');
+  $nb_comments = (int)$nb_comments;
+
+  if ( $nb_comments>0 and $params['comments_per_page']>0 )
+  {
+    $query = '
+SELECT id, date, author, content
+  FROM '.COMMENTS_TABLE.'
+  WHERE '.$where_comments.'
+  ORDER BY date
+  LIMIT '.(int)($params['comments_per_page']*$params['comments_page']).
+    ','.(int)$params['comments_per_page'];
+
+    $result = pwg_query($query);
+    while ($row = mysql_fetch_assoc($result))
+    {
+      $row['id']=(int)$row['id'];
+      array_push($related_comments, $row);
+    }
+  }
+
+  $comment_post_data = null;
+  if ($is_commentable and
+      (!is_a_guest()
+        or (is_a_guest() and $conf['comments_forall'] )
+      )
+      )
+  {
+    $comment_post_data['author'] = $user['username'];
+    $comment_post_data['key'] = get_comment_post_key($params['image_id']);
+  }
+
+  $ret = $image_row;
+  foreach ( array('id','width','height','hit','filesize') as $k )
+  {
+    if (isset($ret[$k]))
+    {
+      $ret[$k] = (int)$ret[$k];
+    }
+  }
+  foreach ( array('path', 'storage_category_id') as $k )
+  {
+    unset($ret[$k]);
+  }
+
+  $ret['rates'] = array( WS_XML_ATTRIBUTES => $rating );
+  $ret['categories'] = new PwgNamedArray($related_categories, 'category', array('id','url', 'page_url') );
+  $ret['tags'] = new PwgNamedArray($related_tags, 'tag', array('id','url_name','url','name','page_url') );
+  if ( isset($comment_post_data) )
+  {
+    $ret['comment_post'] = array( WS_XML_ATTRIBUTES => $comment_post_data );
+  }
+  $ret['comments'] = array(
+     WS_XML_ATTRIBUTES =>
+        array(
+          'page' => $params['comments_page'],
+          'per_page' => $params['comments_per_page'],
+          'count' => count($related_comments),
+          'nb_comments' => $nb_comments,
+        ),
+     WS_XML_CONTENT => new PwgNamedArray($related_comments, 'comment', array('id','date') )
+      );
+
+  return new PwgNamedStruct('image',$ret, null, array('name','comment') );
+}
+
+
+/**
+ * rates the image_id in the parameter
+ */
+function ws_images_Rate($params, &$service)
+{
+  $image_id = (int)$params['image_id'];
+  $query = '
+SELECT DISTINCT id FROM '.IMAGES_TABLE.'
+  INNER JOIN '.IMAGE_CATEGORY_TABLE.' ON id=image_id
+  WHERE id='.$image_id
+  .get_sql_condition_FandF(
+    array(
+        'forbidden_categories' => 'category_id',
+        'forbidden_images' => 'id',
+      ),
+    '    AND'
+    ).'
+    LIMIT 1';
+  if ( mysql_num_rows( pwg_query($query) )==0 )
+  {
+    return new PwgError(404, "Invalid image_id or access denied" );
+  }
+  $rate = (int)$params['rate'];
+  include_once(PHPWG_ROOT_PATH.'include/functions_rate.inc.php');
+  $res = rate_picture( $image_id, $rate );
+  if ($res==false)
+  {
+    global $conf;
+    return new PwgError( 403, "Forbidden or rate not in ". implode(',',$conf['rate_items']));
+  }
+  return $res;
+}
+
+
+/**
+ * returns a list of elements corresponding to a query search
+ */
+function ws_images_search($params, &$service)
+{
+  global $page;
+  $images = array();
+  include_once( PHPWG_ROOT_PATH .'include/functions_search.inc.php' );
+  include_once(PHPWG_ROOT_PATH.'include/functions_picture.inc.php');
+
+  $where_clauses = ws_std_image_sql_filter( $params, 'i.' );
+  $order_by = ws_std_image_sql_order($params, 'i.');
+
+  $super_order_by = false;
+  if ( !empty($order_by) )
+  {
+    global $conf;
+    $conf['order_by'] = 'ORDER BY '.$order_by;
+    $super_order_by=true; // quick_search_result might be faster
+  }
+
+  $search_result = get_quick_search_results($params['query'],
+      $super_order_by,
+      implode(',', $where_clauses)
+    );
+
+  $image_ids = array_slice(
+      $search_result['items'],
+      $params['page']*$params['per_page'],
+      $params['per_page']
+    );
+
+  if ( count($image_ids) )
+  {
+    $query = '
+SELECT * FROM '.IMAGES_TABLE.'
+  WHERE id IN ('.implode(',', $image_ids).')';
+
+    $image_ids = array_flip($image_ids);
+    $result = pwg_query($query);
+    while ($row = mysql_fetch_assoc($result))
+    {
+      $image = array();
+      foreach ( array('id', 'width', 'height', 'hit') as $k )
+      {
+        if (isset($row[$k]))
+        {
+          $image[$k] = (int)$row[$k];
+        }
+      }
+      foreach ( array('file', 'name', 'comment') as $k )
+      {
+        $image[$k] = $row[$k];
+      }
+      $image = array_merge( $image, ws_std_get_urls($row) );
+      $images[$image_ids[$image['id']]] = $image;
+    }
+    ksort($images, SORT_NUMERIC);
+    $images = array_values($images);
+  }
+
+
+  return array( 'images' =>
+    array (
+      WS_XML_ATTRIBUTES =>
+        array(
+            'page' => $params['page'],
+            'per_page' => $params['per_page'],
+            'count' => count($images)
+          ),
+       WS_XML_CONTENT => new PwgNamedArray($images, 'image',
+          ws_std_get_image_xml_attributes() )
+      )
+    );
+}
+
+function ws_images_setPrivacyLevel($params, &$service)
+{
+  if (!is_admin() || is_adviser() )
+  {
+    return new PwgError(401, 'Access denied');
+  }
+  $params['image_id'] = array_map( 'intval',$params['image_id'] );
+  if ( empty($params['image_id']) )
+  {
+    return new PwgError(WS_ERR_INVALID_PARAM, "Invalid image_id");
+  }
+  global $conf;
+  if ( !in_array( (int)$params['level'], $conf['available_permission_levels']) )
+  {
+    return new PwgError(WS_ERR_INVALID_PARAM, "Invalid level");
+  }
+  $query = '
+UPDATE '.IMAGES_TABLE.'
+  SET level='.(int)$params['level'].'
+  WHERE id IN ('.implode(',',$params['image_id']).')';
+  $result = pwg_query($query);
+  $affected_rows = mysql_affected_rows();
+  if ($affected_rows)
+  {
+    include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+    invalidate_user_cache();
+  }
+  return $affected_rows;
+}
+
+function ws_images_add_chunk($params, &$service)
+{
+  // data
+  // original_sum
+  // type {thumb, file, high}
+  // position
+  
+  if (!is_admin() || is_adviser() )
+  {
+    return new PwgError(401, 'Access denied');
+  }
+
+  $upload_dir = PHPWG_ROOT_PATH.'upload/buffer';
+
+  // create the upload directory tree if not exists
+  if (!is_dir($upload_dir)) {
+    umask(0000);
+    $recursive = true;
+    if (!@mkdir($upload_dir, 0777, $recursive))
+    {
+      return new PwgError(500, 'error during buffer directory creation');
+    }
+  }
+
+  if (!is_writable($upload_dir))
+  {
+    // last chance to make the directory writable
+    @chmod($upload_dir, 0777);
+
+    if (!is_writable($upload_dir))
+    {
+      return new PwgError(500, 'buffer directory has no write access');
+    }
+  }
+
+  secure_directory($upload_dir);
+
+  $filename = sprintf(
+    '%s-%s-%05u.block',
+    $params['original_sum'],
+    $params['type'],
+    $params['position']
+    );
+
+  ws_logfile('[ws_images_add_chunk] data length : '.strlen($params['data']));
+
+  $bytes_written = file_put_contents(
+    $upload_dir.'/'.$filename,
+    base64_decode($params['data'])
+    );
+
+  if (false === $bytes_written) {
+    return new PwgError(
+      500,
+      'an error has occured while writting chunk '.$params['position'].' for '.$params['type']
+      );
+  }
+}
+
+function merge_chunks($output_filepath, $original_sum, $type)
+{
+  ws_logfile('[merge_chunks] input parameter $output_filepath : '.$output_filepath);
+
+  $upload_dir = PHPWG_ROOT_PATH.'upload/buffer';
+  $pattern = '/'.$original_sum.'-'.$type.'/';
+  $chunks = array();
+  
+  if ($handle = opendir($upload_dir))
+  {
+    while (false !== ($file = readdir($handle)))
+    {
+      if (preg_match($pattern, $file))
+      {
+        ws_logfile($file);
+        array_push($chunks, $upload_dir.'/'.$file);
+      }
+    }
+    closedir($handle);
+  }
+
+  sort($chunks);
+
+  ws_logfile('[merge_chunks] memory_get_usage before loading chunks: '.memory_get_usage());
+  
+  foreach ($chunks as $chunk)
+  {
+    $string = file_get_contents($chunk);
+    
+    ws_logfile('[merge_chunks] memory_get_usage on chunk '.++$i.': '.memory_get_usage());
+    
+    if (!file_put_contents($output_filepath, $string, FILE_APPEND))
+    {
+      return new PwgError(500, 'error while writting chunks for '.$output_filepath);
+    }
+    
+    unlink($chunk);
+  }
+
+  ws_logfile('[merge_chunks] memory_get_usage after loading chunks: '.memory_get_usage());
+}
+
+function ws_images_add($params, &$service)
+{
+  global $conf;
+  if (!is_admin() || is_adviser() )
+  {
+    return new PwgError(401, 'Access denied');
+  }
+
+  // name
+  // category_id
+  // file_content
+  // file_sum
+  // thumbnail_content
+  // thumbnail_sum
+  // rank
+
+  // $fh_log = fopen('/tmp/php.log', 'w');
+  // fwrite($fh_log, time()."\n");
+  // fwrite($fh_log, 'input rank :'.$params['rank']."\n");
+  // fwrite($fh_log, 'input:  '.$params['file_sum']."\n");
+  // fwrite($fh_log, 'input:  '.$params['thumbnail_sum']."\n");
+
+  // does the image already exists ?
+  $query = '
+SELECT
+    COUNT(*) AS counter
+  FROM '.IMAGES_TABLE.'
+  WHERE md5sum = \''.$params['original_sum'].'\'
+;';
+  list($counter) = mysql_fetch_row(pwg_query($query));
+  if ($counter != 0) {
+    return new PwgError(500, 'file already exists');
+  }
+
+  // current date
+  list($dbnow) = mysql_fetch_row(pwg_query('SELECT NOW();'));
+  list($year, $month, $day) = preg_split('/[^\d]/', $dbnow, 4);
+
+  // upload directory hierarchy
+  $upload_dir = sprintf(
+    PHPWG_ROOT_PATH.'upload/%s/%s/%s',
+    $year,
+    $month,
+    $day
+    );
+
+  //fwrite($fh_log, $upload_dir."\n");
+
+  // create the upload directory tree if not exists
+  if (!is_dir($upload_dir)) {
+    umask(0000);
+    $recursive = true;
+    if (!@mkdir($upload_dir, 0777, $recursive))
+    {
+      return new PwgError(500, 'error during directory creation');
+    }
+  }
+
+  if (!is_writable($upload_dir))
+  {
+    // last chance to make the directory writable
+    @chmod($upload_dir, 0777);
+
+    if (!is_writable($upload_dir))
+    {
+      return new PwgError(500, 'directory has no write access');
+    }
+  }
+
+  secure_directory($upload_dir);
+
+  // compute file path
+  $date_string = preg_replace('/[^\d]/', '', $dbnow);
+  $random_string = substr($params['file_sum'], 0, 8);
+  $filename_wo_ext = $date_string.'-'.$random_string;
+  $file_path = $upload_dir.'/'.$filename_wo_ext.'.jpg';
+
+  // merge the photo file
+  merge_chunks($file_path, $params['original_sum'], 'file');
+  chmod($file_path, 0644);
+
+  // check dumped file md5sum against expected md5sum
+  $dumped_md5 = md5_file($file_path);
+  if ($dumped_md5 != $params['file_sum']) {
+    return new PwgError(500, 'file transfer failed');
+  }
+
+  // thumbnail directory is a subdirectory of the photo file, hard coded
+  // "thumbnail"
+  $thumbnail_dir = $upload_dir.'/thumbnail';
+  if (!is_dir($thumbnail_dir)) {
+    umask(0000);
+    if (!@mkdir($thumbnail_dir, 0777))
+    {
+      return new PwgError(500, 'error during thumbnail directory creation');
+    }
+  }
+
+  if (!is_writable($thumbnail_dir))
+  {
+    // last chance to make the directory writable
+    @chmod($thumbnail_dir, 0777);
+
+    if (!is_writable($thumbnail_dir))
+    {
+      return new PwgError(500, 'thumbnail directory has no write access');
+    }
+  }
+
+  secure_directory($thumbnail_dir);
+
+  // thumbnail path, the filename may use a prefix and the extension is
+  // always "jpg" (no matter what the real file format is)
+  $thumbnail_path = sprintf(
+    '%s/%s%s.%s',
+    $thumbnail_dir,
+    $conf['prefix_thumbnail'],
+    $filename_wo_ext,
+    'jpg'
+    );
+
+  // merge the thumbnail
+  merge_chunks($thumbnail_path, $params['original_sum'], 'thumb');
+  chmod($thumbnail_path, 0644);
+
+  // check dumped thumbnail md5
+  $dumped_md5 = md5_file($thumbnail_path);
+  if ($dumped_md5 != $params['thumbnail_sum']) {
+    return new PwgError(500, 'thumbnail transfer failed');
+  }
+
+  // high resolution
+  if (isset($params['high_sum']))
+  {
+    // high resolution directory is a subdirectory of the photo file, hard
+    // coded "pwg_high"
+    $high_dir = $upload_dir.'/pwg_high';
+    if (!is_dir($high_dir)) {
+      umask(0000);
+      if (!@mkdir($high_dir, 0777))
+      {
+        return new PwgError(500, 'error during high directory creation');
+      }
+    }
+
+    if (!is_writable($high_dir))
+    {
+      // last chance to make the directory writable
+      @chmod($high_dir, 0777);
+
+      if (!is_writable($high_dir))
+      {
+        return new PwgError(500, 'high directory has no write access');
+      }
+    }
+
+    secure_directory($high_dir);
+
+    // high resolution path, same name as web size file
+    $high_path = sprintf(
+      '%s/%s.%s',
+      $high_dir,
+      $filename_wo_ext,
+      'jpg'
+      );
+
+    // merge the high resolution file
+    merge_chunks($high_path, $params['original_sum'], 'high');
+    chmod($high_path, 0644);
+
+    // check dumped thumbnail md5
+    $dumped_md5 = md5_file($high_path);
+    if ($dumped_md5 != $params['high_sum']) {
+      return new PwgError(500, 'high resolution transfer failed');
+    }
+
+    $high_filesize = floor(filesize($high_path)/1024);
+  }
+
+  list($width, $height) = getimagesize($file_path);
+
+  // database registration
+  $insert = array(
+    'file' => $filename_wo_ext.'.jpg',
+    'date_available' => $dbnow,
+    'tn_ext' => 'jpg',
+    'name' => $params['name'],
+    'path' => $file_path,
+    'filesize' => floor(filesize($file_path)/1024),
+    'width' => $width,
+    'height' => $height,
+    'md5sum' => $params['original_sum'],
+    );
+
+  $info_columns = array(
+    'name',
+    'author',
+    'comment',
+    'level',
+    'date_creation',
+    );
+
+  foreach ($info_columns as $key)
+  {
+    if (isset($params[$key]))
+    {
+      $insert[$key] = $params[$key];
+    }
+  }
+
+  if (isset($params['high_sum']))
+  {
+    $insert['has_high'] = 'true';
+    $insert['high_filesize'] = $high_filesize;
+  }
+
+  include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+  mass_inserts(
+    IMAGES_TABLE,
+    array_keys($insert),
+    array($insert)
+    );
+
+  $image_id = mysql_insert_id();
+
+  // let's add links between the image and the categories
+  if (isset($params['categories']))
+  {
+    ws_add_image_category_relations($image_id, $params['categories']);
+  }
+
+  // and now, let's create tag associations
+  if (isset($params['tag_ids']))
+  {
+    set_tags(
+      explode(',', $params['tag_ids']),
+      $image_id
+      );
+  }
+
+  invalidate_user_cache();
+
+  // fclose($fh_log);
+}
+
+/**
+ * perform a login (web service method)
+ */
+function ws_session_login($params, &$service)
+{
+  global $conf;
+
+  if (!$service->isPost())
+  {
+    return new PwgError(405, "This method requires HTTP POST");
+  }
+  if (try_log_user($params['username'], $params['password'],false))
+  {
+    return true;
+  }
+  return new PwgError(999, 'Invalid username/password');
+}
+
+
+/**
+ * performs a logout (web service method)
+ */
+function ws_session_logout($params, &$service)
+{
+  if (!is_a_guest())
+  {
+    logout_user();
+  }
+  return true;
+}
+
+function ws_session_getStatus($params, &$service)
+{
+  global $user;
+  $res = array();
+  $res['username'] = is_a_guest() ? 'guest' : $user['username'];
+  foreach ( array('status', 'template', 'theme', 'language') as $k )
+  {
+    $res[$k] = $user[$k];
+  }
+  $res['charset'] = get_pwg_charset();
+  return $res;
+}
+
+
+/**
+ * returns a list of tags (web service method)
+ */
+function ws_tags_getList($params, &$service)
+{
+  $tags = get_available_tags();
+  if ($params['sort_by_counter'])
+  {
+    usort($tags, create_function('$a,$b', 'return -$a["counter"]+$b["counter"];') );
+  }
+  else
+  {
+    usort($tags, 'tag_alpha_compare');
+  }
+  for ($i=0; $i<count($tags); $i++)
+  {
+    $tags[$i]['id'] = (int)$tags[$i]['id'];
+    $tags[$i]['counter'] = (int)$tags[$i]['counter'];
+    $tags[$i]['url'] = make_index_url(
+        array(
+          'section'=>'tags',
+          'tags'=>array($tags[$i])
+        )
+      );
+  }
+  return array('tags' => new PwgNamedArray($tags, 'tag', array('id','url_name','url', 'name', 'counter' )) );
+}
+
+/**
+ * returns the list of tags as you can see them in administration (web
+ * service method).
+ *
+ * Only admin can run this method and permissions are not taken into
+ * account.
+ */
+function ws_tags_getAdminList($params, &$service)
+{
+  if (!is_admin())
+  {
+    return new PwgError(401, 'Access denied');
+  }
+
+  $tags = get_all_tags();
+  return array(
+    'tags' => new PwgNamedArray(
+      $tags,
+      'tag',
+      array(
+        'name',
+        'id',
+        'url_name',
+        )
+      )
+    );
+}
+
+/**
+ * returns a list of images for tags (web service method)
+ */
+function ws_tags_getImages($params, &$service)
+{
+  @include_once(PHPWG_ROOT_PATH.'include/functions_picture.inc.php');
+  global $conf;
+
+  // first build all the tag_ids we are interested in
+  $params['tag_id'] = array_map( 'intval',$params['tag_id'] );
+  $tags = find_tags($params['tag_id'], $params['tag_url_name'], $params['tag_name']);
+  $tags_by_id = array();
+  foreach( $tags as $tag )
+  {
+    $tags['id'] = (int)$tag['id'];
+    $tags_by_id[ $tag['id'] ] = $tag;
+  }
+  unset($tags);
+  $tag_ids = array_keys($tags_by_id);
+
+
+  $image_ids = array();
+  $image_tag_map = array();
+
+  if ( !empty($tag_ids) )
+  { // build list of image ids with associated tags per image
+    if ($params['tag_mode_and'])
+    {
+      $image_ids = get_image_ids_for_tags( $tag_ids );
+    }
+    else
+    {
+      $query = '
+SELECT image_id, GROUP_CONCAT(tag_id) tag_ids
+  FROM '.IMAGE_TAG_TABLE.'
+  WHERE tag_id IN ('.implode(',',$tag_ids).')
+  GROUP BY image_id';
+      $result = pwg_query($query);
+      while ( $row=mysql_fetch_assoc($result) )
+      {
+        $row['image_id'] = (int)$row['image_id'];
+        array_push( $image_ids, $row['image_id'] );
+        $image_tag_map[ $row['image_id'] ] = explode(',', $row['tag_ids']);
+      }
+    }
+  }
+
+  $images = array();
+  if ( !empty($image_ids))
+  {
+    $where_clauses = ws_std_image_sql_filter($params);
+    $where_clauses[] = get_sql_condition_FandF(
+        array
+          (
+            'forbidden_categories' => 'category_id',
+            'visible_categories' => 'category_id',
+            'visible_images' => 'i.id'
+          ),
+        '', true
+      );
+    $where_clauses[] = 'id IN ('.implode(',',$image_ids).')';
+
+    $order_by = ws_std_image_sql_order($params);
+    if (empty($order_by))
+    {
+      $order_by = $conf['order_by'];
+    }
+    else
+    {
+      $order_by = 'ORDER BY '.$order_by;
+    }
+
+    $query = '
+SELECT DISTINCT i.* FROM '.IMAGES_TABLE.' i
+  INNER JOIN '.IMAGE_CATEGORY_TABLE.' ON i.id=image_id
+  WHERE '. implode('
+    AND ', $where_clauses).'
+'.$order_by.'
+LIMIT '.(int)($params['per_page']*$params['page']).','.(int)$params['per_page'];
+
+    $result = pwg_query($query);
+    while ($row = mysql_fetch_assoc($result))
+    {
+      $image = array();
+      foreach ( array('id', 'width', 'height', 'hit') as $k )
+      {
+        if (isset($row[$k]))
+        {
+          $image[$k] = (int)$row[$k];
+        }
+      }
+      foreach ( array('file', 'name', 'comment') as $k )
+      {
+        $image[$k] = $row[$k];
+      }
+      $image = array_merge( $image, ws_std_get_urls($row) );
+
+      $image_tag_ids = ($params['tag_mode_and']) ? $tag_ids : $image_tag_map[$image['id']];
+      $image_tags = array();
+      foreach ($image_tag_ids as $tag_id)
+      {
+        $url = make_index_url(
+                 array(
+                  'section'=>'tags',
+                  'tags'=> array($tags_by_id[$tag_id])
+                )
+              );
+        $page_url = make_picture_url(
+                 array(
+                  'section'=>'tags',
+                  'tags'=> array($tags_by_id[$tag_id]),
+                  'image_id' => $row['id'],
+                  'image_file' => $row['file'],
+                )
+              );
+        array_push($image_tags, array(
+                'id' => (int)$tag_id,
+                'url' => $url,
+                'page_url' => $page_url,
+              )
+            );
+      }
+      $image['tags'] = new PwgNamedArray($image_tags, 'tag',
+              array('id','url_name','url','page_url')
+            );
+      array_push($images, $image);
+    }
+  }
+
+  return array( 'images' =>
+    array (
+      WS_XML_ATTRIBUTES =>
+        array(
+            'page' => $params['page'],
+            'per_page' => $params['per_page'],
+            'count' => count($images)
+          ),
+       WS_XML_CONTENT => new PwgNamedArray($images, 'image',
+          ws_std_get_image_xml_attributes() )
+      )
+    );
+}
+
+function ws_categories_add($params, &$service)
+{
+  if (!is_admin() or is_adviser())
+  {
+    return new PwgError(401, 'Access denied');
+  }
+
+  include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+
+  $creation_output = create_virtual_category(
+    $params['name'],
+    $params['parent']
+    );
+
+  if (isset($creation_output['error']))
+  {
+    return new PwgError(500, $creation_output['error']);
+  }
+
+  invalidate_user_cache();
+
+  return $creation_output;
+}
+
+function ws_tags_add($params, &$service)
+{
+  if (!is_admin() or is_adviser())
+  {
+    return new PwgError(401, 'Access denied');
+  }
+
+  include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+
+  $creation_output = create_tag($params['name']);
+
+  if (isset($creation_output['error']))
+  {
+    return new PwgError(500, $creation_output['error']);
+  }
+
+  return $creation_output;
+}
+
+function ws_images_exist($params, &$service)
+{
+  if (!is_admin() or is_adviser())
+  {
+    return new PwgError(401, 'Access denied');
+  }
+
+  // search among photos the list of photos already added, based on md5sum
+  // list
+  $md5sums = preg_split(
+    '/[\s,;\|]/',
+    $params['md5sum_list'],
+    -1,
+    PREG_SPLIT_NO_EMPTY
+    );
+
+  $query = '
+SELECT
+    id,
+    md5sum
+  FROM '.IMAGES_TABLE.'
+  WHERE md5sum IN (\''.implode("','", $md5sums).'\')
+;';
+  $id_of_md5 = simple_hash_from_query($query, 'md5sum', 'id');
+
+  $result = array();
+
+  foreach ($md5sums as $md5sum)
+  {
+    $result[$md5sum] = null;
+    if (isset($id_of_md5[$md5sum]))
+    {
+      $result[$md5sum] = $id_of_md5[$md5sum];
+    }
+  }
+
+  return $result;
+}
+
+function ws_images_setInfo($params, &$service)
+{
+  global $conf;
+  if (!is_admin() || is_adviser() )
+  {
+    return new PwgError(401, 'Access denied');
+  }
+
+  // name
+  // category_id
+  // file_content
+  // file_sum
+  // thumbnail_content
+  // thumbnail_sum
+
+  $params['image_id'] = (int)$params['image_id'];
+  if ($params['image_id'] <= 0)
+  {
+    return new PwgError(WS_ERR_INVALID_PARAM, "Invalid image_id");
+  }
+
+  $query='
+SELECT *
+  FROM '.IMAGES_TABLE.'
+  WHERE id = '.$params['image_id'].'
+;';
+
+  $image_row = mysql_fetch_assoc(pwg_query($query));
+  if ($image_row == null)
+  {
+    return new PwgError(404, "image_id not found");
+  }
+
+  // database registration
+  $update = array(
+    'id' => $params['image_id'],
+    );
+
+  $info_columns = array(
+    'name',
+    'author',
+    'comment',
+    'level',
+    'date_creation',
+    );
+
+  $perform_update = false;
+  foreach ($info_columns as $key)
+  {
+    if (isset($params[$key]))
+    {
+      $perform_update = true;
+      $update[$key] = $params[$key];
+    }
+  }
+
+  if ($perform_update)
+  {
+    include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+    mass_updates(
+      IMAGES_TABLE,
+      array(
+        'primary' => array('id'),
+        'update'  => array_diff(array_keys($update), array('id'))
+        ),
+      array($update)
+      );
+  }
+
+  if (isset($params['categories']))
+  {
+    ws_add_image_category_relations(
+      $params['image_id'],
+      $params['categories']
+      );
+  }
+
+  // and now, let's create tag associations
+  if (isset($params['tag_ids']))
+  {
+    include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+    add_tags(
+      explode(',', $params['tag_ids']),
+      array($params['image_id'])
+      );
+  }
+
+  invalidate_user_cache();
+}
+
+function ws_add_image_category_relations($image_id, $categories_string)
+{
+  // let's add links between the image and the categories
+  //
+  // $params['categories'] should look like 123,12;456,auto;789 which means:
+  //
+  // 1. associate with category 123 on rank 12
+  // 2. associate with category 456 on automatic rank
+  // 3. associate with category 789 on automatic rank
+  $cat_ids = array();
+  $rank_on_category = array();
+  $search_current_ranks = false;
+
+  $tokens = explode(';', $categories_string);
+  foreach ($tokens as $token)
+  {
+    @list($cat_id, $rank) = explode(',', $token);
+
+    array_push($cat_ids, $cat_id);
+
+    if (!isset($rank))
+    {
+      $rank = 'auto';
+    }
+    $rank_on_category[$cat_id] = $rank;
+
+    if ($rank == 'auto')
+    {
+      $search_current_ranks = true;
+    }
+  }
+
+  $cat_ids = array_unique($cat_ids);
+
+  if (count($cat_ids) > 0)
+  {
+    if ($search_current_ranks)
+    {
+      $query = '
+SELECT
+    category_id,
+    MAX(rank) AS max_rank
+  FROM '.IMAGE_CATEGORY_TABLE.'
+  WHERE rank IS NOT NULL
+    AND category_id IN ('.implode(',', $cat_ids).')
+  GROUP BY category_id
+;';
+      $current_rank_of = simple_hash_from_query(
+        $query,
+        'category_id',
+        'max_rank'
+        );
+
+      foreach ($cat_ids as $cat_id)
+      {
+        if (!isset($current_rank_of[$cat_id]))
+        {
+          $current_rank_of[$cat_id] = 0;
+        }
+
+        if ('auto' == $rank_on_category[$cat_id])
+        {
+          $rank_on_category[$cat_id] = $current_rank_of[$cat_id] + 1;
+        }
+      }
+    }
+
+    $inserts = array();
+
+    foreach ($cat_ids as $cat_id)
+    {
+      array_push(
+        $inserts,
+        array(
+          'image_id' => $image_id,
+          'category_id' => $cat_id,
+          'rank' => $rank_on_category[$cat_id],
+          )
+        );
+    }
+
+    include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+    mass_inserts(
+      IMAGE_CATEGORY_TABLE,
+      array_keys($inserts[0]),
+      $inserts
+      );
+
+    update_category($cat_ids);
+  }
+}
+
+function ws_logfile($string)
+{
+  return true;
+  
+  file_put_contents(
+    '/tmp/piwigo_ws.log',
+    '['.date('c').'] '.$string."\n",
+    FILE_APPEND
+    );
+}
+?>
Index: /tags/2.0.2/include/ws_protocols/index.php
===================================================================
--- /tags/2.0.2/include/ws_protocols/index.php	(revision 3278)
+++ /tags/2.0.2/include/ws_protocols/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/include/ws_protocols/json_encoder.php
===================================================================
--- /tags/2.0.2/include/ws_protocols/json_encoder.php	(revision 3278)
+++ /tags/2.0.2/include/ws_protocols/json_encoder.php	(revision 3278)
@@ -0,0 +1,87 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+
+#_____________________  PHP 5.2
+if (! function_exists('json_encode')) {
+  function json_encode($data) {
+    switch (gettype($data)) {
+      case 'boolean':
+        return ($data ? 'true' : 'false');
+      case 'null':
+      case 'NULL':
+        return 'null';
+      case 'integer':
+      case 'double':
+        return $data;
+      case 'string':
+        return '"'. str_replace(array("\\",'"',"/","\n","\r","\t"), array("\\\\",'\"',"\\/","\\n","\\r","\\t"), $data) .'"';
+      case 'object':
+      case 'array':
+        if ($data === array()) return '[]'; # empty array
+        if (range(0, count($data) - 1) !== array_keys($data) ) { # string keys, unordered, non-incremental keys, .. - whatever, make object
+          $out = "\n".'{';
+          foreach($data as $key => $value) {
+            $out .= json_encode((string) $key) . ':' . json_encode($value) . ',';
+          }
+          $out = substr($out, 0, -1) . "\n". '}';
+        }else{
+          # regular array
+          $out = "\n".'[' . join("\n".',', array_map('json_encode', $data)) ."\n".']';
+        }
+        return $out;
+    }
+  }
+}
+
+class PwgJsonEncoder extends PwgResponseEncoder
+{
+  function encodeResponse($response)
+  {
+    $respClass = strtolower( get_class($response) );
+    if ($respClass=='pwgerror')
+    {
+      return json_encode(
+        array(
+          'stat' => 'fail',
+          'err' => $response->code(),
+          'message' => $response->message(),
+          )
+      );
+    }
+    parent::flattenResponse($response);
+    return json_encode(
+        array(
+          'stat' => 'ok',
+          'result' => $response,
+      )
+    );
+  }
+
+  function getContentType()
+  {
+    return 'text/plain';
+  }
+}
+
+?>
Index: /tags/2.0.2/include/ws_protocols/php_encoder.php
===================================================================
--- /tags/2.0.2/include/ws_protocols/php_encoder.php	(revision 3278)
+++ /tags/2.0.2/include/ws_protocols/php_encoder.php	(revision 3278)
@@ -0,0 +1,54 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+class PwgSerialPhpEncoder extends PwgResponseEncoder
+{
+  function encodeResponse($response)
+  {
+    $respClass = strtolower( get_class($response) );
+    if ($respClass=='pwgerror')
+    {
+      return serialize(
+        array(
+          'stat' => 'fail',
+          'err' => $response->code(),
+          'message' => $response->message(),
+          )
+      );
+    }
+    parent::flattenResponse($response);
+    return serialize(
+        array(
+          'stat' => 'ok',
+          'result' => $response
+      )
+    );
+  }
+
+  function getContentType()
+  {
+    return 'text/plain';
+  }
+}
+
+?>
Index: /tags/2.0.2/include/ws_protocols/rest_encoder.php
===================================================================
--- /tags/2.0.2/include/ws_protocols/rest_encoder.php	(revision 3278)
+++ /tags/2.0.2/include/ws_protocols/rest_encoder.php	(revision 3278)
@@ -0,0 +1,281 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+
+class PwgXmlWriter
+{
+  var $_indent;
+  var $_indentStr;
+
+  var $_elementStack;
+  var $_lastTagOpen;
+  var $_indentLevel;
+
+  var $_encodedXml;
+
+  function PwgXmlWriter()
+  {
+    $this->_elementStack = array();
+    $this->_lastTagOpen = false;
+    $this->_indentLevel = 0;
+
+    $this->_encodedXml = '';
+    $this->_indent = true;
+    $this->_indentStr = "\t";
+  }
+
+  function &getOutput()
+  {
+    return $this->_encodedXml;
+  }
+
+
+  function start_element($name)
+  {
+    $this->_end_prev(false);
+    if (!empty($this->_elementStack))
+    {
+      $this->_eol_indent();
+    }
+    $this->_indentLevel++;
+    $this->_indent();
+    $this->_output( '<'.$name );
+    $this->_lastTagOpen = true;
+    array_push( $this->_elementStack, $name);
+  }
+
+  function end_element($x)
+  {
+    $close_tag = $this->_end_prev(true);
+    $name = array_pop( $this->_elementStack );
+    if ($close_tag)
+    {
+      $this->_indentLevel--;
+      $this->_indent();
+//      $this->_eol_indent();
+      $this->_output('</'.$name.">");
+    }
+  }
+
+  function write_content($value)
+  {
+    $this->_end_prev(false);
+    $value = (string)$value;
+    $this->_output( htmlspecialchars( $value ) );
+  }
+
+  function write_cdata($value)
+  {
+    $this->_end_prev(false);
+    $value = (string)$value;
+    $this->_output(
+      '<![CDATA['
+      . str_replace(']]>', ']]&gt;', $value)
+      . ']]>' );
+  }
+
+  function write_attribute($name, $value)
+  {
+    $this->_output(' '.$name.'="'.$this->encode_attribute($value).'"');
+  }
+
+  function encode_attribute($value)
+  {
+    return htmlspecialchars( (string)$value);
+  }
+
+  function _end_prev($done)
+  {
+    $ret = true;
+    if ($this->_lastTagOpen)
+    {
+      if ($done)
+      {
+        $this->_indentLevel--;
+        $this->_output( ' />' );
+        //$this->_eol_indent();
+        $ret = false;
+      }
+      else
+      {
+        $this->_output( '>' );
+      }
+      $this->_lastTagOpen = false;
+    }
+    return $ret;
+  }
+
+  function _eol_indent()
+  {
+    if ($this->_indent)
+      $this->_output("\n");
+  }
+
+  function _indent()
+  {
+    if ($this->_indent and
+        $this->_indentLevel > count($this->_elementStack) )
+    {
+      $this->_output(
+        str_repeat( $this->_indentStr, count($this->_elementStack) )
+       );
+    }
+  }
+
+  function _output($raw_content)
+  {
+    $this->_encodedXml .= $raw_content;
+  }
+}
+
+class PwgRestEncoder extends PwgResponseEncoder
+{
+  function encodeResponse($response)
+  {
+    $respClass = strtolower( get_class($response) );
+    if ($respClass=='pwgerror')
+    {
+      $ret = '<?xml version="1.0"?>
+<rsp stat="fail">
+	<err code="'.$response->code().'" msg="'.htmlspecialchars($response->message()).'" />
+</rsp>';
+      return $ret;
+    }
+
+    $this->_writer = new PwgXmlWriter();
+    $this->encode($response);
+    $ret = $this->_writer->getOutput();
+    $ret = '<?xml version="1.0" encoding="'.get_pwg_charset().'" ?>
+<rsp stat="ok">
+'.$ret.'
+</rsp>';
+
+    return $ret;
+  }
+
+  function getContentType()
+  {
+    return 'text/xml';
+  }
+
+  function encode_array($data, $itemName, $xml_attributes=array())
+  {
+    foreach ($data as $item)
+    {
+      $this->_writer->start_element( $itemName );
+      $this->encode($item, $xml_attributes);
+      $this->_writer->end_element( $itemName );
+    }
+  }
+
+  function encode_struct($data, $skip_underscore, $xml_attributes=array())
+  {
+    foreach ($data as $name => $value)
+    {
+      if (is_numeric($name))
+        continue;
+      if ($skip_underscore and $name[0]=='_')
+        continue;
+      if ( is_null($value) )
+        continue; // null means we dont put it
+      if ( $name==WS_XML_ATTRIBUTES)
+      {
+        foreach ($value as $attr_name => $attr_value)
+        {
+          $this->_writer->write_attribute($attr_name, $attr_value);
+        }
+        unset($data[$name]);
+      }
+      else if ( isset($xml_attributes[$name]) )
+      {
+        $this->_writer->write_attribute($name, $value);
+        unset($data[$name]);
+      }
+    }
+
+    foreach ($data as $name => $value)
+    {
+      if (is_numeric($name))
+        continue;
+      if ($skip_underscore and $name[0]=='_')
+        continue;
+      if ( is_null($value) )
+        continue; // null means we dont put it
+      if ($name!=WS_XML_CONTENT)
+        $this->_writer->start_element($name);
+      $this->encode($value);
+      if ($name!=WS_XML_CONTENT)
+        $this->_writer->end_element($name);
+    }
+  }
+
+  function encode($data, $xml_attributes=array() )
+  {
+    switch (gettype($data))
+    {
+      case 'null':
+      case 'NULL':
+        $this->_writer->write_content('');
+        break;
+      case 'boolean':
+        $this->_writer->write_content($data ? '1' : '0');
+        break;
+      case 'integer':
+      case 'double':
+        $this->_writer->write_content($data);
+        break;
+      case 'string':
+        $this->_writer->write_content($data);
+        break;
+      case 'array':
+        $is_array = range(0, count($data) - 1) === array_keys($data);
+        if ($is_array)
+        {
+          $this->encode_array($data, 'item' );
+        }
+        else
+        {
+          $this->encode_struct($data, false, $xml_attributes);
+        }
+        break;
+      case 'object':
+        switch ( strtolower(get_class($data)) )
+        {
+          case 'pwgnamedarray':
+            $this->encode_array($data->_content, $data->_itemName, $data->_xmlAttributes);
+            break;
+          case 'pwgnamedstruct':
+            $this->encode_array( array($data->_content), $data->_name, $data->_xmlAttributes);
+            break;
+          default:
+            $this->encode_struct(get_object_vars($data), true);
+            break;
+        }
+        break;
+      default:
+        trigger_error("Invalid type ". gettype($data)." ".get_class($data), E_USER_WARNING );
+    }
+  }
+}
+
+?>
Index: /tags/2.0.2/include/ws_protocols/rest_handler.php
===================================================================
--- /tags/2.0.2/include/ws_protocols/rest_handler.php	(revision 3278)
+++ /tags/2.0.2/include/ws_protocols/rest_handler.php	(revision 3278)
@@ -0,0 +1,57 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+class PwgRestRequestHandler
+{
+  function handleRequest(&$service)
+  {
+    $params = array();
+
+    $param_array = $service->isPost() ? $_POST : $_GET;
+    foreach ($param_array as $name => $value)
+    {
+      if ($name=='format')
+        continue; // ignore - special keys
+      if ($name=='method')
+      {
+        $method = $value;
+      }
+      else
+      {
+        $params[$name]=$value;
+      }
+    }
+
+    if ( empty($method) )
+    {
+      $service->sendResponse(
+          new PwgError(WS_ERR_INVALID_METHOD, 'Missing "method" name')
+        );
+      return;
+    }
+    $resp = $service->invoke($method, $params);
+    $service->sendResponse($resp);
+  }
+}
+
+?>
Index: /tags/2.0.2/include/ws_protocols/xmlrpc_encoder.php
===================================================================
--- /tags/2.0.2/include/ws_protocols/xmlrpc_encoder.php	(revision 3278)
+++ /tags/2.0.2/include/ws_protocols/xmlrpc_encoder.php	(revision 3278)
@@ -0,0 +1,115 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+function xmlrpc_encode($data)
+{
+  switch (gettype($data))
+  {
+    case 'boolean':
+      return '<boolean>'.($data ? '1' : '0').'</boolean>';
+    case 'integer':
+      return '<int>'.$data.'</int>';
+    case 'double':
+      return '<double>'.$data.'</double>';
+    case 'string':
+      return '<string>'.htmlspecialchars($data).'</string>';
+    case 'object':
+    case 'array':
+      $is_array = range(0, count($data) - 1) === array_keys($data);
+      if ($is_array)
+      {
+        $return = '<array><data>'."\n";
+        foreach ($data as $item)
+        {
+          $return .= '  <value>'.xmlrpc_encode($item)."</value>\n";
+        }
+        $return .= '</data></array>';
+      }
+      else
+      {
+        $return = '<struct>'."\n";
+        foreach ($data as $name => $value)
+        {
+					$name = htmlspecialchars($name);
+          $return .= "  <member><name>$name</name><value>";
+          $return .= xmlrpc_encode($value)."</value></member>\n";
+        }
+        $return .= '</struct>';
+      }
+      return $return;
+  }
+}
+
+class PwgXmlRpcEncoder extends PwgResponseEncoder
+{
+  function encodeResponse($response)
+  {
+    $respClass = strtolower( get_class($response) );
+    if ($respClass=='pwgerror')
+    {
+      $code = $response->code();
+      $msg = htmlspecialchars($response->message());
+      $ret = <<<EOD
+<methodResponse>
+  <fault>
+    <value>
+      <struct>
+        <member>
+          <name>faultCode</name>
+          <value><int>{$code}</int></value>
+        </member>
+        <member>
+          <name>faultString</name>
+          <value><string>{$msg}</string></value>
+        </member>
+      </struct>
+    </value>
+  </fault>
+</methodResponse>
+EOD;
+      return $ret;
+    }
+
+    parent::flattenResponse($response);
+    $ret = xmlrpc_encode($response);
+    $ret = <<<EOD
+<methodResponse>
+  <params>
+    <param>
+      <value>
+        $ret
+      </value>
+    </param>
+  </params>
+</methodResponse>
+EOD;
+    return $ret;
+  }
+
+  function getContentType()
+  {
+    return 'text/xml';
+  }
+}
+
+?>
Index: /tags/2.0.2/index.php
===================================================================
--- /tags/2.0.2/index.php	(revision 3278)
+++ /tags/2.0.2/index.php	(revision 3278)
@@ -0,0 +1,296 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+//--------------------------------------------------------------------- include
+define('PHPWG_ROOT_PATH','./');
+include_once( PHPWG_ROOT_PATH.'include/common.inc.php' );
+include(PHPWG_ROOT_PATH.'include/section_init.inc.php');
+
+trigger_action('loc_begin_index');
+
+// +-----------------------------------------------------------------------+
+// | Check Access and exit when user status is not ok                      |
+// +-----------------------------------------------------------------------+
+check_status(ACCESS_GUEST);
+
+//---------------------------------------------- change of image display order
+if (isset($_GET['image_order']))
+{
+  if ( (int)$_GET['image_order'] > 0)
+  {
+    pwg_set_session_var('image_order', (int)$_GET['image_order']);
+  }
+  else
+  {
+    pwg_unset_session_var('image_order');
+  }
+  redirect(
+    duplicate_index_url(
+      array(),        // nothing to redefine
+      array('start')  // changing display order goes back to section first page
+      )
+    );
+}
+//-------------------------------------------------------------- initialization
+// detection of the start picture to display
+if (!isset($page['start']))
+{
+  $page['start'] = 0;
+}
+
+// access authorization check
+if (isset($page['category']))
+{
+  check_restrictions($page['category']['id']);
+}
+
+if (count($page['items']) > $user['nb_image_page'])
+{
+  $page['navigation_bar'] = create_navigation_bar(
+    duplicate_index_url(array(), array('start')),
+    count($page['items']),
+    $page['start'],
+    $page['nb_image_page'],
+    true
+    );
+}
+else
+{
+  $page['navigation_bar'] = '';
+}
+
+// caddie filling :-)
+if (isset($_GET['caddie']))
+{
+  fill_caddie($page['items']);
+  redirect(duplicate_index_url());
+}
+
+//----------------------------------------------------- template initialization
+//
+// Start output of page
+//
+$title = $page['title'];
+$page['body_id'] = 'theCategoryPage';
+
+$template->set_filenames( array('index'=>'index.tpl') );
+//-------------------------------------------------------------- category title
+$template_title = $page['title'];
+if (count($page['items']) > 0)
+{
+  $template_title.= ' ['.count($page['items']).']';
+}
+$template->assign('TITLE', $template_title);
+
+if (isset($page['flat']) or isset($page['chronology_field']))
+{
+  $template->assign(
+    'U_MODE_NORMAL',
+    duplicate_index_url( array(), array('chronology_field', 'start', 'flat') )
+    );
+}
+
+if (!isset($page['flat']) and 'categories' == $page['section'])
+{
+  $template->assign(
+    'U_MODE_FLAT',
+    duplicate_index_url(array('flat' => ''), array('start', 'chronology_field'))
+    );
+}
+
+if (!isset($page['chronology_field']))
+{
+  $chronology_params =
+      array(
+          'chronology_field' => 'created',
+          'chronology_style' => 'monthly',
+          'chronology_view' => 'list',
+      );
+  $template->assign(
+    'U_MODE_CREATED',
+    duplicate_index_url( $chronology_params, array('start', 'flat') )
+    );
+
+  $chronology_params['chronology_field'] = 'posted';
+  $template->assign(
+    'U_MODE_POSTED',
+    duplicate_index_url( $chronology_params, array('start', 'flat') )
+    );
+}
+else
+{
+  if ($page['chronology_field'] == 'created')
+  {
+    $chronology_field = 'posted';
+  }
+  else
+  {
+    $chronology_field = 'created';
+  }
+  $url = duplicate_index_url(
+            array('chronology_field'=>$chronology_field ),
+            array('chronology_date', 'start', 'flat')
+          );
+  $template->assign(
+      'U_MODE_'.strtoupper($chronology_field),
+      $url
+    );
+}
+
+if ('search' == $page['section'])
+{
+  $template->assign(
+    'U_SEARCH_RULES',
+    get_root_url().'search_rules.php?search_id='.$page['search']
+    );
+}
+
+if (isset($page['category']) and is_admin())
+{
+  $template->assign(
+    'U_EDIT',
+     get_root_url().'admin.php?page=cat_modify'
+        .'&amp;cat_id='.$page['category']['id']
+    );
+}
+
+if (is_admin() and !empty($page['items']))
+{
+  $template->assign(
+    'U_CADDIE',
+     add_url_params(duplicate_index_url(), array('caddie'=>1) )
+    );
+}
+
+if ( $page['section']=='search' and $page['start']==0 and
+    !isset($page['chronology_field']) and isset($page['qsearch_details']) )
+{
+  $template->assign('QUERY_SEARCH',
+    htmlspecialchars($page['qsearch_details']['q']) );
+
+  $cats = array_merge(
+      (array)@$page['qsearch_details']['matching_cats_no_images'],
+      (array)@$page['qsearch_details']['matching_cats'] );
+  if (count($cats))
+  {
+    usort($cats, 'name_compare');
+    $hints = array();
+    foreach ( $cats as $cat )
+    {
+      $hints[] = get_cat_display_name( array($cat), '', false );
+    }
+    $template->assign( 'category_search_results', $hints);
+  }
+
+  $tags = (array)@$page['qsearch_details']['matching_tags'];
+  if (count($tags))
+  {
+    usort($tags, 'name_compare');
+    $hints = array();
+    foreach ( $tags as $tag )
+    {
+      $hints[] =
+        '<a href="' . make_index_url(array('tags'=>array($tag))) . '">'
+        .$tag['name']
+        .'</a>';
+    }
+    $template->assign( 'tag_search_results', $hints);
+  }
+}
+
+// navigation bar
+$template->assign( 'NAV_BAR', $page['navigation_bar'] );
+
+if ( count($page['items']) > 0
+    and $page['section'] != 'most_visited'
+    and $page['section'] != 'best_rated')
+{
+  // image order
+  $order_idx = pwg_get_session_var( 'image_order', 0 );
+
+  $url = add_url_params(
+          duplicate_index_url(),
+          array('image_order' => '')
+        );
+  foreach (get_category_preferred_image_orders() as $order_id => $order)
+  {
+    if ($order[2])
+    {
+      $template->append(
+        'image_orders',
+        array(
+          'DISPLAY' => $order[0],
+          'URL' => $url.$order_id,
+          'SELECTED' => ($order_idx == $order_id ? true:false),
+          )
+        );
+    }
+  }
+}
+
+// category comment
+if (isset($page['comment']) and $page['comment'] != '')
+{
+  $template->assign('CONTENT_DESCRIPTION', $page['comment'] );
+}
+
+// include menubar
+include( PHPWG_ROOT_PATH.'include/menubar.inc.php');
+
+//------------------------------------------------------ main part : thumbnails
+if ( 0==$page['start']
+    and !isset($page['flat'])
+    and !isset($page['chronology_field'])
+    and ('recent_cats'==$page['section'] or 'categories'==$page['section'])
+    and (!isset($page['category']['count_categories']) or $page['category']['count_categories']>0 )
+  )
+{
+  include(PHPWG_ROOT_PATH.'include/category_cats.inc.php');
+}
+if ( !empty($page['items']) )
+{
+  include(PHPWG_ROOT_PATH.'include/category_default.inc.php');
+}
+//------------------------------------------------------- category informations
+
+// slideshow
+// execute after init thumbs in order to have all picture informations
+if (!empty($page['cat_slideshow_url']))
+{
+  if (isset($_GET['slideshow']))
+  {
+    redirect($page['cat_slideshow_url']);
+  }
+  else
+  {
+    $template->assign('U_SLIDESHOW', $page['cat_slideshow_url']);
+  }
+}
+
+include(PHPWG_ROOT_PATH.'include/page_header.php');
+trigger_action('loc_end_index');
+$template->pparse('index');
+//------------------------------------------------------------ log informations
+pwg_log();
+include(PHPWG_ROOT_PATH.'include/page_tail.php');
+?>
Index: /tags/2.0.2/install.php
===================================================================
--- /tags/2.0.2/install.php	(revision 3278)
+++ /tags/2.0.2/install.php	(revision 3278)
@@ -0,0 +1,437 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+//----------------------------------------------------------- include
+define('PHPWG_ROOT_PATH','./');
+
+/**
+ * loads an sql file and executes all queries
+ *
+ * Before executing a query, $replaced is... replaced by $replacing. This is
+ * useful when the SQL file contains generic words. Drop table queries are
+ * not executed.
+ *
+ * @param string filepath
+ * @param string replaced
+ * @param string replacing
+ * @return void
+ */
+function execute_sqlfile($filepath, $replaced, $replacing)
+{
+  $sql_lines = file($filepath);
+  $query = '';
+  foreach ($sql_lines as $sql_line)
+  {
+    $sql_line = trim($sql_line);
+    if (preg_match('/(^--|^$)/', $sql_line))
+    {
+      continue;
+    }
+    $query.= ' '.$sql_line;
+    // if we reached the end of query, we execute it and reinitialize the
+    // variable "query"
+    if (preg_match('/;$/', $sql_line))
+    {
+      $query = trim($query);
+      $query = str_replace($replaced, $replacing, $query);
+      // we don't execute "DROP TABLE" queries
+      if (!preg_match('/^DROP TABLE/i', $query))
+      {
+        global $install_charset_collate;
+        if ( !empty($install_charset_collate) )
+        {
+          if ( preg_match('/^(CREATE TABLE .*)[\s]*;[\s]*/im', $query, $matches) )
+          {
+            $query = $matches[1].' '.$install_charset_collate.';';
+          }
+        }
+        pwg_query($query);
+      }
+      $query = '';
+    }
+  }
+}
+
+set_magic_quotes_runtime(0); // Disable magic_quotes_runtime
+//
+// addslashes to vars if magic_quotes_gpc is off this is a security
+// precaution to prevent someone trying to break out of a SQL statement.
+//
+if( !get_magic_quotes_gpc() )
+{
+  if( is_array($_POST) )
+  {
+    while( list($k, $v) = each($_POST) )
+    {
+      if( is_array($_POST[$k]) )
+      {
+        while( list($k2, $v2) = each($_POST[$k]) )
+        {
+          $_POST[$k][$k2] = addslashes($v2);
+        }
+        @reset($_POST[$k]);
+      }
+      else
+      {
+        $_POST[$k] = addslashes($v);
+      }
+    }
+    @reset($_POST);
+  }
+
+  if( is_array($_GET) )
+  {
+    while( list($k, $v) = each($_GET) )
+    {
+      if( is_array($_GET[$k]) )
+      {
+        while( list($k2, $v2) = each($_GET[$k]) )
+        {
+          $_GET[$k][$k2] = addslashes($v2);
+        }
+        @reset($_GET[$k]);
+      }
+      else
+      {
+        $_GET[$k] = addslashes($v);
+      }
+    }
+    @reset($_GET);
+  }
+
+  if( is_array($_COOKIE) )
+  {
+    while( list($k, $v) = each($_COOKIE) )
+    {
+      if( is_array($_COOKIE[$k]) )
+      {
+        while( list($k2, $v2) = each($_COOKIE[$k]) )
+        {
+          $_COOKIE[$k][$k2] = addslashes($v2);
+        }
+        @reset($_COOKIE[$k]);
+      }
+      else
+      {
+        $_COOKIE[$k] = addslashes($v);
+      }
+    }
+    @reset($_COOKIE);
+  }
+}
+
+//----------------------------------------------------- variable initialization
+
+define('DEFAULT_PREFIX_TABLE', 'piwigo_');
+
+// Obtain various vars
+$dbhost = (!empty($_POST['dbhost'])) ? $_POST['dbhost'] : 'localhost';
+$dbuser = (!empty($_POST['dbuser'])) ? $_POST['dbuser'] : '';
+$dbpasswd = (!empty($_POST['dbpasswd'])) ? $_POST['dbpasswd'] : '';
+$dbname = (!empty($_POST['dbname'])) ? $_POST['dbname'] : '';
+
+if (isset($_POST['install']))
+{
+  $table_prefix = $_POST['prefix'];
+}
+else
+{
+  $table_prefix = DEFAULT_PREFIX_TABLE;
+}
+
+$admin_name = (!empty($_POST['admin_name'])) ? $_POST['admin_name'] : '';
+$admin_pass1 = (!empty($_POST['admin_pass1'])) ? $_POST['admin_pass1'] : '';
+$admin_pass2 = (!empty($_POST['admin_pass2'])) ? $_POST['admin_pass2'] : '';
+$admin_mail = (!empty($_POST['admin_mail'])) ? $_POST['admin_mail'] : '';
+
+$infos = array();
+$errors = array();
+
+// Open config.php ... if it exists
+$config_file = PHPWG_ROOT_PATH.'include/mysql.inc.php';
+if (@file_exists($config_file))
+{
+  include($config_file);
+  // Is Piwigo already installed ?
+  if (defined("PHPWG_INSTALLED"))
+  {
+    die('Piwigo is already installed');
+  }
+}
+
+$prefixeTable = $table_prefix;
+include(PHPWG_ROOT_PATH . 'include/config_default.inc.php');
+@include(PHPWG_ROOT_PATH. 'include/config_local.inc.php');
+include(PHPWG_ROOT_PATH . 'include/constants.php');
+include(PHPWG_ROOT_PATH . 'include/functions.inc.php');
+include(PHPWG_ROOT_PATH . 'admin/include/functions.php');
+include(PHPWG_ROOT_PATH . 'admin/include/functions_upgrade.php');
+
+if (isset($_GET['language']))
+{
+  $language = strip_tags($_GET['language']);
+}
+else
+{
+  $language = 'en_UK';
+  // Try to get browser language
+  foreach (get_languages('utf-8') as $language_code => $language_name)
+  {
+    if (substr($language_code,0,2) == @substr($_SERVER["HTTP_ACCEPT_LANGUAGE"],0,2))
+    {
+      $language = $language_code;
+      break;
+    }
+  }
+}
+
+if ('fr_FR' == $language) {
+  define('PHPWG_DOMAIN', 'fr.piwigo.org');
+}
+else if ('it_IT' == $language) {
+  define('PHPWG_DOMAIN', 'it.piwigo.org');
+}
+else {
+  define('PHPWG_DOMAIN', 'piwigo.org');
+}
+define('PHPWG_URL', 'http://'.PHPWG_DOMAIN);
+
+load_language( 'common.lang', '', array('language'=>$language, 'target_charset'=>'utf-8') );
+load_language( 'admin.lang', '', array('language'=>$language, 'target_charset'=>'utf-8') );
+load_language( 'install.lang', '', array('language'=>$language, 'target_charset'=>'utf-8') );
+
+//------------------------------------------------- check php version
+if (version_compare(PHP_VERSION, REQUIRED_PHP_VERSION, '<'))
+{
+  include(PHPWG_ROOT_PATH.'install/php5_apache_configuration.php');
+}
+
+//----------------------------------------------------- template initialization
+include( PHPWG_ROOT_PATH .'include/template.class.php');
+$template=new Template(PHPWG_ROOT_PATH.'admin/template/goto', 'roma');
+$template->set_filenames( array('install'=>'install.tpl') );
+$step = 1;
+//---------------------------------------------------------------- form analyze
+if ( isset( $_POST['install'] ))
+{
+  if ( @mysql_connect( $_POST['dbhost'],
+                       $_POST['dbuser'],
+                       $_POST['dbpasswd'] ) )
+  {
+    if ( @mysql_select_db($_POST['dbname'] ) )
+    {
+      array_push( $infos, l10n('step1_confirmation') );
+    }
+    else
+    {
+      array_push( $errors, l10n('step1_err_db') );
+    }
+    if ( version_compare(mysql_get_server_info(), '4.1.0', '>=') )
+    {
+      $pwg_charset='utf-8';
+      $pwg_db_charset='utf8';
+      $install_charset_collate = "DEFAULT CHARACTER SET $pwg_db_charset";
+    }
+    else
+    {
+      $pwg_charset='iso-8859-1';
+      $pwg_db_charset='latin1';
+      $install_charset_collate = '';
+      if ( !array_key_exists($language, get_languages($pwg_charset) ) )
+      {
+        $language='en_UK';
+      }
+    }
+  }
+  else
+  {
+    array_push( $errors, l10n('step1_err_server') );
+  }
+
+  $webmaster = trim(preg_replace( '/\s{2,}/', ' ', $admin_name ));
+  if ( empty($webmaster))
+    array_push( $errors, l10n('step2_err_login1') );
+  else if ( preg_match( '/[\'"]/', $webmaster ) )
+    array_push( $errors, l10n('step2_err_login3') );
+  if ( $admin_pass1 != $admin_pass2 || empty($admin_pass1) )
+    array_push( $errors, l10n('step2_err_pass') );
+  if ( empty($admin_mail))
+    array_push( $errors, l10n('reg_err_mail_address') );
+  else
+  {
+    $error_mail_address = validate_mail_address(null, $admin_mail);
+    if (!empty($error_mail_address))
+      array_push( $errors, $error_mail_address );
+  }
+
+  if ( count( $errors ) == 0 )
+  {
+    $step = 2;
+    $file_content = '<?php
+$cfgBase = \''.$dbname.'\';
+$cfgUser = \''.$dbuser.'\';
+$cfgPassword = \''.$dbpasswd.'\';
+$cfgHote = \''.$dbhost.'\';
+
+$prefixeTable = \''.$table_prefix.'\';
+
+define(\'PHPWG_INSTALLED\', true);
+define(\'PWG_CHARSET\', \''.$pwg_charset.'\');
+define(\'DB_CHARSET\', \''.$pwg_db_charset.'\');
+define(\'DB_COLLATE\', \'\');
+
+?'.'>';
+
+    @umask(0111);
+    // writing the configuration file
+    if ( !($fp = @fopen( $config_file, 'w' )))
+    {
+      $html_content = htmlentities( $file_content, ENT_QUOTES );
+      $html_content = nl2br( $html_content );
+      $error_copy = l10n('step1_err_copy');
+      $error_copy .= '<br />--------------------------------------------------------------------<br />';
+      $error_copy .= '<span class="sql_content">' . $html_content . '</span>';
+      $error_copy .= '<br />--------------------------------------------------------------------<br />';
+    }
+    @fputs($fp, $file_content, strlen($file_content));
+    @fclose($fp);
+
+    // Create empty local files to avoid log errors
+    create_empty_local_files();
+
+    // tables creation, based on piwigo_structure.sql
+    execute_sqlfile(
+      PHPWG_ROOT_PATH.'install/piwigo_structure.sql',
+      DEFAULT_PREFIX_TABLE,
+      $table_prefix
+      );
+    // We fill the tables with basic informations
+    execute_sqlfile(
+      PHPWG_ROOT_PATH.'install/config.sql',
+      DEFAULT_PREFIX_TABLE,
+      $table_prefix
+      );
+
+    // fill $conf global array
+    load_conf_from_db();
+
+    $insert = array(
+      'id' => 1,
+      'galleries_url' => PHPWG_ROOT_PATH.'galleries/',
+      );
+    mass_inserts(SITES_TABLE, array_keys($insert), array($insert));
+
+    // webmaster admin user
+    $inserts = array(
+      array(
+        'id'           => 1,
+        'username'     => $admin_name,
+        'password'     => md5($admin_pass1),
+        'mail_address' => $admin_mail,
+        ),
+      array(
+        'id'           => 2,
+        'username'     => 'guest',
+        ),
+      );
+    mass_inserts(USERS_TABLE, array_keys($inserts[0]), $inserts);
+
+    create_user_infos(array(1,2), array('language' => $language));
+
+    // Available upgrades must be ignored after a fresh installation. To
+    // make PWG avoid upgrading, we must tell it upgrades have already been
+    // made.
+    list($dbnow) = mysql_fetch_row(pwg_query('SELECT NOW();'));
+    define('CURRENT_DATE', $dbnow);
+    $datas = array();
+    foreach (get_available_upgrade_ids() as $upgrade_id)
+    {
+      array_push(
+        $datas,
+        array(
+          'id'          => $upgrade_id,
+          'applied'     => CURRENT_DATE,
+          'description' => 'upgrade included in installation',
+          )
+        );
+    }
+    mass_inserts(
+      UPGRADE_TABLE,
+      array_keys($datas[0]),
+      $datas
+      );
+  }
+}
+
+//------------------------------------------------------ start template output
+foreach (get_languages('utf-8') as $language_code => $language_name)
+{
+  if ($language == $language_code)
+  {
+    $template->assign('language_selection', $language_code);
+  }
+  $languages_options[$language_code] = $language_name;
+}
+$template->assign('language_options', $languages_options);
+
+$template->assign(
+  array(
+    'T_CONTENT_ENCODING' => 'utf-8',
+    'RELEASE'=>PHPWG_VERSION,
+    'F_ACTION' => 'install.php?language=' . $language,
+    'F_DB_HOST'=>$dbhost,
+    'F_DB_USER'=>$dbuser,
+    'F_DB_NAME'=>$dbname,
+    'F_DB_PREFIX' => $table_prefix,
+    'F_ADMIN'=>$admin_name,
+    'F_ADMIN_EMAIL'=>$admin_mail,
+    'L_INSTALL_HELP'=>sprintf(l10n('install_help'), PHPWG_URL.'/forum'),
+    ));
+
+//------------------------------------------------------ errors & infos display
+if ($step == 1)
+{
+  $template->assign('install', true);
+}
+else
+{
+  array_push($infos, l10n('install_end_message'));
+
+  if (isset($error_copy))
+  {
+    array_push($errors, $error_copy);
+  }
+}
+if (count($errors) != 0)
+{
+  $template->assign('errors', $errors);
+}
+
+if (count($infos) != 0 )
+{
+  $template->assign('infos', $infos);
+}
+
+//----------------------------------------------------------- html code display
+$template->pparse('install');
+?>
Index: /tags/2.0.2/install/config.sql
===================================================================
--- /tags/2.0.2/install/config.sql	(revision 3278)
+++ /tags/2.0.2/install/config.sql	(revision 3278)
@@ -0,0 +1,31 @@
+-- initial configuration for Piwigo
+
+INSERT INTO piwigo_config (param,value,comment) VALUES ('nb_comment_page','10','number of comments to display on each page');
+INSERT INTO piwigo_config (param,value,comment) VALUES ('log','false','keep an history of visits on your website');
+INSERT INTO piwigo_config (param,value,comment) VALUES ('comments_validation','false','administrators validate users comments before becoming visible');
+INSERT INTO piwigo_config (param,value,comment) VALUES ('comments_forall','false','even guest not registered can post comments');
+INSERT INTO piwigo_config (param,value,comment) VALUES ('gallery_locked','false','Lock your gallery temporary for non admin users');
+INSERT INTO piwigo_config (param,value,comment) VALUES ('gallery_title','Piwigo demonstration site','Title at top of each page and for RSS feed');
+INSERT INTO piwigo_config (param,value,comment) VALUES ('gallery_url','http://piwigo.org/demo','URL given in RSS feed');
+INSERT INTO piwigo_config (param,value,comment) VALUES ('rate','true','Rating pictures feature is enabled');
+INSERT INTO piwigo_config (param,value,comment) VALUES ('rate_anonymous','true','Rating pictures feature is also enabled for visitors');
+INSERT INTO piwigo_config (param,value,comment) VALUES ('page_banner','<h1>Piwigo demonstration site</h1><p>My photos web site</p>','html displayed on the top each page of your gallery');
+INSERT INTO piwigo_config (param,value,comment) VALUES ('history_admin','false','keep a history of administrator visits on your website');
+INSERT INTO piwigo_config (param,value,comment) VALUES ('history_guest','true','keep a history of guest visits on your website');
+INSERT INTO piwigo_config (param,value,comment) VALUES ('allow_user_registration','true','allow visitors to register?');
+INSERT INTO piwigo_config (param,value,comment) VALUES ('secret_key', MD5(RAND()), 'a secret key specific to the gallery for internal use');
+INSERT INTO piwigo_config (param,value,comment) VALUES ('nbm_send_html_mail','true','Send mail on HTML format for notification by mail');
+INSERT INTO piwigo_config (param,value,comment) VALUES ('nbm_send_mail_as','','Send mail as param value for notification by mail');
+INSERT INTO piwigo_config (param,value,comment) VALUES ('nbm_send_detailed_content','true','Send detailed content for notification by mail');
+INSERT INTO piwigo_config (param,value,comment) VALUES ('nbm_complementary_mail_content','','Complementary mail content for notification by mail');
+INSERT INTO piwigo_config (param,value,comment) VALUES ('nbm_send_recent_post_dates','true','Send recent post by dates for notification by mail');
+INSERT INTO piwigo_config (param,value,comment) VALUES ('email_admin_on_new_user','false','Send an email to theadministrators when a user registers');
+INSERT INTO piwigo_config (param,value,comment) VALUES ('email_admin_on_comment','false','Send an email to the administrators when a valid comment is entered');
+INSERT INTO piwigo_config (param,value,comment) VALUES ('email_admin_on_comment_validation','false','Send an email to the administrators when a comment requires validation');
+INSERT INTO piwigo_config (param,value,comment) VALUES ('email_admin_on_picture_uploaded','false','Send an email to the administrators when a picture is uploaded');
+INSERT INTO piwigo_config (param,value,comment) VALUES ('obligatory_user_mail_address','false','Mail address is obligatory for users');
+INSERT INTO piwigo_config (param,value,comment) VALUES ('c13y_ignore',null,'List of ignored anomalies');
+INSERT INTO piwigo_config (param,value,comment) VALUES ('upload_link_everytime','false','Show upload link every time');
+INSERT INTO piwigo_config (param,value,comment) VALUES ('upload_user_access',2 /*ACCESS_CLASSIC*/,'User access level to upload');
+INSERT INTO piwigo_config (param,value,comment) VALUES ('extents_for_templates','a:0:{}','Actived template-extension(s)');
+INSERT INTO piwigo_config (param,value,comment) VALUES ('blk_menubar','','Menubar options');
Index: /tags/2.0.2/install/db/1-database.php
===================================================================
--- /tags/2.0.2/install/db/1-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/1-database.php	(revision 3278)
@@ -0,0 +1,42 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'Just a beginning test';
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+
+list($now) = mysql_fetch_row(pwg_query('SELECT NOW()'));
+echo
+$now
+."\n"
+.'This upgrade script is for test purpose only'
+."\n"
+;
+?>
Index: /tags/2.0.2/install/db/10-database.php
===================================================================
--- /tags/2.0.2/install/db/10-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/10-database.php	(revision 3278)
@@ -0,0 +1,52 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'New table #categories_link';
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+
+$query = "
+CREATE TABLE phpwebgallery_categories_link (
+  source smallint(5) unsigned NOT NULL default '0',
+  destination smallint(5) unsigned NOT NULL default '0',
+  PRIMARY KEY  (source,destination)
+) TYPE=MyISAM;";
+pwg_query($query);
+
+// +-----------------------------------------------------------------------+
+// |                           End notification                            |
+// +-----------------------------------------------------------------------+
+
+echo
+"\n"
+.'Table '.PREFIX_TABLE.'categories_link created'
+."\n"
+;
+?>
Index: /tags/2.0.2/install/db/11-database.php
===================================================================
--- /tags/2.0.2/install/db/11-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/11-database.php	(revision 3278)
@@ -0,0 +1,65 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description =
+  'Table #categories_link created once again with correct prefix';
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+
+if (PREFIX_TABLE == 'phpwebgallery_')
+{
+  echo
+    "\n"
+    .'Table '.PREFIX_TABLE.'categories_link was already correctly created'
+    ."\n"
+    ;
+}
+else
+{
+  $query = '
+DROP TABLE phpwebgallery_categories_link;
+;';
+  pwg_query($query);
+
+  $query = "
+CREATE TABLE ".PREFIX_TABLE."categories_link (
+  source smallint(5) unsigned NOT NULL default '0',
+  destination smallint(5) unsigned NOT NULL default '0',
+  PRIMARY KEY  (source,destination)
+) TYPE=MyISAM;";
+  pwg_query($query);
+
+  echo
+    "\n"
+    .'Table '.PREFIX_TABLE.'categories_link created'
+    ."\n"
+    ;
+}
+?>
Index: /tags/2.0.2/install/db/12-database.php
===================================================================
--- /tags/2.0.2/install/db/12-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/12-database.php	(revision 3278)
@@ -0,0 +1,99 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'Field "Status" Table #user_infos changed';
+
+include_once(PHPWG_ROOT_PATH.'include/constants.php');
+include(PHPWG_ROOT_PATH . 'include/config_default.inc.php');
+@include(PHPWG_ROOT_PATH. 'include/config_local.inc.php');
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+
+echo "Alter table ".USER_INFOS_TABLE;
+$query = "
+alter table ".USER_INFOS_TABLE."
+  modify column `status` enum('webmaster', 'admin', 'normal', 'generic', 'guest') NOT NULL default 'guest'
+;";
+pwg_query($query);
+
+echo "Define webmaster";
+$query = '
+update
+  '.USER_INFOS_TABLE.'
+set status = \'webmaster\'
+where
+  user_id = '.$conf['webmaster_id'].' and status = \'admin\'
+;';
+$result = pwg_query($query);
+
+echo "Define normal";
+$query = '
+select
+  user_id
+from
+  '.USER_INFOS_TABLE.'
+where
+  user_id != '.$conf['guest_id'].' and status = \'guest\'
+;';
+$result = pwg_query($query);
+
+$datas = array();
+
+while ($row = mysql_fetch_array($result))
+{
+  array_push(
+    $datas,
+    array(
+      'user_id'    => $row['user_id'],
+      'status' => 'normal'
+      )
+    );
+}
+
+mass_updates(
+  USER_INFOS_TABLE,
+  array(
+    'primary' => array('user_id'),
+    'update'  => array('status')
+    ),
+  $datas
+  );
+
+// +-----------------------------------------------------------------------+
+// |                           End notification                            |
+// +-----------------------------------------------------------------------+
+
+echo
+"\n"
+.'Column '.USER_INFOS_TABLE.'.status changed'
+."\n"
+;
+
+?>
Index: /tags/2.0.2/install/db/13-database.php
===================================================================
--- /tags/2.0.2/install/db/13-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/13-database.php	(revision 3278)
@@ -0,0 +1,69 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = '#config (gallery_description out page_banner in)';
+
+$query = "
+ALTER TABLE ".PREFIX_TABLE."config MODIFY COLUMN `value` TEXT;";
+pwg_query($query);
+
+
+$query = '
+SELECT value
+  FROM '.PREFIX_TABLE.'config
+  WHERE param=\'gallery_title\'
+;';
+list($t) = array_from_query($query, 'value');
+
+$query = '
+SELECT value
+  FROM '.PREFIX_TABLE.'config
+  WHERE param=\'gallery_description\'
+;';
+list($d) = array_from_query($query, 'value');
+
+$page_banner='<div id="theHeader"><h1>'.$t.'</h1><p>'.$d.'</p></div>';
+$page_banner=addslashes($page_banner);
+$query = '
+INSERT INTO '.PREFIX_TABLE.'config (param,value,comment) VALUES (' .
+"'page_banner','$page_banner','html displayed on the top each page of your gallery');";
+pwg_query($query);
+
+$query = '
+DELETE FROM '.PREFIX_TABLE.'config
+  WHERE param=\'gallery_description\'
+;';
+pwg_query($query);
+
+
+echo
+"\n"
+.'Table '.PREFIX_TABLE.'config updated'
+."\n"
+;
+?>
Index: /tags/2.0.2/install/db/14-database.php
===================================================================
--- /tags/2.0.2/install/db/14-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/14-database.php	(revision 3278)
@@ -0,0 +1,59 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'Update database to new pwg_high structure';
+
+include_once(PHPWG_ROOT_PATH.'include/constants.php');
+include(PHPWG_ROOT_PATH . 'include/config_default.inc.php');
+@include(PHPWG_ROOT_PATH. 'include/config_local.inc.php');
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+
+echo "Alter table ".USER_INFOS_TABLE. ' add field enabled_high';
+$query = "
+alter table ".USER_INFOS_TABLE."
+  add column `enabled_high` enum('true','false') NOT NULL default 'true'
+;";
+pwg_query($query);
+
+echo "Update ".USER_INFOS_TABLE.".enabled_high with default value";
+$query = "
+update ".USER_INFOS_TABLE." set enabled_high = '".$conf['newuser_default_enabled_high']."' 
+where enabled_high <> '".$conf['newuser_default_enabled_high']."'
+;";
+pwg_query($query);
+
+echo
+"\n"
+.'"'.$upgrade_description.'"'.' ended'
+."\n"
+;
+
+?>
Index: /tags/2.0.2/install/db/15-database.php
===================================================================
--- /tags/2.0.2/install/db/15-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/15-database.php	(revision 3278)
@@ -0,0 +1,46 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = '#user_cache, add column nb_total_pictures (feature 262)';
+
+$query = "
+ALTER TABLE ".PREFIX_TABLE."user_cache ADD COLUMN `nb_total_images` MEDIUMINT(8) UNSIGNED;";
+pwg_query($query);
+
+$query = "
+UPDATE ".PREFIX_TABLE."user_cache SET need_update='true'";
+pwg_query($query);
+
+
+echo
+"\n"
+.'"'.$upgrade_description.'"'.' ended'
+."\n"
+;
+
+?>
Index: /tags/2.0.2/install/db/16-database.php
===================================================================
--- /tags/2.0.2/install/db/16-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/16-database.php	(revision 3278)
@@ -0,0 +1,50 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'Update database from adviser functionnality';
+
+include_once(PHPWG_ROOT_PATH.'include/constants.php');
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+
+echo "Alter table ".USER_INFOS_TABLE. ' add field adviser';
+$query = "
+alter table ".USER_INFOS_TABLE."
+  add column `adviser` enum('true','false') NOT NULL default 'false' after `status`
+;";
+pwg_query($query);
+
+echo
+"\n"
+.'"'.$upgrade_description.'"'.' ended'
+."\n"
+;
+
+?>
Index: /tags/2.0.2/install/db/17-database.php
===================================================================
--- /tags/2.0.2/install/db/17-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/17-database.php	(revision 3278)
@@ -0,0 +1,60 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'Add notification by mail param';
+
+include_once(PHPWG_ROOT_PATH.'include/constants.php');
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+
+echo "Add param on ".CONFIG_TABLE;
+$query = "
+INSERT INTO ".CONFIG_TABLE." (param,value,comment) VALUES ('nbm_send_mail_as','','Send mail as param value for notification by mail');
+";
+pwg_query($query);
+
+
+$query = "
+INSERT INTO ".CONFIG_TABLE." (param,value,comment) VALUES ('nbm_send_detailed_content','true','Send detailed content for notification by mail');
+";
+pwg_query($query);
+
+$query = "
+INSERT INTO ".CONFIG_TABLE." (param,value,comment) VALUES ('nbm_complementary_mail_content','','Complementary mail content for notification by mail');
+";
+pwg_query($query);
+
+echo
+"\n"
+.'"'.$upgrade_description.'"'.' ended'
+."\n"
+;
+
+?>
Index: /tags/2.0.2/install/db/18-database.php
===================================================================
--- /tags/2.0.2/install/db/18-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/18-database.php	(revision 3278)
@@ -0,0 +1,88 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'Reduce length of #_user_mail_notification.check_key';
+
+include_once(PHPWG_ROOT_PATH.'include/constants.php');
+
+include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+include_once(PHPWG_ROOT_PATH.'admin/include/functions_notification_by_mail.inc.php');
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+echo "Compute new check_key";
+$query = '
+select
+  user_id
+from
+  '.USER_MAIL_NOTIFICATION_TABLE.'
+;';
+$result = pwg_query($query);
+
+$datas = array();
+
+while ($row = mysql_fetch_array($result))
+{
+  array_push(
+    $datas,
+    array(
+      'user_id'    => $row['user_id'],
+      'check_key' => find_available_check_key()
+      )
+    );
+}
+
+mass_updates(
+  USER_MAIL_NOTIFICATION_TABLE,
+  array(
+    'primary' => array('user_id'),
+    'update'  => array('check_key')
+    ),
+  $datas
+  );
+
+echo "Alter table ".USER_MAIL_NOTIFICATION_TABLE;
+$query = "
+alter table ".USER_MAIL_NOTIFICATION_TABLE."
+  modify column `check_key` varchar(16) binary NOT NULL default ''
+;";
+pwg_query($query);
+
+
+// +-----------------------------------------------------------------------+
+// |                           End notification                            |
+// +-----------------------------------------------------------------------+
+
+echo
+"\n"
+.'Column '.USER_MAIL_NOTIFICATION_TABLE.'.check_key changed'
+."\n"
+;
+
+?>
Index: /tags/2.0.2/install/db/19-database.php
===================================================================
--- /tags/2.0.2/install/db/19-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/19-database.php	(revision 3278)
@@ -0,0 +1,149 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = '#images.keywords moved to new table #tags';
+
+// +-----------------------------------------------------------------------+
+// |                              New tables                               |
+// +-----------------------------------------------------------------------+
+
+$query = '
+CREATE TABLE '.PREFIX_TABLE.'tags (
+  id smallint(5) UNSIGNED NOT NULL auto_increment,
+  name varchar(255) BINARY NOT NULL,
+  url_name varchar(255) BINARY NOT NULL,
+  PRIMARY KEY (id)
+) TYPE=MyISAM
+;';
+pwg_query($query);
+
+$query = '
+CREATE TABLE '.PREFIX_TABLE.'image_tag (
+  image_id mediumint(8) UNSIGNED NOT NULL,
+  tag_id smallint(5) UNSIGNED NOT NULL,
+  PRIMARY KEY (image_id,tag_id)
+) TYPE=MyISAM
+;';
+pwg_query($query);
+
+// +-----------------------------------------------------------------------+
+// |                        Move keywords to tags                          |
+// +-----------------------------------------------------------------------+
+
+// each tag label is associated to a numeric identifier
+$tag_id = array();
+// to each tag id (key) a list of image ids (value) is associated
+$tag_images = array();
+
+$current_id = 1;
+
+$query = '
+SELECT id, keywords
+  FROM '.PREFIX_TABLE.'images
+  WHERE keywords IS NOT NULL
+;';
+$result = pwg_query($query);
+while ($row = mysql_fetch_array($result))
+{
+  foreach(preg_split('/[,]+/', $row['keywords']) as $keyword)
+  {
+    if (!isset($tag_id[$keyword]))
+    {
+      $tag_id[$keyword] = $current_id++;
+    }
+
+    if (!isset($tag_images[ $tag_id[$keyword] ]))
+    {
+      $tag_images[ $tag_id[$keyword] ] = array();
+    }
+
+    array_push($tag_images[ $tag_id[$keyword] ], $row['id']);
+  }
+}
+
+$datas = array();
+foreach ($tag_id as $tag_name => $tag_id)
+{
+  array_push(
+    $datas,
+    array(
+      'id'       => $tag_id,
+      'name'     => $tag_name,
+      'url_name' => str2url($tag_name),
+      )
+    );
+}
+if (!empty($datas))
+mass_inserts(
+  PREFIX_TABLE.'tags',
+  array_keys($datas[0]),
+  $datas
+  );
+
+$datas = array();
+foreach ($tag_images as $tag_id => $images)
+{
+  foreach (array_unique($images) as $image_id)
+  {
+    array_push(
+      $datas,
+      array(
+        'tag_id'   => $tag_id,
+        'image_id' => $image_id,
+        )
+      );
+  }
+}
+
+if (!empty($datas))
+mass_inserts(
+  PREFIX_TABLE.'image_tag',
+  array_keys($datas[0]),
+  $datas
+  );
+
+// +-----------------------------------------------------------------------+
+// |                         Delete images.keywords                        |
+// +-----------------------------------------------------------------------+
+
+$query = '
+ALTER TABLE '.PREFIX_TABLE.'images DROP COLUMN keywords
+;';
+pwg_query($query);
+
+// +-----------------------------------------------------------------------+
+// |                           End notification                            |
+// +-----------------------------------------------------------------------+
+
+echo
+"\n"
+.'Table '.PREFIX_TABLE.'tags created and filled'."\n"
+.'Table '.PREFIX_TABLE.'image_tag created and filled'."\n"
+.'Column '.PREFIX_TABLE.'images.keywords dropped'."\n"
+;
+?>
Index: /tags/2.0.2/install/db/2-database.php
===================================================================
--- /tags/2.0.2/install/db/2-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/2-database.php	(revision 3278)
@@ -0,0 +1,74 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'Update template preference for every user';
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+
+// configuration update
+$query = '
+UPDATE '.PREFIX_TABLE.'config
+  SET value = \'yoga/clear\'
+  WHERE param = \'default_template\'
+;';
+pwg_query($query);
+
+// set yoga/clear as default value for user_infos.template column
+$query = '
+ALTER TABLE '.PREFIX_TABLE.'user_infos
+  CHANGE COLUMN template template varchar(255) NOT NULL default \'yoga/clear\'
+;';
+pwg_query($query);
+
+// users having yoga-dark for template now have yoga/dark
+$query = '
+UPDATE '.PREFIX_TABLE.'user_infos
+  SET template = \'yoga/dark\'
+  WHERE template = \'yoga-dark\'
+;';
+pwg_query($query);
+
+// all other users have yoga/clear
+$query = '
+UPDATE '.PREFIX_TABLE.'user_infos
+  SET template = \'yoga/clear\'
+  WHERE template != \'yoga/dark\'
+;';
+pwg_query($query);
+
+echo
+"\n"
+.'Default template modified to yoga/clear'
+."\n"
+.'Template preference modified for every users : yoga/dark'
+.' (for yoga-dark users) and yoga/clear as default'
+."\n"
+;
+?>
Index: /tags/2.0.2/install/db/20-database.php
===================================================================
--- /tags/2.0.2/install/db/20-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/20-database.php	(revision 3278)
@@ -0,0 +1,87 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description =
+  '#image_category.is_storage replaced by #image.storage_category_id';
+
+// +-----------------------------------------------------------------------+
+// |                              New column                               |
+// +-----------------------------------------------------------------------+
+
+$query = '
+ALTER TABLE '.PREFIX_TABLE.'images
+  ADD storage_category_id smallint(5) unsigned default NULL
+;';
+pwg_query($query);
+
+$query = '
+SELECT category_id, image_id
+  FROM '.PREFIX_TABLE.'image_category
+  WHERE is_storage = \'true\'
+;';
+$result = pwg_query($query);
+
+$datas = array();
+while ($row = mysql_fetch_array($result))
+{
+  array_push(
+    $datas,
+    array(
+      'id' => $row['image_id'],
+      'storage_category_id' => $row['category_id'],
+      )
+    );
+}
+mass_updates(
+  PREFIX_TABLE.'images',
+  array(
+    'primary' => array('id'),
+    'update' => array('storage_category_id'),
+    ),
+  $datas
+  );
+
+// +-----------------------------------------------------------------------+
+// |                         Delete obsolete column                        |
+// +-----------------------------------------------------------------------+
+
+$query = '
+ALTER TABLE '.PREFIX_TABLE.'image_category DROP COLUMN is_storage
+;';
+pwg_query($query);
+
+// +-----------------------------------------------------------------------+
+// |                           End notification                            |
+// +-----------------------------------------------------------------------+
+
+echo
+"\n"
+.'Column '.PREFIX_TABLE.'image_category'
+.' replaced by '.PREFIX_TABLE.'images.storage_category_id'."\n"
+;
+?>
Index: /tags/2.0.2/install/db/21-database.php
===================================================================
--- /tags/2.0.2/install/db/21-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/21-database.php	(revision 3278)
@@ -0,0 +1,48 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'drop table #categories_link';
+
+// +-----------------------------------------------------------------------+
+// |                              New column                               |
+// +-----------------------------------------------------------------------+
+
+$query = '
+DROP TABLE '.PREFIX_TABLE.'categories_link
+;';
+pwg_query($query);
+
+// +-----------------------------------------------------------------------+
+// |                           End notification                            |
+// +-----------------------------------------------------------------------+
+
+echo
+"\n"
+.'Table '.PREFIX_TABLE.'categories_link dropped'."\n"
+;
+?>
Index: /tags/2.0.2/install/db/22-database.php
===================================================================
--- /tags/2.0.2/install/db/22-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/22-database.php	(revision 3278)
@@ -0,0 +1,54 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'add index on #tags.url_name and #image_tag.tag_id ';
+
+
+
+$query = '
+ALTER TABLE '.PREFIX_TABLE.'tags ADD INDEX `tags_i1`(`url_name`);
+;';
+pwg_query($query);
+
+
+$query = '
+ALTER TABLE '.PREFIX_TABLE.'image_tag ADD INDEX `image_tag_i1`(`tag_id`);
+;';
+pwg_query($query);
+
+
+// +-----------------------------------------------------------------------+
+// |                           End notification                            |
+// +-----------------------------------------------------------------------+
+
+echo
+"\n"
+.'Tables '.PREFIX_TABLE.'tags and '.PREFIX_TABLE.'image_tag updated'."\n"
+;
+echo $upgrade_description;
+?>
Index: /tags/2.0.2/install/db/23-database.php
===================================================================
--- /tags/2.0.2/install/db/23-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/23-database.php	(revision 3278)
@@ -0,0 +1,46 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'index images_i1 on storage_category_id comes back';
+
+$query = '
+ALTER TABLE '.PREFIX_TABLE.'images
+  ADD INDEX images_i1(storage_category_id)
+;';
+pwg_query($query);
+
+// +-----------------------------------------------------------------------+
+// |                           End notification                            |
+// +-----------------------------------------------------------------------+
+
+echo
+"\n"
+.$upgrade_description
+."\n"
+;
+?>
Index: /tags/2.0.2/install/db/24-database.php
===================================================================
--- /tags/2.0.2/install/db/24-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/24-database.php	(revision 3278)
@@ -0,0 +1,46 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'increase categories.rank size, up to 65535';
+
+$query = '
+ALTER TABLE '.PREFIX_TABLE.'categories
+  CHANGE COLUMN rank rank SMALLINT(5) UNSIGNED DEFAULT NULL
+;';
+pwg_query($query);
+
+// +-----------------------------------------------------------------------+
+// |                           End notification                            |
+// +-----------------------------------------------------------------------+
+
+echo
+"\n"
+.$upgrade_description
+."\n"
+;
+?>
Index: /tags/2.0.2/install/db/25-database.php
===================================================================
--- /tags/2.0.2/install/db/25-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/25-database.php	(revision 3278)
@@ -0,0 +1,47 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'reinitialize page_banner';
+
+$query = '
+UPDATE '.PREFIX_TABLE.'config
+  SET value = \'<h1>Piwigo demonstration site</h1><p>My photos web site</p>\'
+  WHERE param = \'page_banner\'
+;';
+pwg_query($query);
+
+// +-----------------------------------------------------------------------+
+// |                           End notification                            |
+// +-----------------------------------------------------------------------+
+
+echo
+"\n"
+.$upgrade_description
+."\n"
+;
+?>
Index: /tags/2.0.2/install/db/26-database.php
===================================================================
--- /tags/2.0.2/install/db/26-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/26-database.php	(revision 3278)
@@ -0,0 +1,43 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'add an auto login key in users table';
+
+// add column auto_login_key
+$query = '
+ALTER TABLE '.PREFIX_TABLE.'users
+  ADD auto_login_key varchar(64) NOT NULL
+;';
+pwg_query($query);
+
+echo
+"\n"
+. $upgrade_description
+."\n"
+;
+?>
Index: /tags/2.0.2/install/db/27-database.php
===================================================================
--- /tags/2.0.2/install/db/27-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/27-database.php	(revision 3278)
@@ -0,0 +1,43 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'change username length in users table';
+
+// add column auto_login_key
+$query = '
+ALTER TABLE '.PREFIX_TABLE.'users
+  CHANGE username username VARCHAR(100) NOT NULL 
+;';
+pwg_query($query);
+
+echo
+"\n"
+. $upgrade_description
+."\n"
+;
+?>
Index: /tags/2.0.2/install/db/28-database.php
===================================================================
--- /tags/2.0.2/install/db/28-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/28-database.php	(revision 3278)
@@ -0,0 +1,42 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'Delete old file index.htm';
+
+@unlink(PHPWG_ROOT_PATH.'/admin/images/index.htm');
+@unlink(PHPWG_ROOT_PATH.'/admin/include/index.htm');
+@unlink(PHPWG_ROOT_PATH.'/admin/index.htm');
+@unlink(PHPWG_ROOT_PATH.'/language/index.htm');
+@unlink(PHPWG_ROOT_PATH.'/galleries/index.htm');
+
+echo
+"\n"
+. $upgrade_description
+."\n"
+;
+?>
Index: /tags/2.0.2/install/db/29-database.php
===================================================================
--- /tags/2.0.2/install/db/29-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/29-database.php	(revision 3278)
@@ -0,0 +1,42 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'Add column #categories.image_order';
+
+$query = '
+ALTER TABLE '.PREFIX_TABLE.'categories
+  ADD COLUMN image_order VARCHAR(128) DEFAULT NULL
+;';
+pwg_query($query);
+
+echo
+"\n"
+. $upgrade_description
+."\n"
+;
+?>
Index: /tags/2.0.2/install/db/3-database.php
===================================================================
--- /tags/2.0.2/install/db/3-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/3-database.php	(revision 3278)
@@ -0,0 +1,53 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'Update session table for new session system';
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+
+// delete content of old session table
+$query = '
+DELETE FROM '.PREFIX_TABLE.'sessions
+;';
+pwg_query($query);
+
+// column user_id becomes data of type text
+$query = '
+ALTER TABLE '.PREFIX_TABLE.'sessions
+  CHANGE COLUMN user_id data text NOT NULL
+;';
+pwg_query($query);
+
+echo
+"\n"
+.'Column modified in sessions table'
+."\n"
+;
+?>
Index: /tags/2.0.2/install/db/30-database.php
===================================================================
--- /tags/2.0.2/install/db/30-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/30-database.php	(revision 3278)
@@ -0,0 +1,50 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'Add history_guest and login_history to #config';
+
+$query = '
+INSERT INTO '.PREFIX_TABLE."config (param,value,comment) VALUES ('history_admin',".
+((isset($conf['history_admin']) and $conf['history_admin']) ? 'true' : 'false').
+",'keep a history of administrator visits on your website');";
+pwg_query($query);
+
+$query = '
+INSERT INTO '.PREFIX_TABLE."config (param,value,comment) VALUES ('history_guest','true','keep a history of guest visits on your website');";
+pwg_query($query);
+
+$query = '
+INSERT INTO '.PREFIX_TABLE."config (param,value,comment) VALUES ('login_history','true','keep a history of user logins on your website');";
+pwg_query($query);
+
+echo
+"\n"
+. $upgrade_description
+."\n"
+;
+?>
Index: /tags/2.0.2/install/db/31-database.php
===================================================================
--- /tags/2.0.2/install/db/31-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/31-database.php	(revision 3278)
@@ -0,0 +1,43 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'change the upgrade 27 - username is binary';
+
+// add column auto_login_key
+$query = '
+ALTER TABLE '.PREFIX_TABLE.'users
+  CHANGE username username VARCHAR(100) binary NOT NULL
+;';
+pwg_query($query);
+
+echo
+"\n"
+. $upgrade_description
+."\n"
+;
+?>
Index: /tags/2.0.2/install/db/32-database.php
===================================================================
--- /tags/2.0.2/install/db/32-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/32-database.php	(revision 3278)
@@ -0,0 +1,43 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'add active_plugins to config';
+
+// add column auto_login_key
+$query = '
+INSERT INTO '.PREFIX_TABLE.'config (param,value,comment)
+  VALUES (\'active_plugins\',\'\',\'activated plugins\')
+;';
+pwg_query($query);
+
+echo
+"\n"
+. $upgrade_description
+."\n"
+;
+?>
Index: /tags/2.0.2/install/db/33-database.php
===================================================================
--- /tags/2.0.2/install/db/33-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/33-database.php	(revision 3278)
@@ -0,0 +1,51 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'Add column #group.is_default';
+
+include_once(PHPWG_ROOT_PATH.'include/constants.php');
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+
+echo "Add column is_default on ".GROUPS_TABLE;
+$query = '
+alter table '.GROUPS_TABLE.' add column 
+`is_default` enum(\'true\',\'false\') NOT NULL default \'false\'
+;';
+pwg_query($query);
+
+
+echo
+"\n"
+.'"'.$upgrade_description.'"'.' ended'
+."\n"
+;
+
+?>
Index: /tags/2.0.2/install/db/34-database.php
===================================================================
--- /tags/2.0.2/install/db/34-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/34-database.php	(revision 3278)
@@ -0,0 +1,56 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'Add #plugins and remove active_plugins from #config';
+
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+
+$query = '
+DELETE FROM '.PREFIX_TABLE.'config WHERE param="active_plugins"';
+pwg_query($query);
+
+$query = '
+CREATE TABLE '.PREFIX_TABLE.'plugins (
+  `id` varchar(64) binary NOT NULL default "",
+  `state` enum("inactive","active") NOT NULL default "inactive",
+  `version` varchar(64) NOT NULL default "0",
+  PRIMARY KEY  (`id`)
+);';
+pwg_query($query);
+
+
+echo
+"\n"
+.'"'.$upgrade_description.'"'.' ended'
+."\n"
+;
+
+?>
Index: /tags/2.0.2/install/db/35-database.php
===================================================================
--- /tags/2.0.2/install/db/35-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/35-database.php	(revision 3278)
@@ -0,0 +1,58 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'Add email_admin_on_new_user, email_admin_on_comment, email_admin_on_comment_validation';
+
+include_once(PHPWG_ROOT_PATH.'include/constants.php');
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+
+$query = "
+INSERT INTO ".CONFIG_TABLE." (param,value,comment) VALUES ('email_admin_on_new_user','false','Send an email to the admin when a user registers');
+";
+pwg_query($query);
+
+$query = "
+INSERT INTO ".CONFIG_TABLE." (param,value,comment) VALUES ('email_admin_on_comment','false','Send an email to the admin when a valid comment is entered');
+";
+pwg_query($query);
+
+$query = "
+INSERT INTO ".CONFIG_TABLE." (param,value,comment) VALUES ('email_admin_on_comment_validation','false','Send an email to the admin when a comment requires validation');
+";
+pwg_query($query);
+
+echo
+"\n"
+.'"'.$upgrade_description.'"'.' ended'
+."\n"
+;
+
+?>
Index: /tags/2.0.2/install/db/36-database.php
===================================================================
--- /tags/2.0.2/install/db/36-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/36-database.php	(revision 3278)
@@ -0,0 +1,43 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'get rid of #users.auto_login_key';
+
+$query = '
+ALTER TABLE '.PREFIX_TABLE.'users
+  DROP COLUMN auto_login_key
+;';
+pwg_query($query);
+
+echo
+"\n"
+.'"'.$upgrade_description.'"'.' ended'
+."\n"
+;
+
+?>
Index: /tags/2.0.2/install/db/37-database.php
===================================================================
--- /tags/2.0.2/install/db/37-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/37-database.php	(revision 3278)
@@ -0,0 +1,63 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'Cache user categories update';
+
+include_once(PHPWG_ROOT_PATH.'include/constants.php');
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+
+echo "Create table ".USER_CACHE_CATEGORIES_TABLE;
+$query = '
+CREATE TABLE '.USER_CACHE_CATEGORIES_TABLE.' (
+  `user_id` smallint(5) NOT NULL default \'0\',
+  `cat_id` smallint(5) unsigned NOT NULL default \'0\',
+  `is_child_date_last` enum(\'true\',\'false\') NOT NULL default \'false\',
+  `max_date_last` datetime default NULL,
+  `count_images` mediumint(8) unsigned default 0,
+  `count_categories` mediumint(8) unsigned default 0,
+  PRIMARY KEY  (`user_id`, `cat_id`)
+) TYPE=MyISAM;';
+pwg_query($query);
+
+echo "Update table cache ".USER_CACHE_TABLE;
+$query = '
+UPDATE '.USER_CACHE_TABLE.'
+  SET need_update = \'true\'
+;';
+pwg_query($query);
+
+echo
+"\n"
+.'"'.$upgrade_description.'"'.' ended'
+."\n"
+;
+
+?>
Index: /tags/2.0.2/install/db/38-database.php
===================================================================
--- /tags/2.0.2/install/db/38-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/38-database.php	(revision 3278)
@@ -0,0 +1,46 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'delete #user_cache_categories.is_child_date_last';
+
+include_once(PHPWG_ROOT_PATH.'include/constants.php');
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+$query = '
+ALTER TABLE '.USER_CACHE_CATEGORIES_TABLE.' DROP COLUMN is_child_date_last';
+pwg_query($query);
+
+echo
+"\n"
+.'"'.$upgrade_description.'"'.' ended'
+."\n"
+;
+
+?>
Index: /tags/2.0.2/install/db/39-database.php
===================================================================
--- /tags/2.0.2/install/db/39-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/39-database.php	(revision 3278)
@@ -0,0 +1,40 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'Add allow_user_registration to #config';
+
+$query = '
+INSERT INTO '.PREFIX_TABLE."config (param,value,comment) VALUES ('allow_user_registration','true','allow visitors to register?');";
+pwg_query($query);
+
+echo
+"\n"
+. $upgrade_description
+."\n"
+;
+?>
Index: /tags/2.0.2/install/db/4-database.php
===================================================================
--- /tags/2.0.2/install/db/4-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/4-database.php	(revision 3278)
@@ -0,0 +1,50 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'Table #search is required for search engine redesign';
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+
+// column user_id becomes data of type text
+$query = '
+CREATE TABLE '.PREFIX_TABLE.'search (
+  id int UNSIGNED NOT NULL AUTO_INCREMENT,
+  last_seen date DEFAULT NULL,
+  rules text,
+  PRIMARY KEY  (id)
+);';
+pwg_query($query);
+
+echo
+"\n"
+.'Table '.PREFIX_TABLE.'search created'
+."\n"
+;
+?>
Index: /tags/2.0.2/install/db/40-database.php
===================================================================
--- /tags/2.0.2/install/db/40-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/40-database.php	(revision 3278)
@@ -0,0 +1,40 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'Add ws_status to #config';
+
+$query = '
+INSERT INTO '.PREFIX_TABLE."config (param,value,comment) VALUES ('ws_status','true','Web Service is active/inactive');";
+pwg_query($query);
+
+echo
+"\n"
+. $upgrade_description
+."\n"
+;
+?>
Index: /tags/2.0.2/install/db/41-database.php
===================================================================
--- /tags/2.0.2/install/db/41-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/41-database.php	(revision 3278)
@@ -0,0 +1,61 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'Web service access table creation';
+
+include_once(PHPWG_ROOT_PATH.'include/constants.php');
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+
+echo "Create table ".WEB_SERVICES_ACCESS_TABLE;
+$query = '
+CREATE TABLE '.WEB_SERVICES_ACCESS_TABLE." (
+  id smallint(5) unsigned NOT NULL auto_increment,
+  name varchar(32) NOT NULL default '',
+  access varchar(255) default NULL,
+  `start` datetime default NULL,
+  `end` datetime default NULL,
+  request varchar(255) default NULL,
+  high enum('true','false') NOT NULL default 'true',
+  normal enum('true','false') NOT NULL default 'true',
+  `limit` smallint(5) unsigned default NULL,
+  `comment` varchar(255) default NULL,
+  PRIMARY KEY  (id),
+  UNIQUE KEY name (name)
+) ENGINE=MyISAM COMMENT='Access for Web Services';";
+pwg_query($query);
+
+echo
+"\n"
+.'"'.$upgrade_description.'"'.' ended'
+."\n"
+;
+
+?>
Index: /tags/2.0.2/install/db/42-database.php
===================================================================
--- /tags/2.0.2/install/db/42-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/42-database.php	(revision 3278)
@@ -0,0 +1,84 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'History table new model and new table history_summary';
+
+include_once(PHPWG_ROOT_PATH.'include/constants.php');
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+
+echo "Recreate table ".HISTORY_TABLE."\n";
+
+$query = 'DROP TABLE '.HISTORY_TABLE.';';
+pwg_query($query);
+
+$query = "
+CREATE TABLE `".HISTORY_TABLE."` (
+  `id` int(10) unsigned NOT NULL auto_increment,
+  `date` date NOT NULL default '0000-00-00',
+  `time` time NOT NULL default '00:00:00',
+  `year` smallint(4) NOT NULL default '0',
+  `month` tinyint(2) NOT NULL default '0',
+  `day` tinyint(2) NOT NULL default '0',
+  `hour` tinyint(2) NOT NULL default '0',
+  `user_id` smallint(5) NOT NULL default '0',
+  `IP` varchar(15) NOT NULL default '',
+  `section` enum('categories','tags','search','list','favorites','most_visited','best_rated','recent_pics','recent_cats') default NULL,
+  `category_id` smallint(5) default NULL,
+  `tag_ids` varchar(50) default NULL,
+  `image_id` mediumint(8) default NULL,
+  `summarized` enum('true','false') default 'false',
+  PRIMARY KEY  (`id`),
+  KEY `history_i1` (`summarized`)
+) TYPE=MyISAM
+;";
+pwg_query($query);
+
+echo "Create table ".HISTORY_SUMMARY_TABLE."\n";
+$query = "
+CREATE TABLE `".HISTORY_SUMMARY_TABLE."` (
+  `id` varchar(13) NOT NULL default '',
+  `year` smallint(4) NOT NULL default '0',
+  `month` tinyint(2) default NULL,
+  `day` tinyint(2) default NULL,
+  `hour` tinyint(2) default NULL,
+  `nb_pages` int(11) default NULL,
+  PRIMARY KEY  (`id`)
+) TYPE=MyISAM
+;";
+pwg_query($query);
+
+echo
+"\n"
+.'"'.$upgrade_description.'"'.' ended'
+."\n"
+;
+
+?>
Index: /tags/2.0.2/install/db/43-database.php
===================================================================
--- /tags/2.0.2/install/db/43-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/43-database.php	(revision 3278)
@@ -0,0 +1,47 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'Insert secret_key into #config';
+
+include_once(PHPWG_ROOT_PATH.'include/constants.php');
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+
+$query = '
+INSERT INTO '.PREFIX_TABLE."config (param,value,comment) VALUES ('secret_key', MD5(RAND()), 'a secret key specific to the gallery for internal use');";
+pwg_query($query);
+
+echo
+"\n"
+. $upgrade_description
+."\n"
+;
+
+?>
Index: /tags/2.0.2/install/db/44-database.php
===================================================================
--- /tags/2.0.2/install/db/44-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/44-database.php	(revision 3278)
@@ -0,0 +1,47 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'None efficient index removed for performance reasons';
+
+include_once(PHPWG_ROOT_PATH.'include/constants.php');
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+
+$query = '
+ALTER TABLE '.PREFIX_TABLE.'image_category DROP INDEX `image_category_i1;';
+pwg_query($query);
+
+echo
+"\n"
+. $upgrade_description
+."\n"
+;
+
+?>
Index: /tags/2.0.2/install/db/45-database.php
===================================================================
--- /tags/2.0.2/install/db/45-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/45-database.php	(revision 3278)
@@ -0,0 +1,48 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'Index rename without any reason except human logic';
+
+include_once(PHPWG_ROOT_PATH.'include/constants.php');
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+
+$query = '
+ALTER TABLE '.PREFIX_TABLE.'image_category DROP INDEX image_category_i2 ,
+ADD INDEX image_category ( category_id ) ;';
+pwg_query($query);
+
+echo
+"\n"
+. $upgrade_description
+."\n"
+;
+
+?>
Index: /tags/2.0.2/install/db/46-database.php
===================================================================
--- /tags/2.0.2/install/db/46-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/46-database.php	(revision 3278)
@@ -0,0 +1,46 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'remove login_history from #config (partial revert 30-database.php)';
+
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+
+$query = '
+DELETE FROM '.PREFIX_TABLE.'config WHERE param="login_history"';
+pwg_query($query);
+
+echo
+"\n"
+.'"'.$upgrade_description.'"'.' ended'
+."\n"
+;
+
+?>
Index: /tags/2.0.2/install/db/47-database.php
===================================================================
--- /tags/2.0.2/install/db/47-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/47-database.php	(revision 3278)
@@ -0,0 +1,52 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'Remove ws_status from #config';
+
+$query = '
+DELETE FROM '.PREFIX_TABLE."config WHERE param ='ws_status';";
+pwg_query($query);
+
+echo
+"\n"
+. $upgrade_description
+."\n"
+;
+$upgrade_description = 'Add show_nb_hits to #user_infos';
+
+$query = '
+ALTER TABLE '.PREFIX_TABLE."user_infos ADD `show_nb_hits` 
+ENUM( 'true', 'false' ) DEFAULT 'false' NOT NULL AFTER `show_nb_comments` ;";
+pwg_query($query);
+
+echo
+"\n"
+. $upgrade_description
+."\n"
+;
+?>
Index: /tags/2.0.2/install/db/48-database.php
===================================================================
--- /tags/2.0.2/install/db/48-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/48-database.php	(revision 3278)
@@ -0,0 +1,48 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'Insert show_nb_hits into #config';
+
+include_once(PHPWG_ROOT_PATH.'include/constants.php');
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+
+$query = '
+INSERT INTO '.PREFIX_TABLE."config (param,value,comment) 
+VALUES ('show_nb_hits', 'false', 'Show hits count under thumbnails');";
+pwg_query($query);
+
+echo
+"\n"
+. $upgrade_description
+."\n"
+;
+
+?>
Index: /tags/2.0.2/install/db/49-database.php
===================================================================
--- /tags/2.0.2/install/db/49-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/49-database.php	(revision 3278)
@@ -0,0 +1,54 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'Add notification by mail params (HTML mail and new informartions)';
+
+include_once(PHPWG_ROOT_PATH.'include/constants.php');
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+
+echo "Add params on ".CONFIG_TABLE;
+$query = "
+INSERT INTO ".CONFIG_TABLE." (param,value,comment) VALUES ('nbm_send_html_mail','true','Send mail on HTML format for notification by mail');
+";
+pwg_query($query);
+
+$query = "
+INSERT INTO ".CONFIG_TABLE." (param,value,comment) VALUES ('nbm_send_recent_post_dates','true','Send recent post by dates for notification by mail');
+";
+pwg_query($query);
+
+echo
+"\n"
+.'"'.$upgrade_description.'"'.' ended'
+."\n"
+;
+
+?>
Index: /tags/2.0.2/install/db/5-database.php
===================================================================
--- /tags/2.0.2/install/db/5-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/5-database.php	(revision 3278)
@@ -0,0 +1,46 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'Update images table with has_high column';
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+
+// column user_id becomes data of type text
+$query = "
+ALTER TABLE ".PREFIX_TABLE."images ADD COLUMN has_high ENUM('true') DEFAULT NULL AFTER average_rate;
+";
+pwg_query($query);
+
+echo
+"\n"
+.'Column has_high '.PREFIX_TABLE.'images added'
+."\n"
+;
+?>
Index: /tags/2.0.2/install/db/50-database.php
===================================================================
--- /tags/2.0.2/install/db/50-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/50-database.php	(revision 3278)
@@ -0,0 +1,50 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'Remove high and normal columns from #ws_access';
+
+include_once(PHPWG_ROOT_PATH.'include/constants.php');
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+
+echo "Drop some columns from ".WEB_SERVICES_ACCESS_TABLE;
+$query = "
+ALTER TABLE ".WEB_SERVICES_ACCESS_TABLE."
+  DROP `high`,
+  DROP `normal`;";
+pwg_query($query);
+
+echo
+"\n"
+.'"'.$upgrade_description.'"'.' ended'
+."\n"
+;
+
+?>
Index: /tags/2.0.2/install/db/51-database.php
===================================================================
--- /tags/2.0.2/install/db/51-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/51-database.php	(revision 3278)
@@ -0,0 +1,57 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'Add #history.is_high column';
+
+include_once(PHPWG_ROOT_PATH.'include/constants.php');
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+
+$query = "
+ALTER TABLE ".HISTORY_TABLE."
+  ADD COLUMN is_high ENUM('true', 'false') DEFAULT NULL
+;";
+pwg_query($query);
+
+$query = "
+UPDATE ".HISTORY_TABLE."
+  SET is_high = 'false'
+  WHERE image_id IS NOT NULL
+   AND is_high IS NULL
+;";
+pwg_query($query);
+
+echo
+"\n"
+.'"'.$upgrade_description.'"'.', ended'
+."\n"
+;
+
+?>
Index: /tags/2.0.2/install/db/52-database.php
===================================================================
--- /tags/2.0.2/install/db/52-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/52-database.php	(revision 3278)
@@ -0,0 +1,69 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'Replace #history.is_high by #history.image_type';
+
+include_once(PHPWG_ROOT_PATH.'include/constants.php');
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+
+$query = "
+ALTER TABLE ".HISTORY_TABLE."
+  ADD COLUMN image_type ENUM('picture', 'high', 'other') DEFAULT NULL
+;";
+pwg_query($query);
+
+$query = "
+UPDATE ".HISTORY_TABLE."
+  SET image_type = 'high'
+  WHERE is_high = 'true'
+;";
+pwg_query($query);
+
+$query = "
+UPDATE ".HISTORY_TABLE."
+  SET image_type = 'picture'
+  WHERE is_high = 'false'
+;";
+pwg_query($query);
+
+$query = "
+ALTER TABLE ".HISTORY_TABLE."
+  DROP COLUMN is_high
+;";
+pwg_query($query);
+
+echo
+"\n"
+.'"'.$upgrade_description.'"'.', ended'
+."\n"
+;
+
+?>
Index: /tags/2.0.2/install/db/53-database.php
===================================================================
--- /tags/2.0.2/install/db/53-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/53-database.php	(revision 3278)
@@ -0,0 +1,57 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = '#comments.content is not html escaped anymore';
+
+include_once(PHPWG_ROOT_PATH.'include/constants.php');
+
+
+$replacements = array(
+    array('&#039;', '\''),
+    array('&quot;', '"'),
+    array('&lt;',   '<'),
+    array('&gt;',   '>'),
+    array('&amp;',  '&') // <- this must be the last one
+  );
+
+foreach ($replacements as $replacement)
+{
+  $query = '
+UPDATE '.COMMENTS_TABLE.'
+  SET content = REPLACE(content, "'.addslashes($replacement[0]).'", "'.addslashes($replacement[1]).'")
+;';
+  pwg_query($query);
+}
+
+echo
+"\n"
+.'"'.$upgrade_description.'"'.', ended'
+."\n"
+;
+
+?>
Index: /tags/2.0.2/install/db/54-database.php
===================================================================
--- /tags/2.0.2/install/db/54-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/54-database.php	(revision 3278)
@@ -0,0 +1,69 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'add column #categories.permalink and table #old_permalinks';
+
+include_once(PHPWG_ROOT_PATH.'include/constants.php');
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+
+defined('OLD_PERMALINKS_TABLE') or die('OLD_PERMALINKS_TABLE is not defined');
+
+$query = "
+CREATE TABLE `".OLD_PERMALINKS_TABLE."` (
+  `cat_id` smallint(5) unsigned NOT NULL,
+  `permalink` VARCHAR(64) NOT NULL,
+  `date_deleted` datetime NOT NULL,
+  `last_hit` datetime default NULL,
+  `hit` int(10) unsigned NOT NULL default '0',
+  PRIMARY KEY (`permalink`)
+) TYPE=MyISAM
+;";
+pwg_query($query);
+
+$query = "
+ALTER TABLE `".CATEGORIES_TABLE."`
+  ADD COLUMN `permalink` VARCHAR(64) default NULL
+;";
+pwg_query($query);
+
+$query = "
+ALTER TABLE `".CATEGORIES_TABLE."`
+  ADD UNIQUE INDEX `categories_i3` (`permalink`)
+;";
+pwg_query($query);
+
+echo
+"\n"
+.'"'.$upgrade_description.'"'.' ended'
+."\n"
+;
+
+?>
Index: /tags/2.0.2/install/db/55-database.php
===================================================================
--- /tags/2.0.2/install/db/55-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/55-database.php	(revision 3278)
@@ -0,0 +1,59 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description =
+  'Update #history.image_type to "picture" by default when image_id is not null';
+
+include_once(PHPWG_ROOT_PATH.'include/constants.php');
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+
+$query = "
+UPDATE ".HISTORY_TABLE."
+  SET image_type = 'picture'
+  WHERE image_id IS NOT NULL
+    AND image_type IS NULL
+;";
+pwg_query($query);
+
+$query = "
+UPDATE ".HISTORY_TABLE."
+  SET image_type = NULL
+  WHERE image_id IS NULL
+;";
+pwg_query($query);
+
+echo
+"\n"
+.'"'.$upgrade_description.'"'.', ended'
+."\n"
+;
+
+?>
Index: /tags/2.0.2/install/db/56-database.php
===================================================================
--- /tags/2.0.2/install/db/56-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/56-database.php	(revision 3278)
@@ -0,0 +1,49 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'Add #images.high_filesize';
+
+include_once(PHPWG_ROOT_PATH.'include/constants.php');
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+
+$query = "
+ALTER TABLE ".IMAGES_TABLE."
+  ADD COLUMN high_filesize mediumint(9) unsigned default NULL
+;";
+pwg_query($query);
+
+echo
+"\n"
+.'"'.$upgrade_description.'"'.', ended'
+."\n"
+;
+
+?>
Index: /tags/2.0.2/install/db/57-database.php
===================================================================
--- /tags/2.0.2/install/db/57-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/57-database.php	(revision 3278)
@@ -0,0 +1,63 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'Update email_admin_on_new_user, email_admin_on_comment, email_admin_on_comment_validation & Add email_admin_on_picture_uploaded';
+
+include_once(PHPWG_ROOT_PATH.'include/constants.php');
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+
+$query = "
+UPDATE ".CONFIG_TABLE." set comment = 'Send an email to the administrators when a user registers' where param = 'email_admin_on_new_user';
+";
+pwg_query($query);
+
+$query = "
+UPDATE ".CONFIG_TABLE." set comment = 'Send an email to the administrators when a valid comment is entered' where param = 'email_admin_on_comment';
+";
+pwg_query($query);
+
+$query = "
+UPDATE ".CONFIG_TABLE." set comment = 'Send an email to the administrators when a comment requires validation' where param = 'email_admin_on_comment_validation';
+";
+pwg_query($query);
+
+$query = "
+INSERT INTO ".CONFIG_TABLE." (param,value,comment) VALUES ('email_admin_on_picture_uploaded','false','Send an email to the administrators when a picture is uploaded');
+";
+pwg_query($query);
+
+echo
+"\n"
+.'"'.$upgrade_description.'"'.' ended'
+."\n"
+;
+
+?>
Index: /tags/2.0.2/install/db/58-database.php
===================================================================
--- /tags/2.0.2/install/db/58-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/58-database.php	(revision 3278)
@@ -0,0 +1,48 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'Change default value for #user_infos.language';
+
+include_once(PHPWG_ROOT_PATH.'include/constants.php');
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+
+$query = "
+ALTER TABLE ".USER_INFOS_TABLE." CHANGE `language` `language` varchar(50) NOT NULL default 'en_UK.iso-8859-1'
+";
+pwg_query($query);
+
+echo
+"\n"
+.'"'.$upgrade_description.'"'.' ended'
+."\n"
+;
+
+?>
Index: /tags/2.0.2/install/db/59-database.php
===================================================================
--- /tags/2.0.2/install/db/59-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/59-database.php	(revision 3278)
@@ -0,0 +1,79 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'Rename some indexes following PWG naming rules';
+
+include_once(PHPWG_ROOT_PATH.'include/constants.php');
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+
+$query = "
+DROP INDEX image_category ON ".IMAGE_CATEGORY_TABLE."
+;
+";
+pwg_query($query);
+
+$query = "
+CREATE INDEX image_category_i1 ON ".IMAGE_CATEGORY_TABLE." (category_id)
+;
+";
+pwg_query($query);
+
+$query = "
+DROP INDEX uidx_check_key ON ".USER_MAIL_NOTIFICATION_TABLE."
+;
+";
+pwg_query($query);
+
+$query = "
+CREATE UNIQUE INDEX user_mail_notification_ui1 ON ".USER_MAIL_NOTIFICATION_TABLE." (check_key)
+;
+";
+pwg_query($query);
+
+$query = "
+DROP INDEX name ON ".WEB_SERVICES_ACCESS_TABLE."
+;
+";
+pwg_query($query);
+
+$query = "
+CREATE UNIQUE INDEX ws_access_ui1 ON ".WEB_SERVICES_ACCESS_TABLE." (name)
+;
+";
+pwg_query($query);
+
+echo
+"\n"
+.'"'.$upgrade_description.'"'.' ended'
+."\n"
+;
+
+?>
Index: /tags/2.0.2/install/db/6-database.php
===================================================================
--- /tags/2.0.2/install/db/6-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/6-database.php	(revision 3278)
@@ -0,0 +1,53 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'Table #user_mail_notification is required for NBM';
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+
+// Creating table user_mail_notification
+$query = '
+CREATE TABLE '.PREFIX_TABLE.'user_mail_notification
+(
+  user_id smallint(5) NOT NULL default \'0\',
+  check_key varchar(128) binary NOT NULL,
+  enabled enum(\'true\',\'false\') NOT NULL default \'false\',
+  last_send datetime default NULL,
+  PRIMARY KEY  (`user_id`),
+  UNIQUE KEY `uidx_check_key` (`check_key`)
+) TYPE=MyISAM;';
+pwg_query($query);
+
+echo
+"\n"
+.'Table '.PREFIX_TABLE.'user_mail_notification created'
+."\n"
+;
+?>
Index: /tags/2.0.2/install/db/60-database.php
===================================================================
--- /tags/2.0.2/install/db/60-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/60-database.php	(revision 3278)
@@ -0,0 +1,86 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'Change default value on #user_infos for guest';
+
+include_once(PHPWG_ROOT_PATH.'include/constants.php');
+include(PHPWG_ROOT_PATH . 'include/config_default.inc.php');
+@include(PHPWG_ROOT_PATH. 'include/config_local.inc.php');
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+
+load_conf_from_db();
+
+$query = "
+update ".USER_INFOS_TABLE."
+set
+  template = '".$conf['default_template']."',
+  nb_image_line = ".$conf['nb_image_line'].",
+  nb_line_page = ".$conf['nb_line_page'].",
+  language = '".$conf['default_language']."',
+  maxwidth = ".(empty($conf['default_maxwidth']) ? "null" : $conf['default_maxwidth']).",
+  maxheight = ".(empty($conf['default_maxheight']) ? "null" : $conf['default_maxheight']).",
+  recent_period = ".$conf['recent_period'].",
+  expand = '".boolean_to_string($conf['auto_expand'])."',
+  show_nb_comments = '".boolean_to_string($conf['show_nb_comments'])."',
+  show_nb_hits = '".boolean_to_string($conf['show_nb_hits'])."',
+  enabled_high = '".boolean_to_string(
+    (isset($conf['newuser_default_enabled_high']) ? 
+      $conf['newuser_default_enabled_high'] : true))."'
+where
+  user_id = ".$conf['default_user_id'].";";
+pwg_query($query);
+
+
+$query = "
+delete from ".CONFIG_TABLE."
+where
+  param in
+(
+  'default_template',
+  'nb_image_line',
+  'nb_line_page',
+  'default_language',
+  'default_maxwidth',
+  'default_maxheight',
+  'recent_period',
+  'auto_expand',
+  'show_nb_comments',
+  'show_nb_hits'
+);";
+pwg_query($query);
+
+echo
+"\n"
+.'"'.$upgrade_description.'"'.' ended'
+."\n"
+;
+
+?>
Index: /tags/2.0.2/install/db/61-database.php
===================================================================
--- /tags/2.0.2/install/db/61-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/61-database.php	(revision 3278)
@@ -0,0 +1,50 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'Add unique index on #_groups for name';
+
+include_once(PHPWG_ROOT_PATH.'include/constants.php');
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+
+
+$query = "
+alter table ".GROUPS_TABLE."
+  add UNIQUE KEY `groups_ui1` (`name`)
+;";
+pwg_query($query);
+
+echo
+"\n"
+.'"'.$upgrade_description.'"'.' ended'
+."\n"
+;
+
+?>
Index: /tags/2.0.2/install/db/62-database.php
===================================================================
--- /tags/2.0.2/install/db/62-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/62-database.php	(revision 3278)
@@ -0,0 +1,48 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'Add obligatory_user_mail config';
+
+include_once(PHPWG_ROOT_PATH.'include/constants.php');
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+
+$query = "
+INSERT INTO ".CONFIG_TABLE." (param,value,comment) VALUES ('obligatory_user_mail_address','false','Mail address is obligatory for users');
+";
+pwg_query($query);
+
+echo
+"\n"
+.'"'.$upgrade_description.'"'.' ended'
+."\n"
+;
+
+?>
Index: /tags/2.0.2/install/db/63-database.php
===================================================================
--- /tags/2.0.2/install/db/63-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/63-database.php	(revision 3278)
@@ -0,0 +1,73 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'Add #user_infos.level, #images.level and #user_cache.forbidden_images';
+
+include_once(PHPWG_ROOT_PATH.'include/constants.php');
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+
+$query = '
+ALTER TABLE '.IMAGES_TABLE.' ADD COLUMN level TINYINT UNSIGNED NOT NULL DEFAULT 0
+';
+pwg_query($query);
+
+$query = '
+ALTER TABLE '.USER_INFOS_TABLE.' ADD COLUMN level TINYINT UNSIGNED NOT NULL DEFAULT 0
+';
+pwg_query($query);
+
+$query = '
+ALTER TABLE '.USER_CACHE_TABLE.' ADD COLUMN image_access_type enum("NOT IN","IN") NOT NULL default "NOT IN"
+';
+pwg_query($query);
+
+$query = '
+ALTER TABLE '.USER_CACHE_TABLE.' ADD COLUMN image_access_list TEXT DEFAULT NULL
+';
+pwg_query($query);
+
+$query = '
+UPDATE '.USER_INFOS_TABLE.' SET level=8 WHERE status="webmaster"
+';
+pwg_query($query);
+
+$query = '
+UPDATE '.USER_CACHE_TABLE.' SET need_update=true
+';
+pwg_query($query);
+
+echo
+"\n"
+.'"'.$upgrade_description.'"'.' ended'
+."\n"
+;
+
+?>
Index: /tags/2.0.2/install/db/64-database.php
===================================================================
--- /tags/2.0.2/install/db/64-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/64-database.php	(revision 3278)
@@ -0,0 +1,50 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'Activation of c13_upgrade plugin';
+
+include_once(PHPWG_ROOT_PATH.'include/constants.php');
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+
+$query = '
+REPLACE INTO '.PLUGINS_TABLE.'
+  (id, state)
+  VALUES (\'c13y_upgrade\', \'active\')
+;';
+pwg_query($query);
+
+echo
+"\n"
+.'"'.$upgrade_description.'"'.' ended'
+."\n"
+;
+
+?>
Index: /tags/2.0.2/install/db/65-database.php
===================================================================
--- /tags/2.0.2/install/db/65-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/65-database.php	(revision 3278)
@@ -0,0 +1,300 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+function upgrade65_change_table_to_blob($table, $field_definitions)
+{
+  $types = array('varchar'  => 'varbinary',
+    'text' => 'blob',
+    'mediumtext' => 'mediumblob',
+    'longtext' => 'longblob');
+
+  $changes=array();
+  foreach( $field_definitions as $row)
+  {
+    if ( !isset($row['Collation']) or $row['Collation']=='NULL' )
+      continue;
+    list ($type) = explode('(', $row['Type']);
+    if (!isset($types[$type]))
+      continue; // no need
+    $binaryType = preg_replace('/'. $type .'/i', $types[$type], $row['Type'] );
+    $changes[] = 'MODIFY COLUMN '.$row['Field'].' '.$binaryType;
+  }
+  if (count($changes))
+  {
+    $query = 'ALTER TABLE '.$table.' '.implode(', ', $changes);
+    pwg_query($query);
+  }
+}
+
+function upgrade65_change_table_to_charset($table, $field_definitions, $db_charset)
+{
+  $changes=array();
+  foreach( $field_definitions as $row)
+  {
+    if ( !isset($row['Collation']) or $row['Collation']=='NULL' )
+      continue;
+    $query = $row['Field'].' '.$row['Type'];
+    $query .= ' CHARACTER SET '.$db_charset;
+    if (strpos($row['Collation'],'_bin')!==false)
+    {
+      $query .= ' BINARY';
+    }
+    if ($row['Null']!='YES')
+    {
+      $query.=' NOT NULL';
+      if (isset($row['Default']))
+        $query.=' DEFAULT "'.addslashes($row['Default']).'"';
+    }
+    else
+    {
+      if (!isset($row['Default']))
+        $query.=' DEFAULT NULL';
+      else
+        $query.=' DEFAULT "'.addslashes($row['Default']).'"';
+    }
+
+    if ($row['Extra']=='auto_increment')
+    {
+      $query.=' auto_increment';
+    }
+    $changes[] = 'MODIFY COLUMN '.$query;
+  }
+
+  if (count($changes))
+  {
+    $query = 'ALTER TABLE `'.$table.'` '.implode(', ', $changes);
+    pwg_query($query);
+  }
+}
+
+
+$upgrade_description = 'PWG charset migration';
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+if ( !defined('PWG_CHARSET') )
+{
+  $upgrade_log = '';
+
+// +-----------------------------------------------------------------------+
+// load all the user languages
+  $all_langs=array();
+  $query='
+SELECT language, COUNT(user_id) AS count FROM '.USER_INFOS_TABLE.'
+  GROUP BY language';
+  $result = pwg_query($query);
+  while ( $row=mysql_fetch_assoc($result) )
+  {
+    $language = $row["language"];
+    $lang_def = explode('.', $language);
+    if ( count($lang_def)==2 )
+    {
+      $new_lang = $lang_def[0];
+      $charset = strtolower($lang_def[1]);
+    }
+    else
+    {
+      $new_lang = 'en_UK';
+      $charset = 'iso-8859-1';
+    }
+    $all_langs[$language] = array(
+      'count' => $row['count'],
+      'new_lang' => $new_lang,
+      'charset' => $charset,
+      );
+    $upgrade_log .= ">>user_lang\t".$language."\t".$row['count']."\n";
+  }
+  $upgrade_log .= "\n";
+
+
+// +-----------------------------------------------------------------------+
+// get admin charset
+  include(PHPWG_ROOT_PATH . 'include/config_default.inc.php');
+  @include(PHPWG_ROOT_PATH. 'include/config_local.inc.php');
+  $admin_charset='iso-8859-1';
+  $query='
+SELECT language FROM '.USER_INFOS_TABLE.'
+  WHERE user_id='.$conf['webmaster_id'];
+  $result = pwg_query($query);
+  if (mysql_num_rows($result)==0)
+  {
+    $query='
+SELECT language FROM '.USER_INFOS_TABLE.'
+  WHERE status="webmaster" and adviser="false"
+  LIMIT 1';
+    $result = pwg_query($query);
+  }
+
+  if ( $row=mysql_fetch_assoc($result) )
+  {
+    $admin_charset = $all_langs[$row['language']]['charset'];
+  }
+  $upgrade_log .= ">>admin_charset\t".$admin_charset."\n";
+
+
+// +-----------------------------------------------------------------------+
+// get mysql version and structure of tables
+  $mysql_version = mysql_get_server_info();
+  $upgrade_log .= ">>mysql_ver\t".$mysql_version."\n";
+
+  $all_tables = array();
+  $query = 'SHOW TABLES LIKE "'.$prefixeTable.'%"';
+  $result = pwg_query($query);
+  while ( $row=mysql_fetch_array($result) )
+  {
+    array_push($all_tables, $row[0]);
+  }
+
+  $all_tables_definition = array();
+  foreach( $all_tables as $table)
+  {
+    $query = 'SHOW FULL COLUMNS FROM '.$table;
+    $result = pwg_query($query);
+    $field_definitions=array();
+    while ( $row=mysql_fetch_array($result) )
+    {
+      if ( !isset($row['Collation']) or $row['Collation']=='NULL' )
+        continue;
+      array_push($field_definitions, $row);
+    }
+    $all_tables_definition[$table] = $field_definitions;
+  }
+
+// +-----------------------------------------------------------------------+
+// calculate the result and convert the tables
+
+//tables that can be converted without going through binary (they contain only ascii data)
+  $safe_tables=array('history','history_backup','history_summary','old_permalinks','plugins','rate','upgrade','user_cache','user_feed','user_infos','user_mail_notification', 'users', 'waiting','ws_access');
+  $safe_tables=array_flip($safe_tables);
+
+  $pwg_charset = 'iso-8859-1';
+  $db_charset = 'latin1';
+  $db_collate = '';
+  if ( version_compare($mysql_version, '4.1', '<') )
+  { // below 4.1 no charset support
+    $upgrade_log .= "< conversion\tnothing\n";
+  }
+  elseif ($admin_charset=='iso-8859-1')
+  {
+    $pwg_charset = 'utf-8';
+    $db_charset = 'utf8';
+    foreach($all_tables as $table)
+    {
+      upgrade65_change_table_to_charset($table, $all_tables_definition[$table], 'utf8' );
+      $query = 'ALTER TABLE '.$table.' DEFAULT CHARACTER SET utf8';
+      pwg_query($query);
+    }
+    $upgrade_log .= "< conversion\tchange utf8\n";
+  }
+/*ALTER TABLE tbl_name CONVERT TO CHARACTER SET charset_name; (or change column character set)
+
+Warning: The preceding operation converts column values between the character sets. This is not what you want if you have a column in one character set (like latin1) but the stored values actually use some other, incompatible character set (like utf8). In this case, you have to do the following for each such column:
+
+ALTER TABLE t1 CHANGE c1 c1 BLOB;
+ALTER TABLE t1 CHANGE c1 c1 TEXT CHARACTER SET utf8;
+*/
+  elseif ( $admin_charset=='utf-8')
+  {
+    $pwg_charset = 'utf-8';
+    $db_charset = 'utf8';
+    foreach($all_tables as $table)
+    {
+      if ( !isset($safe_tables[ substr($table, strlen($prefixeTable)) ]) )
+        upgrade65_change_table_to_blob($table, $all_tables_definition[$table] );
+      upgrade65_change_table_to_charset($table, $all_tables_definition[$table], 'utf8' );
+      $query = 'ALTER TABLE '.$table.' DEFAULT CHARACTER SET utf8';
+      pwg_query($query);
+    }
+    $upgrade_log .= "< conversion\tchange binary\n";
+    $upgrade_log .= "< conversion\tchange utf8\n";
+  }
+  elseif ( $admin_charset=='iso-8859-2'/*Central European*/)
+  {
+    $pwg_charset = 'utf-8';
+    $db_charset = 'utf8';
+    foreach($all_tables as $table)
+    {
+      if ( !isset($safe_tables[ substr($table, strlen($prefixeTable)) ]) )
+      {
+        upgrade65_change_table_to_blob($table, $all_tables_definition[$table] );
+        upgrade65_change_table_to_charset($table, $all_tables_definition[$table], 'latin2' );
+      }
+      upgrade65_change_table_to_charset($table, $all_tables_definition[$table], 'utf8' );
+      $query = 'ALTER TABLE '.$table.' DEFAULT CHARACTER SET utf8';
+      pwg_query($query);
+    }
+    $upgrade_log .= "< conversion\tchange binary\n";
+    $upgrade_log .= "< conversion\tchange latin2\n";
+    $upgrade_log .= "< conversion\tchange utf8\n";
+  }
+
+
+// +-----------------------------------------------------------------------+
+// changes to write in mysql.inc.php
+  array_push($mysql_changes,
+'define(\'PWG_CHARSET\', \''.$pwg_charset.'\');
+define(\'DB_CHARSET\',  \''.$db_charset.'\');
+define(\'DB_COLLATE\',  \'\');'
+  );
+
+  foreach ($all_langs as $old_lang=>$lang_data)
+  {
+    $query='
+  UPDATE '.USER_INFOS_TABLE.' SET language="'.$lang_data['new_lang'].'"
+    WHERE language="'.$old_lang.'"';
+    pwg_query($query);
+  }
+
+  define('PWG_CHARSET', $pwg_charset);
+  define('DB_CHARSET',  $db_charset);
+  define('DB_COLLATE',  '');
+
+  if ( version_compare(mysql_get_server_info(), '4.1.0', '>=') and DB_CHARSET!='' )
+  {
+    pwg_query('SET NAMES "'.DB_CHARSET.'"');
+  }
+
+  echo $upgrade_log;
+  $fp = @fopen( PHPWG_ROOT_PATH.'upgrade65.log', 'w' );
+  if ($fp)
+  {
+    @fputs($fp, $upgrade_log, strlen($upgrade_log));
+    @fclose($fp);
+  }
+
+echo
+"\n"
+.'"'.$upgrade_description.'"'.' ended'
+."\n"
+;
+}
+else
+{
+  echo 'PWG_CHARSET already defined - nada';
+}
+?>
Index: /tags/2.0.2/install/db/66-database.php
===================================================================
--- /tags/2.0.2/install/db/66-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/66-database.php	(revision 3278)
@@ -0,0 +1,48 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'Add c13y_ignore config';
+
+include_once(PHPWG_ROOT_PATH.'include/constants.php');
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+
+$query = "
+INSERT INTO ".CONFIG_TABLE." (param,value,comment) VALUES ('c13y_ignore',null,'List of ignored anomalies');
+";
+pwg_query($query);
+
+echo
+"\n"
+.'"'.$upgrade_description.'"'.' ended'
+."\n"
+;
+
+?>
Index: /tags/2.0.2/install/db/67-database.php
===================================================================
--- /tags/2.0.2/install/db/67-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/67-database.php	(revision 3278)
@@ -0,0 +1,48 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'Uninstall dew plugin';
+
+include_once(PHPWG_ROOT_PATH.'include/constants.php');
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+
+$query = "
+delete from ".PLUGINS_TABLE." where id ='dew';
+";
+pwg_query($query);
+
+echo
+"\n"
+.'"'.$upgrade_description.'"'.' ended'
+."\n"
+;
+
+?>
Index: /tags/2.0.2/install/db/68-database.php
===================================================================
--- /tags/2.0.2/install/db/68-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/68-database.php	(revision 3278)
@@ -0,0 +1,55 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'Change type from text to mediumtext for #sessions.data #user_cache.forbidden_categories and #user_cache.image_access_list';
+
+include_once(PHPWG_ROOT_PATH.'include/constants.php');
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+
+$query = '
+ALTER TABLE '.SESSIONS_TABLE.'
+  MODIFY COLUMN data MEDIUMTEXT NOT NULL';
+pwg_query($query);
+
+$query = '
+ALTER TABLE '.USER_CACHE_TABLE.'
+  MODIFY COLUMN forbidden_categories MEDIUMTEXT,
+  MODIFY COLUMN image_access_list MEDIUMTEXT
+  ';
+pwg_query($query);
+
+echo
+"\n"
+.'"'.$upgrade_description.'"'.' ended'
+."\n"
+;
+
+?>
Index: /tags/2.0.2/install/db/69-database.php
===================================================================
--- /tags/2.0.2/install/db/69-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/69-database.php	(revision 3278)
@@ -0,0 +1,58 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'Move #categories.date_last and nb_images to #user_cache_categories';
+
+include_once(PHPWG_ROOT_PATH.'include/constants.php');
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+
+$query = '
+ALTER TABLE '.USER_CACHE_CATEGORIES_TABLE.'
+  ADD COLUMN date_last datetime default NULL AFTER cat_id,
+  ADD COLUMN nb_images mediumint(8) unsigned NOT NULL default 0 AFTER max_date_last';
+pwg_query($query);
+
+$query = '
+ALTER TABLE '.CATEGORIES_TABLE.'
+  DROP COLUMN date_last,
+  DROP COLUMN nb_images
+  ';
+pwg_query($query);
+
+invalidate_user_cache(); // just to force recalculation
+
+echo
+"\n"
+.'"'.$upgrade_description.'"'.' ended'
+."\n"
+;
+
+?>
Index: /tags/2.0.2/install/db/7-database.php
===================================================================
--- /tags/2.0.2/install/db/7-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/7-database.php	(revision 3278)
@@ -0,0 +1,65 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'Anonymous rating';
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+
+$query = '
+ALTER TABLE '.PREFIX_TABLE.'rate DROP PRIMARY KEY;'
+;
+pwg_query($query);
+
+$query ='
+ALTER TABLE '.PREFIX_TABLE.'rate ADD COLUMN anonymous_id VARCHAR(45) NOT NULL DEFAULT \'\' AFTER element_id;'
+;
+pwg_query($query);
+
+$query ='
+ALTER TABLE '.PREFIX_TABLE.'rate ADD COLUMN date DATE NOT NULL AFTER rate;'
+;
+pwg_query($query);
+
+$query ='
+UPDATE '.PREFIX_TABLE.'rate SET date=NOW() WHERE date<"1990-01-01";'
+;
+pwg_query($query);
+
+$query = '
+ALTER TABLE '.PREFIX_TABLE.'rate ADD PRIMARY KEY (element_id, user_id, anonymous_id);'
+;
+pwg_query($query);
+
+echo
+"\n"
+.'Table '.PREFIX_TABLE.'rate upgraded'
+."\n"
+;
+?>
Index: /tags/2.0.2/install/db/70-database.php
===================================================================
--- /tags/2.0.2/install/db/70-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/70-database.php	(revision 3278)
@@ -0,0 +1,53 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'Add upload config';
+
+include_once(PHPWG_ROOT_PATH.'include/constants.php');
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+
+$query = "
+replace into ".CONFIG_TABLE."
+  (param, value, comment)
+values
+('upload_link_everytime','false','Show Upload link every time'),
+('upload_user_access',".ACCESS_CLASSIC.",'Minimal user status allowed to upload pictures')
+;";
+
+pwg_query($query);
+
+echo
+"\n"
+.'"'.$upgrade_description.'"'.' ended'
+."\n"
+;
+
+?>
Index: /tags/2.0.2/install/db/71-database.php
===================================================================
--- /tags/2.0.2/install/db/71-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/71-database.php	(revision 3278)
@@ -0,0 +1,58 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'Delete unnecessary #history_summary.id, #history.year, #history.month, #history.day and #history.hour';
+
+include_once(PHPWG_ROOT_PATH.'include/constants.php');
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+
+$query = 'ALTER TABLE '.HISTORY_SUMMARY_TABLE.'
+DROP PRIMARY KEY,
+DROP COLUMN id,
+ADD UNIQUE KEY history_summary_ymdh (`year`, `month`, `day`, `hour`)
+;';
+pwg_query($query);
+
+$query = 'ALTER TABLE '.HISTORY_TABLE.'
+DROP COLUMN year,
+DROP COLUMN month,
+DROP COLUMN day,
+DROP COLUMN hour
+;';
+pwg_query($query);
+
+echo
+"\n"
+.'"'.$upgrade_description.'"'.' ended'
+."\n"
+;
+
+?>
Index: /tags/2.0.2/install/db/72-database.php
===================================================================
--- /tags/2.0.2/install/db/72-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/72-database.php	(revision 3278)
@@ -0,0 +1,48 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'Add extents_for_templates config';
+
+include_once(PHPWG_ROOT_PATH.'include/constants.php');
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+
+$query = "
+INSERT INTO ".CONFIG_TABLE." (param,value,comment) VALUES ('extents_for_templates','a:0:{}','Actived template-extension(s)');
+";
+pwg_query($query);
+
+echo
+"\n"
+.'"'.$upgrade_description.'"'.' ended'
+."\n"
+;
+
+?>
Index: /tags/2.0.2/install/db/73-database.php
===================================================================
--- /tags/2.0.2/install/db/73-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/73-database.php	(revision 3278)
@@ -0,0 +1,46 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'Add #user_cache.cache_update_time';
+
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+
+$query = '
+ALTER TABLE '.USER_CACHE_TABLE.' ADD COLUMN `cache_update_time` INTEGER UNSIGNED NOT NULL DEFAULT 0 AFTER need_update';
+pwg_query($query);
+
+echo
+"\n"
+.'"'.$upgrade_description.'"'.' ended'
+."\n"
+;
+
+?>
Index: /tags/2.0.2/install/db/74-database.php
===================================================================
--- /tags/2.0.2/install/db/74-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/74-database.php	(revision 3278)
@@ -0,0 +1,48 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'Add blk_menubar config';
+
+include_once(PHPWG_ROOT_PATH.'include/constants.php');
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+
+$query = "
+INSERT INTO ".CONFIG_TABLE." (param,value,comment) VALUES ('blk_menubar','','Menubar options');
+";
+pwg_query($query);
+
+echo
+"\n"
+.'"'.$upgrade_description.'"'.' ended'
+."\n"
+;
+
+?>
Index: /tags/2.0.2/install/db/75-database.php
===================================================================
--- /tags/2.0.2/install/db/75-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/75-database.php	(revision 3278)
@@ -0,0 +1,46 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'Add blk_menubar config';
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+
+$query = 'DROP TABLE IF EXISTS '.$prefixeTable.'ws_access';
+pwg_query($query);
+
+$upgrade_description = $query;
+
+echo
+"\n"
+.'"'.$upgrade_description.'"'.' ended'
+."\n"
+;
+
+?>
Index: /tags/2.0.2/install/db/76-database.php
===================================================================
--- /tags/2.0.2/install/db/76-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/76-database.php	(revision 3278)
@@ -0,0 +1,46 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'Add image_category.rank column';
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+
+$query = 'ALTER TABLE '.IMAGE_CATEGORY_TABLE.' add column `rank` mediumint(8) unsigned default NULL';
+pwg_query($query);
+
+$upgrade_description = $query;
+
+echo
+"\n"
+.'"'.$upgrade_description.'"'.' ended'
+."\n"
+;
+
+?>
Index: /tags/2.0.2/install/db/77-database.php
===================================================================
--- /tags/2.0.2/install/db/77-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/77-database.php	(revision 3278)
@@ -0,0 +1,54 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'images.file categories.permalink old_permalinks.permalink - become binary';
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+
+$query = 'ALTER TABLE '.CATEGORIES_TABLE.'
+  MODIFY COLUMN permalink varchar(64) binary default NULL';
+pwg_query($query);
+
+$query = 'ALTER TABLE '.OLD_PERMALINKS_TABLE.'
+  MODIFY COLUMN permalink varchar(64) binary NOT NULL default ""';
+pwg_query($query);
+
+$query = 'ALTER TABLE '.IMAGES_TABLE.'
+  MODIFY COLUMN file varchar(255) binary NOT NULL default ""';
+pwg_query($query);
+
+
+echo
+"\n"
+.'"'.$upgrade_description.'"'.' ended'
+."\n"
+;
+
+?>
Index: /tags/2.0.2/install/db/78-database.php
===================================================================
--- /tags/2.0.2/install/db/78-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/78-database.php	(revision 3278)
@@ -0,0 +1,46 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'Add images.md5sum column, for web API uploaded photos';
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+
+$query = 'ALTER TABLE '.IMAGES_TABLE.' add column `md5sum` char(32) default NULL';
+pwg_query($query);
+
+$upgrade_description = $query;
+
+echo
+"\n"
+.'"'.$upgrade_description.'"'.' ended'
+."\n"
+;
+
+?>
Index: /tags/2.0.2/install/db/79-database.php
===================================================================
--- /tags/2.0.2/install/db/79-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/79-database.php	(revision 3278)
@@ -0,0 +1,47 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'Update default template';
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+
+// set yoga/Sylvia as default value for user_infos.template column
+$query = '
+ALTER TABLE '.PREFIX_TABLE.'user_infos
+  CHANGE COLUMN template template varchar(255) NOT NULL default \'yoga/Sylvia\'
+;';
+pwg_query($query);
+
+echo
+"\n"
+.'Default template modified to yoga/Sylvia'
+."\n"
+;
+?>
Index: /tags/2.0.2/install/db/8-database.php
===================================================================
--- /tags/2.0.2/install/db/8-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/8-database.php	(revision 3278)
@@ -0,0 +1,83 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description = 'Move rate, rate_anonymous and gallery_url from config file to database';
+
+$params = array(
+  'gallery_url' => array('http://demo.phpwebgallery.net','URL given in RSS feed'),
+  'rate' => array('true','Rating pictures feature is enabled') ,
+  'rate_anonymous' => array('true','Rating pictures feature is also enabled for visitors')
+  );
+
+
+
+// +-Get real values from config file--------------------------------------+
+
+$conf_save = $conf;
+unset($conf);
+@include(PHPWG_ROOT_PATH. 'include/config_local.inc.php');
+if ( isset($conf['gallery_url']) )
+{
+  $params['gallery_url'][0] = $conf['gallery_url'];
+}
+if ( isset($conf['rate']) and is_bool($conf['rate']) )
+{
+  $params['rate'][0] = $conf['rate'] ? 'true' : 'false';
+}
+if ( isset($conf['rate_anonymous']) and is_bool($conf['rate_anonymous']) )
+{
+  $params['rate_anonymous'][0] = $conf['rate_anonymous'] ? 'true' : 'false';
+}
+$conf = $conf_save;
+
+
+
+// +-Do I already have them in DB ?----------------------------------------+
+$query = 'SELECT param FROM '.PREFIX_TABLE.'config';
+$result = pwg_query($query);
+while ($row = mysql_fetch_array($result))
+{
+  unset( $params[ $row['param'] ] );
+}
+
+// +-Perform the insert query----------------------------------------------+
+foreach ($params as $param_key => $param_values)
+{
+  $query = '
+INSERT INTO '.PREFIX_TABLE.'config (param,value,comment) VALUES (' .
+"'$param_key','$param_values[0]','$param_values[1]');";
+  pwg_query($query);
+}
+
+
+echo
+"\n"
+.'Table '.PREFIX_TABLE.'config upgraded'
+."\n"
+;
+?>
Index: /tags/2.0.2/install/db/9-database.php
===================================================================
--- /tags/2.0.2/install/db/9-database.php	(revision 3278)
+++ /tags/2.0.2/install/db/9-database.php	(revision 3278)
@@ -0,0 +1,86 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$upgrade_description =
+  'Column #image_category.is_storage replaces #images.storage_category_id';
+
+// +-----------------------------------------------------------------------+
+// |                            Upgrade content                            |
+// +-----------------------------------------------------------------------+
+
+$query = "
+ALTER TABLE ".PREFIX_TABLE."image_category
+  ADD COLUMN is_storage ENUM('true','false') DEFAULT 'false'
+;";
+pwg_query($query);
+
+$query = '
+SELECT id, storage_category_id
+  FROM '.PREFIX_TABLE.'images
+;';
+$result = pwg_query($query);
+
+$datas = array();
+
+while ($row = mysql_fetch_array($result))
+{
+  array_push(
+    $datas,
+    array(
+      'image_id'    => $row['id'],
+      'category_id' => $row['storage_category_id'],
+      'is_storage'  => 'true',
+      )
+    );
+}
+
+mass_updates(
+  PREFIX_TABLE.'image_category',
+  array(
+    'primary' => array('image_id', 'category_id'),
+    'update'  => array('is_storage')
+    ),
+  $datas
+  );
+
+$query = '
+ALTER TABLE '.PREFIX_TABLE.'images
+  DROP COLUMN storage_category_id
+;';
+pwg_query($query);
+
+// +-----------------------------------------------------------------------+
+// |                           End notification                            |
+// +-----------------------------------------------------------------------+
+
+echo
+"\n"
+.'Column '.PREFIX_TABLE.'image_category.is_storage created and filled'
+."\n"
+;
+?>
Index: /tags/2.0.2/install/db/index.php
===================================================================
--- /tags/2.0.2/install/db/index.php	(revision 3278)
+++ /tags/2.0.2/install/db/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/install/hosting.php
===================================================================
--- /tags/2.0.2/install/hosting.php	(revision 3278)
+++ /tags/2.0.2/install/hosting.php	(revision 3278)
@@ -0,0 +1,59 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+
+/* PHP5 configuration for known servers */
+$hosting = array(
+
+  //1and1
+    'kundenserver.de' => 'AddType x-mapp-php5 .php',
+
+  //Apinc
+    'apinc.org' => 'AddHandler x-httpd-php5 .php',
+
+  //Free
+    'free.fr' => 'php 1',
+
+  //Lost Oasis
+    'lost-oasis.net' => 'PHP_Version 5.0',
+    'lo-data.net' => 'PHP_Version 5.0',
+
+  //MediaTemple
+    'gridserver.com' => 'AddHandler php5-script .php',
+
+  //Online
+    'online.net' => 'AddType application/x-httpd-php5 .php',
+
+  //Ouvaton
+    'web.ocsa-data.net' => 'AddHandler application/x-suexec-php5 .php',
+
+  //OVH
+    'ovh.net' => 'SetEnv PHP_VER 5',
+
+  //Strato
+    'rzone.de' => 'AddType application/x-httpd-php5 .php',
+
+  //Web1.fr - NFrance
+    'nfrance.com' => 'AddHandler php-fastcgi5 .php',
+);
+?>
Index: /tags/2.0.2/install/index.php
===================================================================
--- /tags/2.0.2/install/index.php	(revision 3278)
+++ /tags/2.0.2/install/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/install/php5_apache_configuration.php
===================================================================
--- /tags/2.0.2/install/php5_apache_configuration.php	(revision 3278)
+++ /tags/2.0.2/install/php5_apache_configuration.php	(revision 3278)
@@ -0,0 +1,170 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+$script = script_basename();
+
+if (($script != 'install' and $script != 'upgrade')
+  or version_compare(PHP_VERSION, REQUIRED_PHP_VERSION, '>='))
+{
+  die('Nothing to do here...');
+}
+
+function initPHP5()
+{
+  include(PHPWG_ROOT_PATH.'install/hosting.php');
+  $htaccess = PHPWG_ROOT_PATH.'.htaccess';
+  
+  if ((file_exists($htaccess) and (!is_readable($htaccess) or !is_writable($htaccess)))
+    or !($my_hostname = @gethostbyaddr($_SERVER['SERVER_ADDR'])))
+  {
+    return false;
+  }
+
+  foreach ($hosting as $hostname => $rule)
+  {
+    if (preg_match('!'.preg_quote($hostname).'$!',$my_hostname))
+    {
+      if (false !== ($fh = @fopen($htaccess,"ab")))
+      {
+        fwrite($fh,"\n".$rule);
+        fclose($fh);
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
+function openPage()
+{
+  global $script;
+
+  $title = 'Piwigo '.PHPWG_VERSION.' - '.l10n(ucwords($script));
+
+  header('Content-Type: text/html; charset=UTF-8');
+
+  echo '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<meta http-equiv="Content-script-type" content="text/javascript">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<link rel="shortcut icon" type="image/x-icon" href="template-common/favicon.ico">
+<link rel="stylesheet" type="text/css" href="admin/template/goto/layout.css">
+<link rel="stylesheet" type="text/css" href="admin/template/goto/default-colors.css">
+<link rel="stylesheet" type="text/css" href="admin/template/goto/theme/roma/theme.css">
+<style type="text/css">
+.content {
+  width: 800px;
+  min-height: 0px !important;
+  margin: auto;
+  padding: 25px;
+  text-align: left;
+}
+
+table { margin: 0 0 15px 0; }
+td {  padding: 3px 10px; }
+h1 { text-align: left; }
+</style>
+<title>'.$title.'</title>
+</head>
+
+<body>
+<div id="headbranch"></div>
+<div id="the_page">
+<div id="theHeader"></div>
+<div id="content" class="content">
+
+<h2>'.$title.'</h2>';
+}
+
+function closePage()
+{
+  echo '
+</div>
+<div style="text-align: center">'.sprintf(l10n('install_help'), PHPWG_URL.'/forum').'</div>
+</div>
+</body>
+</html>';
+}
+
+if (isset($_GET['setphp5']))
+{
+  // Try to configure php5
+  if (initPHP5())
+  {
+    header('Location: '.$script.'.php?language='.$language);
+  }
+  else
+  {
+    openPage();
+    echo '
+<h1>'.l10n('Sorry!').'</h1>
+<p>
+'.l10n('Piwigo was not able to configure PHP 5.').'<br>
+'.l10n("You may referer to your hosting provider's support and see how you could switch to PHP 5 by yourself.").'<br>
+'.l10n('Hope to see you back soon.').'
+</p>';
+    closePage();
+  }
+}
+else
+{
+  openPage();
+  echo '
+  <table>
+  <tr>
+    <td>'.l10n('language').'</td>
+    <td>
+      <select name="language" onchange="document.location = \''.$script.'.php?language=\'+this.options[this.selectedIndex].value;">';
+  foreach (get_languages('utf-8') as $code => $name)
+  {
+    echo '
+      <option label="'.$name.'" value="'.$code.'" '.($code == $language ? 'selected="selected"' : '') .'>'.$name.'</option>';
+  }
+  echo '
+      </select>
+    </td>
+  </tr>
+</table>
+
+<h1>'.l10n('PHP 5 is required').'</h1>
+<p>
+'.sprintf(l10n('It appears your webhost is currently running PHP %s.'), PHP_VERSION).'<br>
+'.l10n('Piwigo may try to switch your configuration to PHP 5 by creating or modifying a .htaccess file.').'<br>
+'.l10n('Note you can change your configuration by yourself and restart Piwigo after that.').'<br>
+</p>
+<p style="text-align: center;"><br>
+<input type="button" value="'.l10n('Try to configure PHP 5').'" onClick="document.location = \''.$script.'.php?language='.$language.'&amp;setphp5=\';">
+</p>';
+  closePage();
+}
+
+exit();
+?>
Index: /tags/2.0.2/install/piwigo_structure.sql
===================================================================
--- /tags/2.0.2/install/piwigo_structure.sql	(revision 3278)
+++ /tags/2.0.2/install/piwigo_structure.sql	(revision 3278)
@@ -0,0 +1,441 @@
+-- MySQL dump 9.11
+--
+-- Host: localhost    Database: pwg-bsf
+-- ------------------------------------------------------
+-- Server version	4.0.24_Debian-10-log
+
+--
+-- Table structure for table `piwigo_caddie`
+--
+
+DROP TABLE IF EXISTS `piwigo_caddie`;
+CREATE TABLE `piwigo_caddie` (
+  `user_id` smallint(5) NOT NULL default '0',
+  `element_id` mediumint(8) NOT NULL default '0',
+  PRIMARY KEY  (`user_id`,`element_id`)
+) TYPE=MyISAM;
+
+--
+-- Table structure for table `piwigo_categories`
+--
+
+DROP TABLE IF EXISTS `piwigo_categories`;
+CREATE TABLE `piwigo_categories` (
+  `id` smallint(5) unsigned NOT NULL auto_increment,
+  `name` varchar(255) NOT NULL default '',
+  `id_uppercat` smallint(5) unsigned default NULL,
+  `comment` text,
+  `dir` varchar(255) default NULL,
+  `rank` smallint(5) unsigned default NULL,
+  `status` enum('public','private') NOT NULL default 'public',
+  `site_id` tinyint(4) unsigned default '1',
+  `visible` enum('true','false') NOT NULL default 'true',
+  `uploadable` enum('true','false') NOT NULL default 'false',
+  `representative_picture_id` mediumint(8) unsigned default NULL,
+  `uppercats` varchar(255) NOT NULL default '',
+  `commentable` enum('true','false') NOT NULL default 'true',
+  `global_rank` varchar(255) default NULL,
+  `image_order` varchar(128) default NULL,
+  `permalink` varchar(64) binary default NULL,
+  PRIMARY KEY  (`id`),
+  UNIQUE KEY `categories_i3` (`permalink`),
+  KEY `categories_i2` (`id_uppercat`)
+) TYPE=MyISAM;
+
+--
+-- Table structure for table `piwigo_comments`
+--
+
+DROP TABLE IF EXISTS `piwigo_comments`;
+CREATE TABLE `piwigo_comments` (
+  `id` int(11) unsigned NOT NULL auto_increment,
+  `image_id` mediumint(8) unsigned NOT NULL default '0',
+  `date` datetime NOT NULL default '0000-00-00 00:00:00',
+  `author` varchar(255) default NULL,
+  `content` longtext,
+  `validated` enum('true','false') NOT NULL default 'false',
+  `validation_date` datetime default NULL,
+  PRIMARY KEY  (`id`),
+  KEY `comments_i2` (`validation_date`),
+  KEY `comments_i1` (`image_id`)
+) TYPE=MyISAM;
+
+--
+-- Table structure for table `piwigo_config`
+--
+
+DROP TABLE IF EXISTS `piwigo_config`;
+CREATE TABLE `piwigo_config` (
+  `param` varchar(40) NOT NULL default '',
+  `value` text,
+  `comment` varchar(255) default NULL,
+  PRIMARY KEY  (`param`)
+) TYPE=MyISAM COMMENT='configuration table';
+
+--
+-- Table structure for table `piwigo_favorites`
+--
+
+DROP TABLE IF EXISTS `piwigo_favorites`;
+CREATE TABLE `piwigo_favorites` (
+  `user_id` smallint(5) NOT NULL default '0',
+  `image_id` mediumint(8) unsigned NOT NULL default '0',
+  PRIMARY KEY  (`user_id`,`image_id`)
+) TYPE=MyISAM;
+
+--
+-- Table structure for table `piwigo_group_access`
+--
+
+DROP TABLE IF EXISTS `piwigo_group_access`;
+CREATE TABLE `piwigo_group_access` (
+  `group_id` smallint(5) unsigned NOT NULL default '0',
+  `cat_id` smallint(5) unsigned NOT NULL default '0',
+  PRIMARY KEY  (`group_id`,`cat_id`)
+) TYPE=MyISAM;
+
+--
+-- Table structure for table `piwigo_groups`
+--
+
+DROP TABLE IF EXISTS `piwigo_groups`;
+CREATE TABLE `piwigo_groups` (
+  `id` smallint(5) unsigned NOT NULL auto_increment,
+  `name` varchar(255) NOT NULL default '',
+  `is_default` enum('true','false') NOT NULL default 'false',
+  PRIMARY KEY  (`id`),
+  UNIQUE KEY `groups_ui1` (`name`)
+) TYPE=MyISAM;
+
+--
+-- Table structure for table `piwigo_history`
+--
+
+DROP TABLE IF EXISTS `piwigo_history`;
+CREATE TABLE `piwigo_history` (
+  `id` int(10) unsigned NOT NULL auto_increment,
+  `date` date NOT NULL default '0000-00-00',
+  `time` time NOT NULL default '00:00:00',
+  `user_id` smallint(5) NOT NULL default '0',
+  `IP` varchar(15) NOT NULL default '',
+  `section` enum('categories','tags','search','list','favorites','most_visited','best_rated','recent_pics','recent_cats') default NULL,
+  `category_id` smallint(5) default NULL,
+  `tag_ids` varchar(50) default NULL,
+  `image_id` mediumint(8) default NULL,
+  `summarized` enum('true','false') default 'false',
+  `image_type` enum('picture','high','other') default NULL,
+  PRIMARY KEY  (`id`),
+  KEY `history_i1` (`summarized`)
+) TYPE=MyISAM;
+
+--
+-- Table structure for table `piwigo_history_summary`
+--
+
+DROP TABLE IF EXISTS `piwigo_history_summary`;
+CREATE TABLE `piwigo_history_summary` (
+  `year` smallint(4) NOT NULL default '0',
+  `month` tinyint(2) default NULL,
+  `day` tinyint(2) default NULL,
+  `hour` tinyint(2) default NULL,
+  `nb_pages` int(11) default NULL,
+  UNIQUE KEY history_summary_ymdh (`year`,`month`,`day`,`hour`)
+) TYPE=MyISAM;
+
+--
+-- Table structure for table `piwigo_image_category`
+--
+
+DROP TABLE IF EXISTS `piwigo_image_category`;
+CREATE TABLE `piwigo_image_category` (
+  `image_id` mediumint(8) unsigned NOT NULL default '0',
+  `category_id` smallint(5) unsigned NOT NULL default '0',
+  `rank` mediumint(8) unsigned default NULL,
+  PRIMARY KEY  (`image_id`,`category_id`),
+  KEY `image_category_i1` (`category_id`)
+) TYPE=MyISAM;
+
+--
+-- Table structure for table `piwigo_image_tag`
+--
+
+DROP TABLE IF EXISTS `piwigo_image_tag`;
+CREATE TABLE `piwigo_image_tag` (
+  `image_id` mediumint(8) unsigned NOT NULL default '0',
+  `tag_id` smallint(5) unsigned NOT NULL default '0',
+  PRIMARY KEY  (`image_id`,`tag_id`),
+  KEY `image_tag_i1` (`tag_id`)
+) TYPE=MyISAM;
+
+--
+-- Table structure for table `piwigo_images`
+--
+
+DROP TABLE IF EXISTS `piwigo_images`;
+CREATE TABLE `piwigo_images` (
+  `id` mediumint(8) unsigned NOT NULL auto_increment,
+  `file` varchar(255) binary NOT NULL default '',
+  `date_available` datetime NOT NULL default '0000-00-00 00:00:00',
+  `date_creation` date default NULL,
+  `tn_ext` varchar(4) default '',
+  `name` varchar(255) default NULL,
+  `comment` text,
+  `author` varchar(255) default NULL,
+  `hit` int(10) unsigned NOT NULL default '0',
+  `filesize` mediumint(9) unsigned default NULL,
+  `width` smallint(9) unsigned default NULL,
+  `height` smallint(9) unsigned default NULL,
+  `representative_ext` varchar(4) default NULL,
+  `date_metadata_update` date default NULL,
+  `average_rate` float(5,2) unsigned default NULL,
+  `has_high` enum('true') default NULL,
+  `path` varchar(255) NOT NULL default '',
+  `storage_category_id` smallint(5) unsigned default NULL,
+  `high_filesize` mediumint(9) unsigned default NULL,
+  `level` tinyint unsigned NOT NULL default '0',
+  `md5sum` char(32) default NULL,
+  PRIMARY KEY  (`id`),
+  KEY `images_i2` (`date_available`),
+  KEY `images_i3` (`average_rate`),
+  KEY `images_i4` (`hit`),
+  KEY `images_i5` (`date_creation`),
+  KEY `images_i1` (`storage_category_id`)
+) TYPE=MyISAM;
+
+--
+-- Table structure for table `piwigo_old_permalinks`
+--
+
+DROP TABLE IF EXISTS `piwigo_old_permalinks`;
+CREATE TABLE `piwigo_old_permalinks` (
+  `cat_id` smallint(5) unsigned NOT NULL default '0',
+  `permalink` varchar(64) binary NOT NULL default '',
+  `date_deleted` datetime NOT NULL default '0000-00-00 00:00:00',
+  `last_hit` datetime default NULL,
+  `hit` int(10) unsigned NOT NULL default '0',
+  PRIMARY KEY  (`permalink`)
+) TYPE=MyISAM;
+
+--
+-- Table structure for table `piwigo_plugins`
+--
+
+DROP TABLE IF EXISTS `piwigo_plugins`;
+CREATE TABLE `piwigo_plugins` (
+  `id` varchar(64) binary NOT NULL default '',
+  `state` enum('inactive','active') NOT NULL default 'inactive',
+  `version` varchar(64) NOT NULL default '0',
+  PRIMARY KEY  (`id`)
+) TYPE=MyISAM;
+
+--
+-- Table structure for table `piwigo_rate`
+--
+
+DROP TABLE IF EXISTS `piwigo_rate`;
+CREATE TABLE `piwigo_rate` (
+  `user_id` smallint(5) NOT NULL default '0',
+  `element_id` mediumint(8) unsigned NOT NULL default '0',
+  `anonymous_id` varchar(45) NOT NULL default '',
+  `rate` tinyint(2) unsigned NOT NULL default '0',
+  `date` date NOT NULL default '0000-00-00',
+  PRIMARY KEY  (`element_id`,`user_id`,`anonymous_id`)
+) TYPE=MyISAM;
+
+--
+-- Table structure for table `piwigo_search`
+--
+
+DROP TABLE IF EXISTS `piwigo_search`;
+CREATE TABLE `piwigo_search` (
+  `id` int(10) unsigned NOT NULL auto_increment,
+  `last_seen` date default NULL,
+  `rules` text,
+  PRIMARY KEY  (`id`)
+) TYPE=MyISAM;
+
+--
+-- Table structure for table `piwigo_sessions`
+--
+
+DROP TABLE IF EXISTS `piwigo_sessions`;
+CREATE TABLE `piwigo_sessions` (
+  `id` varchar(255) binary NOT NULL default '',
+  `data` mediumtext NOT NULL,
+  `expiration` datetime NOT NULL default '0000-00-00 00:00:00',
+  PRIMARY KEY  (`id`)
+) TYPE=MyISAM;
+
+--
+-- Table structure for table `piwigo_sites`
+--
+
+DROP TABLE IF EXISTS `piwigo_sites`;
+CREATE TABLE `piwigo_sites` (
+  `id` tinyint(4) NOT NULL auto_increment,
+  `galleries_url` varchar(255) NOT NULL default '',
+  PRIMARY KEY  (`id`),
+  UNIQUE KEY `sites_ui1` (`galleries_url`)
+) TYPE=MyISAM;
+
+--
+-- Table structure for table `piwigo_tags`
+--
+
+DROP TABLE IF EXISTS `piwigo_tags`;
+CREATE TABLE `piwigo_tags` (
+  `id` smallint(5) unsigned NOT NULL auto_increment,
+  `name` varchar(255) binary NOT NULL default '',
+  `url_name` varchar(255) binary NOT NULL default '',
+  PRIMARY KEY  (`id`),
+  KEY `tags_i1` (`url_name`)
+) TYPE=MyISAM;
+
+--
+-- Table structure for table `piwigo_upgrade`
+--
+
+DROP TABLE IF EXISTS `piwigo_upgrade`;
+CREATE TABLE `piwigo_upgrade` (
+  `id` varchar(20) NOT NULL default '',
+  `applied` datetime NOT NULL default '0000-00-00 00:00:00',
+  `description` varchar(255) default NULL,
+  PRIMARY KEY  (`id`)
+) TYPE=MyISAM;
+
+--
+-- Table structure for table `piwigo_user_access`
+--
+
+DROP TABLE IF EXISTS `piwigo_user_access`;
+CREATE TABLE `piwigo_user_access` (
+  `user_id` smallint(5) NOT NULL default '0',
+  `cat_id` smallint(5) unsigned NOT NULL default '0',
+  PRIMARY KEY  (`user_id`,`cat_id`)
+) TYPE=MyISAM;
+
+--
+-- Table structure for table `piwigo_user_cache`
+--
+
+DROP TABLE IF EXISTS `piwigo_user_cache`;
+CREATE TABLE `piwigo_user_cache` (
+  `user_id` smallint(5) NOT NULL default '0',
+  `need_update` enum('true','false') NOT NULL default 'true',
+  `cache_update_time` integer unsigned NOT NULL default 0,
+  `forbidden_categories` mediumtext,
+  `nb_total_images` mediumint(8) unsigned default NULL,
+  `image_access_type` enum('NOT IN','IN') NOT NULL default 'NOT IN',
+  `image_access_list` mediumtext default NULL,
+  PRIMARY KEY  (`user_id`)
+) TYPE=MyISAM;
+
+--
+-- Table structure for table `piwigo_user_cache_categories`
+--
+
+DROP TABLE IF EXISTS `piwigo_user_cache_categories`;
+CREATE TABLE `piwigo_user_cache_categories` (
+  `user_id` smallint(5) NOT NULL default '0',
+  `cat_id` smallint(5) unsigned NOT NULL default '0',
+  `date_last` datetime default NULL,
+  `max_date_last` datetime default NULL,
+  `nb_images` mediumint(8) unsigned NOT NULL default '0',
+  `count_images` mediumint(8) unsigned default '0',
+  `count_categories` mediumint(8) unsigned default '0',
+  PRIMARY KEY  (`user_id`,`cat_id`)
+) TYPE=MyISAM;
+
+--
+-- Table structure for table `piwigo_user_feed`
+--
+
+DROP TABLE IF EXISTS `piwigo_user_feed`;
+CREATE TABLE `piwigo_user_feed` (
+  `id` varchar(50) binary NOT NULL default '',
+  `user_id` smallint(5) NOT NULL default '0',
+  `last_check` datetime default NULL,
+  PRIMARY KEY  (`id`)
+) TYPE=MyISAM;
+
+--
+-- Table structure for table `piwigo_user_group`
+--
+
+DROP TABLE IF EXISTS `piwigo_user_group`;
+CREATE TABLE `piwigo_user_group` (
+  `user_id` smallint(5) NOT NULL default '0',
+  `group_id` smallint(5) unsigned NOT NULL default '0',
+  PRIMARY KEY  (`group_id`,`user_id`)
+) TYPE=MyISAM;
+
+--
+-- Table structure for table `piwigo_user_infos`
+--
+
+DROP TABLE IF EXISTS `piwigo_user_infos`;
+CREATE TABLE `piwigo_user_infos` (
+  `user_id` smallint(5) NOT NULL default '0',
+  `nb_image_line` tinyint(1) unsigned NOT NULL default '5',
+  `nb_line_page` tinyint(3) unsigned NOT NULL default '3',
+  `status` enum('webmaster','admin','normal','generic','guest') NOT NULL default 'guest',
+  `adviser` enum('true','false') NOT NULL default 'false',
+  `language` varchar(50) NOT NULL default 'en_UK',
+  `maxwidth` smallint(6) default NULL,
+  `maxheight` smallint(6) default NULL,
+  `expand` enum('true','false') NOT NULL default 'false',
+  `show_nb_comments` enum('true','false') NOT NULL default 'false',
+  `show_nb_hits` enum('true','false') NOT NULL default 'false',
+  `recent_period` tinyint(3) unsigned NOT NULL default '7',
+  `template` varchar(255) NOT NULL default 'yoga/Sylvia',
+  `registration_date` datetime NOT NULL default '0000-00-00 00:00:00',
+  `enabled_high` enum('true','false') NOT NULL default 'true',
+  `level` tinyint unsigned NOT NULL default '0',
+  UNIQUE KEY `user_infos_ui1` (`user_id`)
+) TYPE=MyISAM;
+
+--
+-- Table structure for table `piwigo_user_mail_notification`
+--
+
+DROP TABLE IF EXISTS `piwigo_user_mail_notification`;
+CREATE TABLE `piwigo_user_mail_notification` (
+  `user_id` smallint(5) NOT NULL default '0',
+  `check_key` varchar(16) binary NOT NULL default '',
+  `enabled` enum('true','false') NOT NULL default 'false',
+  `last_send` datetime default NULL,
+  PRIMARY KEY  (`user_id`),
+  UNIQUE KEY `user_mail_notification_ui1` (`check_key`)
+) TYPE=MyISAM;
+
+--
+-- Table structure for table `piwigo_users`
+--
+
+DROP TABLE IF EXISTS `piwigo_users`;
+CREATE TABLE `piwigo_users` (
+  `id` smallint(5) NOT NULL auto_increment,
+  `username` varchar(100) binary NOT NULL default '',
+  `password` varchar(32) default NULL,
+  `mail_address` varchar(255) default NULL,
+  PRIMARY KEY  (`id`),
+  UNIQUE KEY `users_ui1` (`username`)
+) TYPE=MyISAM;
+
+--
+-- Table structure for table `piwigo_waiting`
+--
+
+DROP TABLE IF EXISTS `piwigo_waiting`;
+CREATE TABLE `piwigo_waiting` (
+  `id` int(10) unsigned NOT NULL auto_increment,
+  `storage_category_id` smallint(5) unsigned NOT NULL default '0',
+  `file` varchar(255) NOT NULL default '',
+  `username` varchar(255) NOT NULL default '',
+  `mail_address` varchar(255) NOT NULL default '',
+  `date` int(10) unsigned NOT NULL default '0',
+  `tn_ext` char(3) default NULL,
+  `validated` enum('true','false') NOT NULL default 'false',
+  `infos` text,
+  PRIMARY KEY  (`id`)
+) TYPE=MyISAM;
Index: /tags/2.0.2/install/upgrade_1.3.0.php
===================================================================
--- /tags/2.0.2/install/upgrade_1.3.0.php	(revision 3278)
+++ /tags/2.0.2/install/upgrade_1.3.0.php	(revision 3278)
@@ -0,0 +1,126 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+
+/**
+ * Upgrade from 1.3.0 to 1.3.1
+ */
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die ('This page cannot be loaded directly, load upgrade.php');
+}
+else
+{
+  if (!defined('PHPWG_IN_UPGRADE') or !PHPWG_IN_UPGRADE)
+  {
+    die ('Hacking attempt!');
+  }
+}
+
+$queries = array(
+  "
+ALTER TABLE phpwebgallery_categories
+  ADD COLUMN uppercats varchar(255) NOT NULL default ''
+;",
+
+  "
+CREATE TABLE phpwebgallery_user_category (
+  user_id smallint(5) unsigned NOT NULL default '0'
+)
+;",
+
+  "
+ALTER TABLE phpwebgallery_categories
+  ADD INDEX id (id)
+;",
+
+  "
+ALTER TABLE phpwebgallery_categories
+  ADD INDEX id_uppercat (id_uppercat)
+;",
+
+  "
+ALTER TABLE phpwebgallery_image_category
+  ADD INDEX category_id (category_id)
+;",
+
+  "
+ALTER TABLE phpwebgallery_image_category
+  ADD INDEX image_id (image_id)
+;",
+  );
+
+foreach ($queries as $query)
+{
+  $query = str_replace('phpwebgallery_', PREFIX_TABLE, $query);
+  pwg_query($query);
+}
+// filling the new column categories.uppercats
+$id_uppercats = array();
+
+$query = '
+SELECT id, id_uppercat
+  FROM '.CATEGORIES_TABLE.'
+;';
+$result = pwg_query($query);
+while ($row = mysql_fetch_array($result))
+{
+  if (!isset($row['id_uppercat']) or $row['id_uppercat'] == '')
+  {
+    $row['id_uppercat'] = 'NULL';
+  }
+  $id_uppercats[$row['id']] = $row['id_uppercat'];
+}
+
+$datas = array();
+
+foreach (array_keys($id_uppercats) as $id)
+{
+  $data = array();
+  $data['id'] = $id;
+  $uppercats = array();
+  
+  array_push($uppercats, $id);
+  while (isset($id_uppercats[$id]) and $id_uppercats[$id] != 'NULL')
+  {
+    array_push($uppercats, $id_uppercats[$id]);
+    $id = $id_uppercats[$id];
+  }
+  $data['uppercats'] = implode(',', array_reverse($uppercats));
+
+  array_push($datas, $data);
+}
+
+mass_updates(
+  CATEGORIES_TABLE,
+  array(
+    'primary' => array('id'),
+    'update' => array('uppercats')
+    ),
+  $datas
+  );
+
+// now we upgrade from 1.3.1 to 1.6.0
+include_once(PHPWG_ROOT_PATH.'install/upgrade_1.3.1.php');
+?>
Index: /tags/2.0.2/install/upgrade_1.3.1.php
===================================================================
--- /tags/2.0.2/install/upgrade_1.3.1.php	(revision 3278)
+++ /tags/2.0.2/install/upgrade_1.3.1.php	(revision 3278)
@@ -0,0 +1,613 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+/**
+ * Upgrade from 1.3.x (x >= 1) to 1.4.0
+ */
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die ('This page cannot be loaded directly, load upgrade.php');
+}
+else
+{
+  if (!defined('PHPWG_IN_UPGRADE') or !PHPWG_IN_UPGRADE)
+  {
+    die ('Hacking attempt!');
+  }
+}
+
+// save data before deletion
+$query = '
+SELECT prefix_thumbnail, mail_webmaster
+  FROM '.PREFIX_TABLE.'config
+;';
+$save = mysql_fetch_array(pwg_query($query));
+
+$queries = array(
+  "
+DROP TABLE phpwebgallery_config
+;",
+
+  "
+CREATE TABLE phpwebgallery_config (
+  param varchar(40) NOT NULL default '',
+  value varchar(255) default NULL,
+  comment varchar(255) default NULL,
+  PRIMARY KEY  (param)
+) TYPE=MyISAM COMMENT='configuration table'
+;",
+
+  "
+ALTER TABLE phpwebgallery_categories
+  CHANGE COLUMN site_id site_id tinyint(4) unsigned default '1'
+;",
+
+  "
+ALTER TABLE phpwebgallery_categories
+  ADD COLUMN commentable enum('true','false') NOT NULL default 'true'
+;",
+
+  "
+ALTER TABLE phpwebgallery_categories
+  ADD COLUMN global_rank varchar(255) default NULL
+;",
+
+  "
+ALTER TABLE phpwebgallery_categories
+  ADD INDEX categories_i2 (id_uppercat)
+;",
+
+  "
+ALTER TABLE phpwebgallery_comments
+  ADD COLUMN date_temp int(11) unsigned
+;",
+
+  "
+UPDATE phpwebgallery_comments
+  SET date_temp = date
+;",
+
+  "
+ALTER TABLE phpwebgallery_comments
+  CHANGE COLUMN date date datetime NOT NULL default '0000-00-00 00:00:00'
+;",
+
+  "
+UPDATE phpwebgallery_comments
+  SET date = FROM_UNIXTIME(date_temp)
+;",
+
+  "
+ALTER TABLE phpwebgallery_comments
+  DROP COLUMN date_temp
+;",
+
+  "
+ALTER TABLE phpwebgallery_favorites
+  DROP INDEX user_id
+;",
+
+  "
+ALTER TABLE phpwebgallery_favorites
+  ADD PRIMARY KEY (user_id,image_id)
+;",
+
+  "
+ALTER TABLE phpwebgallery_history
+  ADD COLUMN date_temp int(11) unsigned
+;",
+
+  "
+UPDATE phpwebgallery_history
+  SET date_temp = date
+;",
+
+  "
+ALTER TABLE phpwebgallery_history
+  CHANGE COLUMN date date datetime NOT NULL default '0000-00-00 00:00:00'
+;",
+
+  "
+UPDATE phpwebgallery_history
+  SET date = FROM_UNIXTIME(date_temp)
+;",
+
+  "
+ALTER TABLE phpwebgallery_history
+  DROP COLUMN date_temp
+;",
+
+  "
+ALTER TABLE phpwebgallery_history
+  ADD INDEX history_i1 (date)
+;",
+
+  "
+ALTER TABLE phpwebgallery_image_category
+  ADD INDEX image_category_i1 (image_id),
+  ADD INDEX image_category_i2 (category_id)
+;",
+
+  "
+ALTER TABLE phpwebgallery_images
+  CHANGE COLUMN tn_ext tn_ext varchar(4) default ''
+;",
+
+  "
+ALTER TABLE phpwebgallery_images
+  ADD COLUMN path varchar(255) NOT NULL default ''
+;",
+
+  "
+ALTER TABLE phpwebgallery_images
+  ADD COLUMN date_metadata_update date default NULL
+;",
+
+  "
+ALTER TABLE phpwebgallery_images
+  ADD COLUMN average_rate float(5,2) unsigned default NULL
+;",
+
+  "
+ALTER TABLE phpwebgallery_images
+  ADD COLUMN representative_ext varchar(4) default NULL
+;",
+
+  "
+ALTER TABLE phpwebgallery_images
+  DROP INDEX storage_category_id
+;",
+
+  "
+ALTER TABLE phpwebgallery_images
+  ADD INDEX images_i1 (storage_category_id)
+;",
+
+  "
+ALTER TABLE phpwebgallery_images
+  ADD INDEX images_i2 (date_available)
+;",
+
+  "
+ALTER TABLE phpwebgallery_images
+  ADD INDEX images_i3 (average_rate)
+;",
+
+  "
+ALTER TABLE phpwebgallery_images
+  ADD INDEX images_i4 (hit)
+;",
+
+  "
+ALTER TABLE phpwebgallery_images
+  ADD INDEX images_i5 (date_creation)
+;",
+
+  "
+ALTER TABLE phpwebgallery_sessions
+  DROP COLUMN ip
+;",
+
+    "
+ALTER TABLE phpwebgallery_sessions
+  ADD COLUMN expiration_temp int(11) unsigned
+;",
+
+  "
+UPDATE phpwebgallery_sessions
+  SET expiration_temp = expiration
+;",
+
+  "
+ALTER TABLE phpwebgallery_sessions
+  CHANGE COLUMN expiration expiration datetime NOT NULL default '0000-00-00 00:00:00'
+;",
+
+  "
+UPDATE phpwebgallery_sessions
+  SET expiration = FROM_UNIXTIME(expiration_temp)
+;",
+
+  "
+ALTER TABLE phpwebgallery_sessions
+  DROP COLUMN expiration_temp
+;",
+
+  "
+ALTER TABLE phpwebgallery_sites
+  DROP INDEX galleries_url
+;",
+
+  "
+ALTER TABLE phpwebgallery_sites
+  ADD UNIQUE sites_ui1 (galleries_url)
+;",
+
+  "
+DROP TABLE phpwebgallery_user_category
+;",
+
+  "
+ALTER TABLE phpwebgallery_users
+  DROP COLUMN long_period
+;",
+
+  "
+ALTER TABLE phpwebgallery_users
+  DROP COLUMN short_period
+;",
+
+  "
+ALTER TABLE phpwebgallery_users
+  ADD COLUMN recent_period tinyint(3) unsigned NOT NULL default '7'
+;",
+
+  "
+ALTER TABLE phpwebgallery_users
+  DROP INDEX username
+;",
+
+  "
+ALTER TABLE phpwebgallery_users
+  ADD UNIQUE users_ui1 (username)
+;",
+
+  "
+CREATE TABLE phpwebgallery_rate (
+  user_id smallint(5) unsigned NOT NULL default '0',
+  element_id mediumint(8) unsigned NOT NULL default '0',
+  rate tinyint(2) unsigned NOT NULL default '0',
+  PRIMARY KEY  (user_id,element_id)
+) TYPE=MyISAM
+;",
+
+  "
+CREATE TABLE phpwebgallery_user_forbidden (
+  user_id smallint(5) unsigned NOT NULL default '0',
+  need_update enum('true','false') NOT NULL default 'true',
+  forbidden_categories text,
+  PRIMARY KEY  (user_id)
+) TYPE=MyISAM
+;",
+
+  "
+UPDATE phpwebgallery_users
+  SET language = 'en_UK.iso-8859-1'
+    , template = 'default'
+;",
+
+  "
+DELETE FROM phpwebgallery_user_access
+;",
+
+  "
+DELETE FROM phpwebgallery_group_access
+;"
+
+  );
+
+foreach ($queries as $query)
+{
+  $query = str_replace('phpwebgallery_', PREFIX_TABLE, $query);
+  pwg_query($query);
+}
+
+//
+// check indexes
+//
+$indexes_of = array(
+  'categories' => array(
+    'categories_i2' => array(
+      'columns' => array('id_uppercat'),
+      'unique' => false,
+      )
+    ),
+  'image_category' => array(
+    'image_category_i1' => array(
+      'columns' => array('image_id'),
+      'unique' => false,
+      ),
+    'image_category_i2' => array(
+      'columns' => array('category_id'),
+      'unique' => false,
+      ),
+    ),
+  );
+
+foreach (array_keys($indexes_of) as $table)
+{
+  $existing_indexes = array();
+
+  $query = '
+SHOW INDEX
+  FROM '.PREFIX_TABLE.$table.'
+;';
+  $result = pwg_query($query);
+  while ($row = mysql_fetch_array($result))
+  {
+    if ($row['Key_name'] != 'PRIMARY')
+    {
+      if (!in_array($row['Key_name'], array_keys($indexes_of[$table])))
+      {
+        $query = '
+ALTER TABLE '.PREFIX_TABLE.$table.'
+  DROP INDEX '.$row['Key_name'].'
+;';
+        pwg_query($query);
+      }
+      else
+      {
+        array_push($existing_indexes, $row['Key_name']);
+      }
+    }
+  }
+
+  foreach ($indexes_of[$table] as $index_name => $index)
+  {
+    if (!in_array($index_name, $existing_indexes))
+    {
+      $query = '
+ALTER TABLE '.PREFIX_TABLE.$table.'
+  ADD '.($index['unique'] ? 'UNIQUE' : 'INDEX').' '
+        .$index_name.' ('.implode(',', $index['columns']).')
+;';
+      pwg_query($query);
+    }
+  }
+}
+
+//
+// insert params in new configuration table
+//
+$params = array(
+  array(
+    'param'   => 'prefix_thumbnail',
+    'value'   => $save['prefix_thumbnail'],
+    'comment' => 'thumbnails filename prefix'
+    ),
+  array(
+    'param'   => 'mail_webmaster',
+    'value'   => $save['mail_webmaster'],
+    'comment' => 'webmaster mail'
+    ),
+  array(
+    'param'   => 'default_language',
+    'value'   => 'en_UK.iso-8859-1',
+    'comment' => 'Default gallery language'
+    ),
+  array(
+    'param'   => 'default_template',
+    'value'   => 'default',
+    'comment' => 'Default gallery style'
+    ),
+  array(
+    'param'   => 'default_maxwidth',
+    'value'   => '',
+    'comment' => 'maximum width authorized for displaying images'
+    ),
+  array(
+    'param'   => 'default_maxheight',
+    'value'   => '',
+    'comment' => 'maximum height authorized for the displaying images'
+    ),
+  array(
+    'param'   => 'nb_comment_page',
+    'value'   => '10',
+    'comment' => 'number of comments to display on each page'
+    ),
+  array(
+    'param'   => 'upload_maxfilesize',
+    'value'   => '150',
+    'comment' => 'maximum filesize for the uploaded pictures'
+    ),
+  array(
+    'param'   => 'upload_maxwidth',
+    'value'   => '800',
+    'comment' => 'maximum width authorized for the uploaded images'
+    ),
+  array(
+    'param'   => 'upload_maxheight',
+    'value'   => '600',
+    'comment' => 'maximum height authorized for the uploaded images'
+    ),
+  array(
+    'param'   => 'upload_maxwidth_thumbnail',
+    'value'   => '150',
+    'comment' => 'maximum width authorized for the uploaded thumbnails'
+    ),
+  array(
+    'param'   => 'upload_maxheight_thumbnail',
+    'value'   => '100',
+    'comment' => 'maximum height authorized for the uploaded thumbnails'
+    ),
+  array(
+    'param'   => 'log',
+    'value'   => 'false',
+    'comment' => 'keep an history of visits on your website'
+    ),
+  array(
+    'param'   => 'comments_validation',
+    'value'   => 'false',
+    'comment' => 'administrators validate users comments before becoming visible'
+    ),
+  array(
+    'param'   => 'comments_forall',
+    'value'   => 'false',
+    'comment' => 'even guest not registered can post comments'
+    ),
+  array(
+    'param'   => 'mail_notification',
+    'value'   => 'false',
+    'comment' => 'automated mail notification for adminsitrators'
+    ),
+  array(
+    'param'   => 'nb_image_line',
+    'value'   => '5',
+    'comment' => 'Number of images displayed per row'
+    ),
+  array(
+    'param'   => 'nb_line_page',
+    'value'   => '3',
+    'comment' => 'Number of rows displayed per page'
+    ),
+  array(
+    'param'   => 'recent_period',
+    'value'   => '7',
+    'comment' => 'Period within which pictures are displayed as new (in days)'
+    ),
+  array(
+    'param'   => 'auto_expand',
+    'value'   => 'false',
+    'comment' => 'Auto expand of the category tree'
+    ),
+  array(
+    'param'   => 'show_nb_comments',
+    'value'   => 'false',
+    'comment' => 'Show the number of comments under the thumbnails'
+    ),
+  array(
+    'param'   => 'use_iptc',
+    'value'   => 'false',
+    'comment' => 'Use IPTC data during database synchronization with files metadata'
+    ),
+  array(
+    'param'   => 'use_exif',
+    'value'   => 'false',
+    'comment' => 'Use EXIF data during database synchronization with files metadata'
+    ),
+  array(
+    'param'   => 'show_iptc',
+    'value'   => 'false',
+    'comment' => 'Show IPTC metadata on picture.php if asked by user'
+    ),
+  array(
+    'param'   => 'show_exif',
+    'value'   => 'true',
+    'comment' => 'Show EXIF metadata on picture.php if asked by user'
+    ),
+  array(
+    'param'   => 'authorize_remembering',
+    'value'   => 'true',
+    'comment' => 'Authorize users to be remembered, see $conf{remember_me_length}'
+    ),
+  array(
+    'param'   => 'gallery_locked',
+    'value'   => 'false',
+    'comment' => 'Lock your gallery temporary for non admin users'
+    ),
+  );
+
+mass_inserts(
+  CONFIG_TABLE,
+  array_keys($params[0]),
+  $params
+  );
+
+// refresh calculated datas
+update_global_rank();
+update_category();
+
+// update calculated field "images.path"
+$cat_ids = array();
+
+$query = '
+SELECT DISTINCT(storage_category_id) AS unique_storage_category_id
+  FROM '.IMAGES_TABLE.'
+;';
+$result = pwg_query($query);
+while ($row = mysql_fetch_array($result))
+{
+  array_push($cat_ids, $row['unique_storage_category_id']);
+}
+$fulldirs = get_fulldirs($cat_ids);
+
+foreach ($cat_ids as $cat_id)
+{
+  $query = '
+UPDATE '.IMAGES_TABLE.'
+  SET path = CONCAT(\''.$fulldirs[$cat_id].'\',\'/\',file)
+  WHERE storage_category_id = '.$cat_id.'
+;';
+  pwg_query($query);
+}
+
+// all sub-categories of private categories become private
+$cat_ids = array();
+
+$query = '
+SELECT id
+  FROM '.CATEGORIES_TABLE.'
+  WHERE status = \'private\'
+;';
+$result = pwg_query($query);
+while ($row = mysql_fetch_array($result))
+{
+  array_push($cat_ids, $row['id']);
+}
+
+if (count($cat_ids) > 0)
+{
+  $privates = get_subcat_ids($cat_ids);
+
+  $query = '
+UPDATE '.CATEGORIES_TABLE.'
+  SET status = \'private\'
+  WHERE id IN ('.implode(',', $privates).')
+;';
+  pwg_query($query);
+}
+
+// load the config file
+$config_file = PHPWG_ROOT_PATH.'include/mysql.inc.php';
+$config_file_contents = @file_get_contents($config_file);
+if ($config_file_contents === false)
+{
+  die('CANNOT LOAD '.$config_file);
+}
+$php_end_tag = strrpos($config_file_contents, '?'.'>');
+if ($php_end_tag === false)
+{
+  die('CANNOT FIND PHP END TAG IN '.$config_file);
+}
+if (!is_writable($config_file))
+{
+  die('FILE NOT WRITABLE '.$config_file);
+}
+
+// changes to write in mysql.inc.php
+array_push($mysql_changes, 'define(\'PHPWG_INSTALLED\', true);');
+
+// Send infos
+$page['infos'] = array_merge(
+  $page['infos'],
+  array(
+    l10n('all sub-categories of private categories become private'),
+    l10n('user permissions and group permissions have been erased'),
+    l10n('only thumbnails prefix and webmaster mail saved')
+    )
+  );
+
+// now we upgrade from 1.4.0
+include_once(PHPWG_ROOT_PATH.'install/upgrade_1.4.0.php');
+?>
Index: /tags/2.0.2/install/upgrade_1.4.0.php
===================================================================
--- /tags/2.0.2/install/upgrade_1.4.0.php	(revision 3278)
+++ /tags/2.0.2/install/upgrade_1.4.0.php	(revision 3278)
@@ -0,0 +1,292 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die ('This page cannot be loaded directly, load upgrade.php');
+}
+else
+{
+  if (!defined('PHPWG_IN_UPGRADE') or !PHPWG_IN_UPGRADE)
+  {
+    die ('Hacking attempt!');
+  }
+}
+
+$last_time = get_moment();
+
+// will the user have to edit include/config_local.inc.php for
+// prefix_thumbnail configuration parameter
+$query = '
+SELECT value
+  FROM '.CONFIG_TABLE.'
+  WHERE param = \'prefix_thumbnail\'
+;';
+list($prefix_thumbnail) = mysql_fetch_array(pwg_query($query));
+
+// delete obsolete configuration
+$query = '
+DELETE
+  FROM '.PREFIX_TABLE.'config
+  WHERE param IN (
+   \'prefix_thumbnail\',
+   \'mail_webmaster\',
+   \'upload_maxfilesize\',
+   \'upload_maxwidth\',
+   \'upload_maxheight\',
+   \'upload_maxwidth_thumbnail\',
+   \'upload_maxheight_thumbnail\',
+   \'mail_notification\',
+   \'use_iptc\',
+   \'use_exif\',
+   \'show_iptc\',
+   \'show_exif\',
+   \'authorize_remembering\'
+   )
+;';
+pwg_query($query);
+
+$queries = array(
+
+  "
+ALTER TABLE piwigo_categories
+  CHANGE COLUMN date_last date_last datetime default NULL
+;",
+
+  "
+ALTER TABLE piwigo_comments
+  ADD COLUMN validation_date datetime default NULL
+;",
+
+  "
+UPDATE piwigo_comments
+  SET validation_date = date
+",
+
+  "
+ALTER TABLE piwigo_comments
+  ADD INDEX comments_i1 (image_id)
+;",
+
+  "
+ALTER TABLE piwigo_comments
+  ADD INDEX comments_i2 (validation_date)
+;",
+
+  "
+ALTER TABLE piwigo_favorites
+  CHANGE COLUMN user_id user_id smallint(5) NOT NULL default '0'
+;",
+
+  "
+ALTER TABLE piwigo_images
+  CHANGE COLUMN date_available
+    date_available datetime NOT NULL default '0000-00-00 00:00:00'
+;",
+
+  "
+ALTER TABLE piwigo_rate
+  CHANGE COLUMN user_id user_id smallint(5) NOT NULL default '0'
+;",
+
+  "
+ALTER TABLE piwigo_sessions
+  CHANGE COLUMN user_id user_id smallint(5) NOT NULL default '0'
+;",
+
+  "
+ALTER TABLE piwigo_user_access
+  CHANGE COLUMN user_id user_id smallint(5) NOT NULL default '0'
+;",
+
+  "
+DROP TABLE piwigo_user_forbidden
+;",
+
+  "
+ALTER TABLE piwigo_user_group
+ CHANGE COLUMN user_id user_id smallint(5) NOT NULL default '0'
+;",
+
+  "
+ALTER TABLE piwigo_users
+  CHANGE COLUMN id id smallint(5) NOT NULL auto_increment
+;",
+
+  "
+CREATE TABLE piwigo_caddie (
+  user_id smallint(5) NOT NULL default '0',
+  element_id mediumint(8) NOT NULL default '0',
+  PRIMARY KEY  (user_id,element_id)
+) TYPE=MyISAM
+;",
+
+  "
+CREATE TABLE piwigo_user_cache (
+  user_id smallint(5) NOT NULL default '0',
+  need_update enum('true','false') NOT NULL default 'true',
+  forbidden_categories text,
+  PRIMARY KEY  (user_id)
+) TYPE=MyISAM
+;",
+
+  "
+CREATE TABLE piwigo_user_feed (
+  id varchar(50) binary NOT NULL default '',
+  user_id smallint(5) NOT NULL default '0',
+  last_check datetime default NULL,
+  PRIMARY KEY  (id)
+) TYPE=MyISAM
+;",
+
+  "
+CREATE TABLE piwigo_user_infos (
+  user_id smallint(5) NOT NULL default '0',
+  nb_image_line tinyint(1) unsigned NOT NULL default '5',
+  nb_line_page tinyint(3) unsigned NOT NULL default '3',
+  status enum('admin','guest') NOT NULL default 'guest',
+  language varchar(50) NOT NULL default 'english',
+  maxwidth smallint(6) default NULL,
+  maxheight smallint(6) default NULL,
+  expand enum('true','false') NOT NULL default 'false',
+  show_nb_comments enum('true','false') NOT NULL default 'false',
+  recent_period tinyint(3) unsigned NOT NULL default '7',
+  template varchar(255) NOT NULL default 'yoga',
+  registration_date datetime NOT NULL default '0000-00-00 00:00:00',
+  UNIQUE KEY user_infos_ui1 (user_id)
+) TYPE=MyISAM
+;"
+  );
+
+foreach ($queries as $query)
+{
+  $query = str_replace('piwigo_', PREFIX_TABLE, $query);
+  pwg_query($query);
+}
+
+// user datas migration from piwigo_users to piwigo_user_infos
+$query = '
+SELECT *
+  FROM '.USERS_TABLE.'
+;';
+
+$datas = array();
+list($dbnow) = mysql_fetch_row(pwg_query('SELECT NOW();'));
+
+$result = pwg_query($query);
+while ($row = mysql_fetch_array($result))
+{
+  $row['user_id'] = $row['id'];
+  $row['registration_date'] = $dbnow;
+  array_push($datas, $row);
+}
+
+include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+mass_inserts(
+  USER_INFOS_TABLE,
+  array(
+    'user_id',
+    'nb_image_line',
+    'nb_line_page',
+    'status',
+    'language',
+    'maxwidth',
+    'maxheight',
+    'expand',
+    'show_nb_comments',
+    'recent_period',
+    'template',
+    'registration_date'
+    ),
+  $datas
+  );
+
+$queries = array(
+
+  "
+UPDATE ".USER_INFOS_TABLE."
+  SET template = 'yoga'
+;",
+
+  "
+UPDATE ".USER_INFOS_TABLE."
+  SET language = 'en_UK.iso-8859-1'
+  WHERE language NOT IN ('en_UK.iso-8859-1', 'fr_FR.iso-8859-1')
+;",
+
+  "
+UPDATE ".CONFIG_TABLE."
+  SET value = 'en_UK.iso-8859-1'
+  WHERE param = 'default_language'
+    AND value NOT IN ('en_UK.iso-8859-1', 'fr_FR.iso-8859-1')
+;",
+
+  "
+UPDATE ".CONFIG_TABLE."
+  SET value = 'yoga'
+  WHERE param = 'default_template'
+;",
+
+  "
+INSERT INTO ".CONFIG_TABLE."
+  (param,value,comment)
+  VALUES
+  (
+    'gallery_title',
+    'Piwigo demonstration site',
+    'Title at top of each page and for RSS feed'
+  )
+;",
+
+  "
+INSERT INTO ".CONFIG_TABLE."
+  (param,value,comment)
+  VALUES
+  (
+    'gallery_description',
+    'My photos web site',
+    'Short description displayed with gallery title'
+  )
+;"
+
+  );
+
+foreach ($queries as $query)
+{
+  $query = str_replace('piwigo_', PREFIX_TABLE, $query);
+  pwg_query($query);
+}
+
+if ($prefix_thumbnail != 'TN-')
+{
+  array_push(
+    $page['infos'],
+    'the thumbnail prefix configuration parameter was moved to configuration
+file, copy config_local.inc.php from "tools" directory to "include" directory
+and edit $conf[\'prefix_thumbnail\'] = '.$prefix_thumbnail
+    );
+}
+
+// now we upgrade from 1.5.0 to 1.6.0
+include_once(PHPWG_ROOT_PATH.'install/upgrade_1.5.0.php');
+?>
Index: /tags/2.0.2/install/upgrade_1.5.0.php
===================================================================
--- /tags/2.0.2/install/upgrade_1.5.0.php	(revision 3278)
+++ /tags/2.0.2/install/upgrade_1.5.0.php	(revision 3278)
@@ -0,0 +1,469 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die ('This page cannot be loaded directly, load upgrade.php');
+}
+else
+{
+  if (!defined('PHPWG_IN_UPGRADE') or !PHPWG_IN_UPGRADE)
+  {
+    die ('Hacking attempt!');
+  }
+}
+
+/**
+ * replace old style #images.keywords by #tags. Requires a big data
+ * migration.
+ *
+ * @return void
+ */
+function tag_replace_keywords()
+{
+  // code taken from upgrades 19 and 22
+  
+  $query = '
+CREATE TABLE '.PREFIX_TABLE.'tags (
+  id smallint(5) UNSIGNED NOT NULL auto_increment,
+  name varchar(255) BINARY NOT NULL,
+  url_name varchar(255) BINARY NOT NULL,
+  PRIMARY KEY (id)
+)
+;';
+  pwg_query($query);
+  
+  $query = '
+CREATE TABLE '.PREFIX_TABLE.'image_tag (
+  image_id mediumint(8) UNSIGNED NOT NULL,
+  tag_id smallint(5) UNSIGNED NOT NULL,
+  PRIMARY KEY (image_id,tag_id)
+)
+;';
+  pwg_query($query);
+  
+  //
+  // Move keywords to tags
+  //
+
+  // each tag label is associated to a numeric identifier
+  $tag_id = array();
+  // to each tag id (key) a list of image ids (value) is associated
+  $tag_images = array();
+
+  $current_id = 1;
+
+  $query = '
+SELECT id, keywords
+  FROM '.PREFIX_TABLE.'images
+  WHERE keywords IS NOT NULL
+;';
+  $result = pwg_query($query);
+  while ($row = mysql_fetch_array($result))
+  {
+    foreach(preg_split('/[,]+/', $row['keywords']) as $keyword)
+    {
+      if (!isset($tag_id[$keyword]))
+      {
+        $tag_id[$keyword] = $current_id++;
+      }
+
+      if (!isset($tag_images[ $tag_id[$keyword] ]))
+      {
+        $tag_images[ $tag_id[$keyword] ] = array();
+      }
+
+      array_push(
+        $tag_images[ $tag_id[$keyword] ],
+        $row['id']
+        );
+    }
+  }
+
+  $datas = array();
+  foreach ($tag_id as $tag_name => $tag_id)
+  {
+    array_push(
+      $datas,
+      array(
+        'id'       => $tag_id,
+        'name'     => $tag_name,
+        'url_name' => str2url($tag_name),
+        )
+      );
+  }
+  
+  if (!empty($datas))
+  {
+    mass_inserts(
+      PREFIX_TABLE.'tags',
+      array_keys($datas[0]),
+      $datas
+      );
+  }
+
+  $datas = array();
+  foreach ($tag_images as $tag_id => $images)
+  {
+    foreach (array_unique($images) as $image_id)
+    {
+      array_push(
+        $datas,
+        array(
+          'tag_id'   => $tag_id,
+          'image_id' => $image_id,
+          )
+        );
+    }
+  }
+  
+  if (!empty($datas))
+  {
+    mass_inserts(
+      PREFIX_TABLE.'image_tag',
+      array_keys($datas[0]),
+      $datas
+      );
+  }
+
+  //
+  // Delete images.keywords
+  //
+  $query = '
+ALTER TABLE '.PREFIX_TABLE.'images DROP COLUMN keywords
+;';
+  pwg_query($query);
+
+  //
+  // Add useful indexes
+  //
+  $query = '
+ALTER TABLE '.PREFIX_TABLE.'tags
+  ADD INDEX tags_i1(url_name)
+;';
+  pwg_query($query);
+
+
+  $query = '
+ALTER TABLE '.PREFIX_TABLE.'image_tag
+  ADD INDEX image_tag_i1(tag_id)
+;';
+  pwg_query($query);
+
+  // print_time('tags have replaced keywords');
+}
+
+tag_replace_keywords();
+
+$queries = array(
+  "
+CREATE TABLE ".PREFIX_TABLE."search (
+  id int UNSIGNED NOT NULL AUTO_INCREMENT,
+  last_seen date DEFAULT NULL,
+  rules text,
+  PRIMARY KEY  (id)
+);",
+
+  "
+CREATE TABLE ".PREFIX_TABLE."user_mail_notification (
+  user_id smallint(5) NOT NULL default '0',
+  check_key varchar(16) binary NOT NULL default '',
+  enabled enum('true','false') NOT NULL default 'false',
+  last_send datetime default NULL,
+  PRIMARY KEY  (user_id),
+  UNIQUE KEY uidx_check_key (check_key)
+);",
+
+  "
+CREATE TABLE ".PREFIX_TABLE."upgrade (
+  id varchar(20) NOT NULL default '',
+  applied datetime NOT NULL default '0000-00-00 00:00:00',
+  description varchar(255) default NULL,
+  PRIMARY KEY  (`id`)
+);",
+
+  "
+ALTER TABLE ".PREFIX_TABLE."config
+  MODIFY COLUMN value TEXT
+;",
+
+  "
+ALTER TABLE ".PREFIX_TABLE."images
+  ADD COLUMN has_high enum('true') default NULL
+;",
+
+  "
+ALTER TABLE ".PREFIX_TABLE."rate
+  ADD COLUMN anonymous_id varchar(45) NOT NULL default ''
+;",
+  "
+ALTER TABLE ".PREFIX_TABLE."rate
+  ADD COLUMN date date NOT NULL default '0000-00-00'
+;",
+  "
+ALTER TABLE ".PREFIX_TABLE."rate
+  DROP PRIMARY KEY
+;",
+  "
+ALTER TABLE ".PREFIX_TABLE."rate
+  ADD PRIMARY KEY (element_id,user_id,anonymous_id)
+;",
+  "
+UPDATE ".PREFIX_TABLE."rate
+  SET date = CURDATE()
+;",
+  
+  "
+DELETE
+  FROM ".PREFIX_TABLE."sessions
+;",
+  "
+ALTER TABLE ".PREFIX_TABLE."sessions
+  DROP COLUMN user_id
+;",
+  "
+ALTER TABLE ".PREFIX_TABLE."sessions
+  ADD COLUMN data text NOT NULL
+;",
+  
+  "
+ALTER TABLE ".PREFIX_TABLE."user_cache
+  ADD COLUMN nb_total_images mediumint(8) unsigned default NULL
+;",
+  
+  "
+ALTER TABLE ".PREFIX_TABLE."user_infos
+  CHANGE COLUMN status
+     status enum('webmaster','admin','normal','generic','guest')
+     NOT NULL default 'guest'
+;",
+  "
+UPDATE ".PREFIX_TABLE."user_infos
+  SET status = 'normal'
+  WHERE status = 'guest'
+;",
+  "
+UPDATE ".PREFIX_TABLE."user_infos
+  SET status = 'guest'
+  WHERE user_id = ".$conf['guest_id']."
+;",
+  "
+UPDATE ".PREFIX_TABLE."user_infos
+  SET status = 'webmaster'
+  WHERE user_id = ".$conf['webmaster_id']."
+;",
+
+  "
+ALTER TABLE ".PREFIX_TABLE."user_infos
+   CHANGE COLUMN template template varchar(255) NOT NULL default 'yoga/clear'
+;",
+
+  "
+UPDATE ".PREFIX_TABLE."user_infos
+  SET template = 'yoga/dark'
+  WHERE template = 'yoga-dark'
+;",
+  "
+UPDATE ".PREFIX_TABLE."user_infos
+  SET template = 'yoga/clear'
+  WHERE template != 'yoga/dark'
+;",
+  "
+ALTER TABLE ".PREFIX_TABLE."user_infos
+  ADD COLUMN adviser enum('true','false') NOT NULL default 'false'
+;",
+  "
+ALTER TABLE ".PREFIX_TABLE."user_infos
+  ADD COLUMN enabled_high enum('true','false') NOT NULL default 'true'
+;",
+  "
+ALTER TABLE ".PREFIX_TABLE."categories
+  CHANGE COLUMN rank rank SMALLINT(5) UNSIGNED DEFAULT NULL
+;",
+  // configuration table
+  "
+UPDATE ".PREFIX_TABLE."config
+  SET value = 'yoga/clear'
+  WHERE param = 'default_template'
+;"
+  );
+
+foreach ($queries as $query)
+{
+  pwg_query($query);
+}
+
+//
+// Move rate, rate_anonymous and gallery_url from config file to database
+//
+$params = array(
+  'gallery_url' => array(
+    'http://piwigo.org/demo',
+    'URL given in RSS feed'
+    ),
+  'rate' => array(
+    'true',
+    'Rating pictures feature is enabled'
+    ),
+  'rate_anonymous' => array(
+    'true',
+    'Rating pictures feature is also enabled for visitors'
+    )
+  );
+// Get real values from config file
+$conf_save = $conf;
+unset($conf);
+@include(PHPWG_ROOT_PATH. 'include/config_local.inc.php');
+if ( isset($conf['gallery_url']) )
+{
+  $params['gallery_url'][0] = $conf['gallery_url'];
+}
+if ( isset($conf['rate']) and is_bool($conf['rate']) )
+{
+  $params['rate'][0] = $conf['rate'] ? 'true' : 'false';
+}
+if ( isset($conf['rate_anonymous']) and is_bool($conf['rate_anonymous']) )
+{
+  $params['rate_anonymous'][0] = $conf['rate_anonymous'] ? 'true' : 'false';
+}
+$conf = $conf_save;
+
+// Do I already have them in DB ?
+$query = 'SELECT param FROM '.PREFIX_TABLE.'config';
+$result = pwg_query($query);
+while ($row = mysql_fetch_array($result))
+{
+  unset( $params[ $row['param'] ] );
+}
+
+// Perform the insert query
+foreach ($params as $param_key => $param_values)
+{
+  $query = '
+INSERT INTO '.PREFIX_TABLE.'config
+  (param,value,comment)
+  VALUES
+ ('."'$param_key','$param_values[0]','$param_values[1]')
+;";
+  pwg_query($query);
+}
+
+$query = "
+ALTER TABLE ".PREFIX_TABLE."config MODIFY COLUMN `value` TEXT;";
+pwg_query($query);
+
+
+//
+// replace gallery_description by page_banner
+//
+$query = '
+SELECT value
+  FROM '.PREFIX_TABLE.'config
+  WHERE param=\'gallery_title\'
+;';
+list($t) = array_from_query($query, 'value');
+
+$query = '
+SELECT value
+  FROM '.PREFIX_TABLE.'config
+  WHERE param=\'gallery_description\'
+;';
+list($d) = array_from_query($query, 'value');
+
+$page_banner='<h1>'.$t.'</h1><p>'.$d.'</p>';
+$page_banner=addslashes($page_banner);
+$query = '
+INSERT INTO '.PREFIX_TABLE.'config
+  (param,value,comment)
+  VALUES
+  (
+    \'page_banner\',
+    \''.$page_banner.'\',
+    \'html displayed on the top each page of your gallery\'
+  )
+;';
+pwg_query($query);
+
+$query = '
+DELETE FROM '.PREFIX_TABLE.'config
+  WHERE param=\'gallery_description\'
+;';
+pwg_query($query);
+
+//
+// configuration for notification by mail
+//
+$query = "
+INSERT INTO ".CONFIG_TABLE."
+  (param,value,comment)
+  VALUES
+  (
+    'nbm_send_mail_as',
+    '',
+    'Send mail as param value for notification by mail'
+  ),
+  (
+    'nbm_send_detailed_content',
+    'true',
+    'Send detailed content for notification by mail'
+  ),
+  (
+    'nbm_complementary_mail_content',
+    '',
+    'Complementary mail content for notification by mail'
+  )
+;";
+pwg_query($query);
+
+// depending on the way the 1.5.0 was installed (from scratch or by upgrade)
+// the database structure has small differences that should be corrected.
+
+$query = '
+ALTER TABLE '.PREFIX_TABLE.'users
+  CHANGE COLUMN password password varchar(32) default NULL
+;';
+pwg_query($query);
+
+$to_keep = array('id', 'username', 'password', 'mail_address');
+  
+$query = '
+DESC '.PREFIX_TABLE.'users
+;';
+
+$result = pwg_query($query);
+
+while ($row = mysql_fetch_array($result))
+{
+  if (!in_array($row['Field'], $to_keep))
+  {
+    $query = '
+ALTER TABLE '.PREFIX_TABLE.'users
+  DROP COLUMN '.$row['Field'].'
+;';
+    pwg_query($query);
+  }
+}
+
+// now we upgrade from 1.6.0 to 1.6.2
+include_once(PHPWG_ROOT_PATH.'install/upgrade_1.6.0.php');
+?>
Index: /tags/2.0.2/install/upgrade_1.6.0.php
===================================================================
--- /tags/2.0.2/install/upgrade_1.6.0.php	(revision 3278)
+++ /tags/2.0.2/install/upgrade_1.6.0.php	(revision 3278)
@@ -0,0 +1,54 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die ('This page cannot be loaded directly, load upgrade.php');
+}
+else
+{
+  if (!defined('PHPWG_IN_UPGRADE') or !PHPWG_IN_UPGRADE)
+  {
+    die ('Hacking attempt!');
+  }
+}
+
+$queries = array(
+  "
+ALTER TABLE ".PREFIX_TABLE."user_infos
+  ADD auto_login_key varchar(64) NOT NULL
+;",
+  '
+ALTER TABLE '.PREFIX_TABLE.'users
+  CHANGE username username VARCHAR(100) binary NOT NULL
+;',
+  );
+
+foreach ($queries as $query)
+{
+  pwg_query($query);
+}
+
+// now we upgrade from 1.6.2
+include_once(PHPWG_ROOT_PATH.'install/upgrade_1.6.2.php');
+?>
Index: /tags/2.0.2/install/upgrade_1.6.2.php
===================================================================
--- /tags/2.0.2/install/upgrade_1.6.2.php	(revision 3278)
+++ /tags/2.0.2/install/upgrade_1.6.2.php	(revision 3278)
@@ -0,0 +1,347 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die ('This page cannot be loaded directly, load upgrade.php');
+}
+else
+{
+  if (!defined('PHPWG_IN_UPGRADE') or !PHPWG_IN_UPGRADE)
+  {
+    die ('Hacking attempt!');
+  }
+}
+
+$queries = array(
+"
+ALTER TABLE `".PREFIX_TABLE."categories`
+  ADD COLUMN `permalink` varchar(64) default NULL
+;",
+
+"
+ALTER TABLE `".PREFIX_TABLE."categories`
+  ADD COLUMN `image_order` varchar(128) default NULL
+;",
+
+"
+ALTER TABLE `".PREFIX_TABLE."categories`
+  ADD UNIQUE `categories_i3` (`permalink`)
+;",
+
+"
+ALTER TABLE `".PREFIX_TABLE."groups`
+  ADD COLUMN `is_default` enum('true','false') NOT NULL default 'false'
+;",
+
+"
+RENAME TABLE `".PREFIX_TABLE."history` TO `".PREFIX_TABLE."history_backup`
+;",
+
+"
+CREATE TABLE `".PREFIX_TABLE."history` (
+  `id` int(10) unsigned NOT NULL auto_increment,
+  `date` date NOT NULL default '0000-00-00',
+  `time` time NOT NULL default '00:00:00',
+  `year` smallint(4) NOT NULL default '0',
+  `month` tinyint(2) NOT NULL default '0',
+  `day` tinyint(2) NOT NULL default '0',
+  `hour` tinyint(2) NOT NULL default '0',
+  `user_id` smallint(5) NOT NULL default '0',
+  `IP` varchar(15) NOT NULL default '',
+  `section` enum('categories','tags','search','list','favorites','most_visited','best_rated','recent_pics','recent_cats') default NULL,
+  `category_id` smallint(5) default NULL,
+  `tag_ids` varchar(50) default NULL,
+  `image_id` mediumint(8) default NULL,
+  `summarized` enum('true','false') default 'false',
+  `image_type` enum('picture','high','other') default NULL,
+  PRIMARY KEY  (`id`),
+  KEY `history_i1` (`summarized`)
+) TYPE=MyISAM
+;",
+
+"
+ALTER TABLE `".PREFIX_TABLE."image_category`
+  DROP INDEX `image_category_i1`
+;",
+
+"
+ALTER TABLE `".PREFIX_TABLE."image_category`
+  ADD INDEX `image_category_i1` (`category_id`)
+;",
+
+"
+ALTER TABLE `".PREFIX_TABLE."image_category`
+  DROP INDEX `image_category_i2`
+;",
+
+"
+ALTER TABLE `".PREFIX_TABLE."images`
+  ADD COLUMN `high_filesize` mediumint(9) unsigned default NULL
+;",
+
+"
+ALTER TABLE `".PREFIX_TABLE."user_infos`
+  CHANGE COLUMN `language`
+    `language` varchar(50) NOT NULL default 'en_UK.iso-8859-1'
+;",
+
+"
+ALTER TABLE `".PREFIX_TABLE."user_infos`
+  DROP COLUMN `auto_login_key`
+;",
+
+"
+ALTER TABLE `".PREFIX_TABLE."user_infos`
+  ADD COLUMN `show_nb_hits` enum('true','false') NOT NULL default 'false'
+;",
+
+"
+ALTER TABLE `".PREFIX_TABLE."user_mail_notification`
+  DROP INDEX `uidx_check_key`
+;",
+
+"
+ALTER TABLE `".PREFIX_TABLE."user_mail_notification`
+  ADD UNIQUE `user_mail_notification_ui1` (`check_key`)
+;",
+
+"
+CREATE TABLE `".PREFIX_TABLE."history_summary` (
+  `id` varchar(13) NOT NULL default '',
+  `year` smallint(4) NOT NULL default '0',
+  `month` tinyint(2) default NULL,
+  `day` tinyint(2) default NULL,
+  `hour` tinyint(2) default NULL,
+  `nb_pages` int(11) default NULL,
+  PRIMARY KEY  (`id`)
+) TYPE=MyISAM
+;",
+
+"
+CREATE TABLE `".PREFIX_TABLE."old_permalinks` (
+  `cat_id` smallint(5) unsigned NOT NULL default '0',
+  `permalink` varchar(64) NOT NULL default '',
+  `date_deleted` datetime NOT NULL default '0000-00-00 00:00:00',
+  `last_hit` datetime default NULL,
+  `hit` int(10) unsigned NOT NULL default '0',
+  PRIMARY KEY  (`permalink`)
+) TYPE=MyISAM
+;",
+
+"
+CREATE TABLE `".PREFIX_TABLE."plugins` (
+  `id` varchar(64) binary NOT NULL default '',
+  `state` enum('inactive','active') NOT NULL default 'inactive',
+  `version` varchar(64) NOT NULL default '0',
+  PRIMARY KEY  (`id`)
+) TYPE=MyISAM
+;",
+
+"
+CREATE TABLE `".PREFIX_TABLE."user_cache_categories` (
+  `user_id` smallint(5) NOT NULL default '0',
+  `cat_id` smallint(5) unsigned NOT NULL default '0',
+  `max_date_last` datetime default NULL,
+  `count_images` mediumint(8) unsigned default '0',
+  `count_categories` mediumint(8) unsigned default '0',
+  PRIMARY KEY  (`user_id`,`cat_id`)
+) TYPE=MyISAM
+;",
+
+/* TABLE DROPPED BEFORE Butterfly/Piwigo release - see later DROP IF EXISTS
+"
+CREATE TABLE `".PREFIX_TABLE."ws_access` (
+  `id` smallint(5) unsigned NOT NULL auto_increment,
+  `name` varchar(32) NOT NULL default '',
+  `access` varchar(255) default NULL,
+  `start` datetime default NULL,
+  `end` datetime default NULL,
+  `request` varchar(255) default NULL,
+  `limit` smallint(5) unsigned default NULL,
+  `comment` varchar(255) default NULL,
+  PRIMARY KEY  (`id`),
+  UNIQUE KEY `ws_access_ui1` (`name`)
+) TYPE=MyISAM COMMENT='Access for Web Services'
+;",*/
+
+"
+INSERT INTO ".PREFIX_TABLE."config
+  (param,value,comment)
+  VALUES
+  ('show_nb_hits', 'false', 'Show hits count under thumbnails')
+;",
+
+"
+INSERT INTO ".PREFIX_TABLE."config
+  (param,value,comment)
+  VALUES
+  ('history_admin','false','keep a history of administrator visits on your website')
+;",
+
+"
+INSERT INTO ".PREFIX_TABLE."config
+  (param,value,comment)
+  VALUES
+  ('history_guest','true','keep a history of guest visits on your website')
+;",
+
+"
+INSERT INTO ".PREFIX_TABLE."config
+  (param,value,comment)
+  VALUES
+  ('allow_user_registration','true','allow visitors to register?')
+;",
+
+"
+INSERT INTO ".PREFIX_TABLE."config
+  (param,value,comment)
+  VALUES
+  ('secret_key', MD5(RAND()), 'a secret key specific to the gallery for internal use')
+;",
+
+"
+INSERT INTO ".PREFIX_TABLE."config
+  (param,value,comment)
+  VALUES
+  ('nbm_send_html_mail','true','Send mail on HTML format for notification by mail')
+;",
+
+"
+INSERT INTO ".PREFIX_TABLE."config
+  (param,value,comment)
+  VALUES
+  ('nbm_send_recent_post_dates','true','Send recent post by dates for notification by mail')
+;",
+
+"
+INSERT INTO ".PREFIX_TABLE."config
+  (param,value,comment)
+  VALUES
+  ('email_admin_on_new_user','false','Send an email to theadministrators when a user registers')
+;",
+
+"
+INSERT INTO ".PREFIX_TABLE."config
+  (param,value,comment)
+  VALUES
+  ('email_admin_on_comment','false','Send an email to the administrators when a valid comment is entered')
+;",
+
+"
+INSERT INTO ".PREFIX_TABLE."config
+  (param,value,comment)
+  VALUES
+  ('email_admin_on_comment_validation','false','Send an email to the administrators when a comment requires validation')
+;",
+
+"
+INSERT INTO ".PREFIX_TABLE."config
+  (param,value,comment)
+  VALUES
+  ('email_admin_on_picture_uploaded','false','Send an email to the administrators when a picture is uploaded')
+;",
+
+"
+UPDATE ".PREFIX_TABLE."user_cache
+  SET need_update = 'true'
+;",
+
+);
+
+foreach ($queries as $query)
+{
+  pwg_query($query);
+}
+
+$replacements = array(
+  array('&#039;', '\''),
+  array('&quot;', '"'),
+  array('&lt;',   '<'),
+  array('&gt;',   '>'),
+  array('&amp;',  '&') // <- this must be the last one
+  );
+
+foreach ($replacements as $replacement)
+{
+    $query = '
+UPDATE '.PREFIX_TABLE.'comments
+  SET content = REPLACE(content, "'.
+  addslashes($replacement[0]).
+  '", "'.
+  addslashes($replacement[1]).
+  '")
+;';
+    pwg_query($query);
+}
+
+load_conf_from_db();
+
+$query = "
+UPDATE ".USER_INFOS_TABLE."
+SET
+  template = '".$conf['default_template']."',
+  nb_image_line = ".$conf['nb_image_line'].",
+  nb_line_page = ".$conf['nb_line_page'].",
+  language = '".$conf['default_language']."',
+  maxwidth = ".
+  (empty($conf['default_maxwidth']) ? "NULL" : $conf['default_maxwidth']).
+  ",
+  maxheight = ".
+  (empty($conf['default_maxheight']) ? "NULL" : $conf['default_maxheight']).
+  ",
+  recent_period = ".$conf['recent_period'].",
+  expand = '".boolean_to_string($conf['auto_expand'])."',
+  show_nb_comments = '".boolean_to_string($conf['show_nb_comments'])."',
+  show_nb_hits = '".boolean_to_string($conf['show_nb_hits'])."',
+  enabled_high = '".boolean_to_string(
+    (isset($conf['newuser_default_enabled_high']) ?
+      $conf['newuser_default_enabled_high'] : true)
+    ).
+  "'
+WHERE
+  user_id = ".$conf['default_user_id'].";";
+pwg_query($query);
+
+$query = "
+DELETE FROM ".CONFIG_TABLE."
+WHERE
+  param IN
+(
+  'default_template',
+  'nb_image_line',
+  'nb_line_page',
+  'default_language',
+  'default_maxwidth',
+  'default_maxheight',
+  'recent_period',
+  'auto_expand',
+  'show_nb_comments',
+  'show_nb_hits'
+)
+;";
+pwg_query($query);
+
+// now we upgrade from 1.7.0
+include_once(PHPWG_ROOT_PATH.'install/upgrade_1.7.0.php');
+?>
Index: /tags/2.0.2/install/upgrade_1.7.0.php
===================================================================
--- /tags/2.0.2/install/upgrade_1.7.0.php	(revision 3278)
+++ /tags/2.0.2/install/upgrade_1.7.0.php	(revision 3278)
@@ -0,0 +1,123 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die ('This page cannot be loaded directly, load upgrade.php');
+}
+else
+{
+  if (!defined('PHPWG_IN_UPGRADE') or !PHPWG_IN_UPGRADE)
+  {
+    die ('Hacking attempt!');
+  }
+}
+
+define('UPGRADES_PATH', PHPWG_ROOT_PATH.'install/db');
+
+list($dbnow) = mysql_fetch_row(pwg_query('SELECT NOW();'));
+define('CURRENT_DATE', $dbnow);
+
+// +-----------------------------------------------------------------------+
+// |             Fill upgrade table without applying upgrade               |
+// +-----------------------------------------------------------------------+
+
+// retrieve already applied upgrades
+$query = '
+SELECT id
+  FROM '.PREFIX_TABLE.'upgrade
+;';
+$applied = array_from_query($query, 'id');
+
+// retrieve existing upgrades
+$existing = get_available_upgrade_ids();
+
+// which upgrades need to be applied?
+$to_apply = array_diff($existing, $applied);
+$inserts = array();
+foreach ($to_apply as $upgrade_id)
+{
+  if ($upgrade_id > 60)
+  {
+    break;
+  }
+  
+  array_push(
+    $inserts,
+    array(
+      'id' => $upgrade_id,
+      'applied' => CURRENT_DATE,
+      'description' => '[migration from 1.7.0 to '.PHPWG_VERSION.'] not applied',
+      )
+    );
+}
+
+if (!empty($inserts))
+{
+  mass_inserts(
+    '`'.UPGRADE_TABLE.'`',
+    array_keys($inserts[0]),
+    $inserts
+    );
+}
+
+// +-----------------------------------------------------------------------+
+// |                          Perform upgrades                             |
+// +-----------------------------------------------------------------------+
+
+ob_start();
+echo '<pre>';
+
+for ($upgrade_id = 61; ; $upgrade_id++)
+{
+  if (!file_exists(UPGRADES_PATH.'/'.$upgrade_id.'-database.php'))
+  {
+    break;
+  }
+  
+  unset($upgrade_description);
+
+  echo "\n\n";
+  echo '=== upgrade '.$upgrade_id."\n";
+
+  // include & execute upgrade script. Each upgrade script must contain
+  // $upgrade_description variable which describe briefly what the upgrade
+  // script does.
+  include(UPGRADES_PATH.'/'.$upgrade_id.'-database.php');
+
+  // notify upgrade
+  $query = '
+INSERT INTO `'.PREFIX_TABLE.'upgrade`
+  (id, applied, description)
+  VALUES
+  (\''.$upgrade_id.'\', NOW(), \'[migration from 1.7.0 to '.PHPWG_VERSION.'] '.$upgrade_description.'\')
+;';
+  pwg_query($query);
+}
+
+echo '</pre>';
+ob_end_clean();
+
+// now we upgrade from 2.0.0
+// include_once(PHPWG_ROOT_PATH.'install/upgrade_2.0.0.php');
+?>
Index: /tags/2.0.2/language/de_DE/about.html
===================================================================
--- /tags/2.0.2/language/de_DE/about.html	(revision 3278)
+++ /tags/2.0.2/language/de_DE/about.html	(revision 3278)
@@ -0,0 +1,7 @@
+  <li>Piwigo ist eine Web-Anwendung zur leichten Erstellung 
+einer Online-Bildergalerie mit Benutzerverwaltung.</li>
+
+  <li>Technisch gesehen ist Piwigo eine PHP-Anwendung mit einer MySQL Datenbank.</li>
+
+  <li>Wenn Sie Anregungen oder Kommentare haben, besuchen Sie die <a
+  href="http://piwigo.org">offizielle Website</a>.</li>
Index: /tags/2.0.2/language/de_DE/admin.lang.php
===================================================================
--- /tags/2.0.2/language/de_DE/admin.lang.php	(revision 3278)
+++ /tags/2.0.2/language/de_DE/admin.lang.php	(revision 3278)
@@ -0,0 +1,649 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+$lang['%d association'] = '%d Element wird insgesamt angezeigt (physisch und virtuell)';
+$lang['%d associations'] = '%d Elemente werden insgesamt angezeigt (physisch und virtuell)';
+$lang['cat_inclu_part1_S'] = '%d Kategorie enthalten';
+$lang['cat_inclu_part1_P'] = '%d Kategorien enthalten ';
+$lang['cat_inclu_part2_S'] = '%d physisch';
+$lang['cat_inclu_part2_P'] = '%d physische';
+$lang['cat_inclu_part3_S'] = ' und %d virtuell';
+$lang['cat_inclu_part3_P'] = ' und %d virtuelle';
+$lang['%d category moved'] = '%d Kategorie verschoben';
+$lang['%d categories moved'] = '%d Kategorien verschoben';
+$lang['%d group'] = '%d Gruppe';
+$lang['%d groups'] = '%d Gruppe';
+$lang['%d member'] = '%d Mitglied';
+$lang['%d members'] = '%d Mitglieder';
+$lang['%d tag'] = '%d Tag';
+$lang['%d tags'] = '%d Tags';
+$lang['%d user comment rejected'] = '%d Benutzerkommentar abgewiesen';
+$lang['%d user comments rejected'] = '%d Benutzerkommentare abgewiesen';
+$lang['%d user comment validated'] = '%d Benutzerkommentar freigeschaltet';
+$lang['%d user comments validated'] = '%d Benutzerkommentare freigeschaltet';
+$lang['%d user deleted'] = '%d Benutzer gelöscht';
+$lang['%d users deleted'] = '%d Benutzer gelöscht';
+$lang['%d user'] = '%d Benutzer';
+$lang['%d users'] = '%d Benutzer';
+$lang['%d waiting for validation'] = '%d Warten auf Freischaltung';
+$lang['%d waiting pictures rejected'] = '%d freizuschaltende Elemente abgewiesen';
+$lang['%d waiting pictures validated'] = '%d freizuschaltende Elemente akzeptiert';
+$lang['Actions'] = 'Aktionen';
+$lang['Activate'] = 'Aktivieren';
+$lang['Add/delete a permalink'] = 'Hinzufügen/Löschen einer dauerhafte Verbindung (Permalink)';
+$lang['Add a tag'] = 'Tag hinzufügen';
+$lang['Add a user'] = 'Benutzer hinzufügen';
+$lang['Add group'] = 'Gruppe hinzufügen';
+$lang['Add selected elements to caddie'] = 'Hinzufügen ausgewählter Elemente zum Sammelkorb';
+$lang['Add'] = 'Hinzufügen';
+$lang['Allow user registration'] = 'Erlaube die Neuregistrierung von Benutzern';
+$lang['Apply to subcategories'] = 'Einstellungen auch für Unterkategirien übernehmen';
+$lang['Are you sure?'] = 'Sind Sie sicher?';
+$lang['Associated'] = 'ist verlinkt';
+$lang['Association to categories'] = 'Ist in folgende Kategorien verlinkt';
+$lang['Batch management'] = 'Batch management';
+$lang['Caddie management'] = 'Sammelkorb verwalten';
+$lang['Caddie'] = 'Sammelkorb';
+$lang['Categories authorized thanks to group associations'] = 'Für Kategorien freigeschaltet durch Gruppenzugehörigkeit';
+$lang['Categories manual order was saved'] = 'Kategorienreihenfolge gespeichert';
+$lang['Categories ordered alphanumerically'] = 'Kategorien alphanumerisch sortiert';
+$lang['Category elements associated to the following categories: %s'] = 'Kategorieelemente zu folgenden Kategorien zugeordnet: %s';
+$lang['Check for upgrade failed for unknown reasons.'] = 'Suche nach einem Upgrade nicht möglich.';
+$lang['Check for upgrade'] = 'Prüfe ob eine neue Version der Bildergalerie verfügbar ist.';
+$lang['Comments for all'] = 'Kommentare für alle erlaubt';
+$lang['Controversy'] = 'Abweichung';
+$lang['Current name'] = 'Derzeitiger Name';
+$lang['Database'] = 'Datenbank';
+$lang['Deactivate'] = 'Deaktiviere';
+$lang['Delete Representant'] = 'Lösche Vorschaubild';
+$lang['Delete selected tags'] = 'Lösche markierte tags';
+$lang['Delete selected users'] = 'Lösche markierte Benutzer';
+$lang['Deletions'] = 'Löschungen';
+$lang['Deny selected groups'] = 'Ausgewählte Gruppen ablehnen';
+$lang['Deny selected users'] = 'Ausgewählte Benutzer ablehnen';
+$lang['Description'] = 'Beschreibung';
+$lang['Display options'] = 'Anzeigeeinstellungen';
+$lang['Dissociated'] = 'ist nicht verlinkt';
+$lang['Does not represent'] = 'Ist nicht Vorschaubild für diese Kategirien';
+$lang['Edit all picture informations'] = 'Bearbeite alle Bildinformationen';
+$lang['Edit selected tags'] = 'Bearbeite markierte tags';
+$lang['Edit tags'] = 'Bearbeite tags';
+$lang['Elements'] = 'Elemente';
+$lang['Email administrators when a new user registers'] = 'sende eine E-Mail an den(die) Adminstrator(en) wenn sich ein neuer Benutzer registriert hat';
+$lang['Email administrators when a valid comment is entered'] = 'sende eine E-Mail an den(die) Adminstrator(en) wenn ein Kommentar hinterlassen wurde';
+$lang['Email administrators when a comment requires validation'] = 'sende eine E-Mail an den(die) Adminstrator(en) wenn ein Kommentar die Freischaltung durch den Admin erfordert';
+$lang['Email administrators when a picture is uploaded'] = 'sende eine E-Mail an den(die) Adminstrator(en) wenn ein Bild hochgeladen wurde';
+$lang['Empty caddie'] = 'leere Sammelkorb';
+$lang['Environment'] = 'Server-Daten';
+$lang['Form'] = 'Form';
+$lang['Gallery URL'] = 'genaue URL zur Gallerie';
+$lang['Gallery description'] = 'Galeriebeschreibung';
+$lang['Gallery title'] = 'Galerietitel';
+$lang['Grant selected groups'] = 'Ausgewählte Gruppen zulassen';
+$lang['Grant selected users'] = 'Ausgewählte Benutzer zulassen';
+$lang['Group name'] = 'Gruppenname';
+$lang['Groups'] = 'Gruppen';
+$lang['Guests'] = 'Gäste';
+$lang['History'] = 'Statistik';
+$lang['Informations'] = 'Kategorieinformation';
+$lang['Install'] = 'Installiere';
+$lang['Link all category elements to a new category'] = 'Verlinkte alle Kategorieelemente zu einer neuen Kategorie';
+$lang['Link all category elements to some existing categories'] = 'Verlinkte alle Kategorieelemente zu einer bestehenden Kategorie';
+$lang['Linked categories'] = 'Verlinkte Kategorie';
+$lang['Lock gallery'] = 'SCHLIESSE DIE BILDERGALERIE     VORSICHT, Aussperrgefahr!!!';
+$lang['Maintenance'] = 'Wartung';
+$lang['Manage permissions for a category'] = 'Befugnisse für Kategorien verwalten';
+$lang['Manage permissions for group "%s"'] = 'Befugnisse verwalten für die Gruppe "%s"';
+$lang['Manage permissions for user "%s"'] = 'Befugnisse verwalten für den Benutzer "%s"';
+$lang['Manage tags'] = 'Verwalte Tags';
+$lang['Members'] = 'Mitglieder';
+$lang['Metadata synchronized from file'] = 'Metadaten synchronisiert von Datei';
+$lang['Move categories'] = 'Verschiebe Kategorie';
+$lang['Move'] = 'Bewege';
+$lang['Name'] = 'Name';
+$lang['New name'] = 'Neuer Name';
+$lang['New parent category'] = 'Neue Oberkategorie';
+$lang['New tag'] = 'Neuer tag';
+$lang['No tag defined. Use Administration>Pictures>Tags'] = 'Kein tag definiert. Benutze Verwaltung > Elemente > Tags';
+$lang['Number of comments per page'] = 'Anzahl von Kommentaren pro Seite';
+$lang['Number of rates'] = 'Anzahl von Bewertungen';
+$lang['Number of thumbnails to create'] = 'Anzahl von zu erstellenden Vorschaubildern';
+$lang['Only private categories are listed'] = 'Nur provate Kategorien aufgeführt';
+$lang['Operating system'] = 'Betriebssystem';
+$lang['Options'] = 'Optionen';
+$lang['Order alphanumerically'] = 'Ordne Alphanumerisch';
+$lang['Other private categories'] = 'Andere private Kategorien';
+$lang['Page banner'] = 'Seitenbanner';
+$lang['Parent category'] = 'übergeordnete Kategorie';
+$lang['Path'] = 'Pfad';
+$lang['Permalink'] = 'Permalink';
+$lang['Permalink_%s_histo_used_by_%s'] = 'Permalink %s wurde vorher Kategorie %s zugewiesen. Lösche ihn zuerst aus der History';
+$lang['Permalink_name_rule'] = 'Ein Permalink darf nur aus folgenden Zeichen bestehen: a-z, A-Z, 0-9, "-" or "_". Er darf nicht nur aus Zahlen bstehen oder mit einer Zal beginnen mit einem darauffolgenden "-"';
+$lang['Permalink %s is already used by category %s'] = 'Permalink %s wird zur Zeit von Kategorie %s benutzt';
+$lang['Permalink history'] = 'Permalink history';
+$lang['Permalinks'] = 'Permalinks';
+$lang['Permission denied'] = 'Zugriff verweigern';
+$lang['Permission granted thanks to a group'] = 'Durch Zugehörigkeit einer Gruppe gewährte Erlaubnis';
+$lang['Permission granted'] = 'Zugriff erlaubt';
+$lang['Picture informations updated'] = 'Elementinformationen aktualisiert';
+$lang['Plugins'] = 'Plugins';
+$lang['Position'] = 'Position';
+$lang['Preferences'] = 'Einstellungen';
+$lang['Properties'] = 'Eigenschaften';
+$lang['Random picture'] = 'zufälliges Bild';
+$lang['Rate date'] = 'Bewertungsdatum';
+$lang['Rating by guests'] = 'Erlaube Bewertung(en) durch Gäste';
+$lang['Rating'] = 'Bewertungen';
+$lang['Reject All'] = 'alle abweisen';
+$lang['Reject'] = 'abweisen';
+$lang['Representant'] = 'Vorschaubild';
+$lang['Representation of categories'] = 'Galerievorschaubild';
+$lang['Representative'] = 'Vorschaubild';
+$lang['Represents'] = 'Ist Vorschaubild für diese Kategorien';
+$lang['Save order'] = 'Reihenfolge speichern';
+$lang['Save to permalink history'] = 'Speichere in der permalink history';
+$lang['Select at least one category'] = 'Mindestens eine Kategorie auswählen';
+$lang['Select at least one picture'] = 'Mindestens ein Element auswählen';
+$lang['Select at least one user'] = 'Mindestens einen Benutzer auswählen';
+$lang['Show info'] = 'Info anzeigen';
+$lang['Site manager'] = 'Seitenmanager';
+$lang['Status'] = 'Benutzerstatus';
+$lang['Statistics'] = 'Statistik';
+$lang['Storage category'] = 'Speicherkategorie';
+$lang['Sum of rates'] = 'Summe der Bewertungen';
+$lang['Tag "%s" already exists'] = 'Tag "%s" existiert bereits';
+$lang['Tag "%s" was added'] = 'Tag "%s" wurde hinzugefügt';
+$lang['Tag selection'] = 'Tag Auswahl';
+$lang['Take selected elements out of caddie'] = 'Entferne markierte Elemente aus dem Sammelkorb';
+$lang['The %d following tag were deleted'] = 'Der folgende Tag wird gelöscht';
+$lang['The %d following tags were deleted'] = 'Die %d folgenden Tags werden gelöscht :';
+$lang['Unable to check for upgrade since allow_url_fopen is disabled.'] = 'Kann nicht nach Upgrade suchen, weil allow_url_fopen deaktiviert ist.';
+$lang['Uninstall'] = 'Deinstallieren';
+$lang['Use default sort order']='Nutze die Voreingestellte Sortieroption (Festgelegt in der Konfigurationsdatei)';
+$lang['User comments validation'] = 'Kommentare warten auf Freigabe';
+$lang['Users'] = 'Benutzer';
+$lang['Validate All'] = 'Gebe alle frei';
+$lang['Validate'] = 'Freigeben';
+$lang['Validation'] = 'Freigabe durch Admin';
+$lang['Version'] = 'Version';
+$lang['Virtual categories movement'] = 'Verschieben virtueller Kategorien';
+$lang['Virtual categories to move'] = 'Wähle eine oder mehrere Virtuelle Kategorien aus um sie zu verschieben';
+$lang['Virtual category name'] = 'Virtuelle Kategoriename';
+$lang['Webmaster cannot be deleted'] = 'Webmaster kann nicht gelöscht werden';
+$lang['You are running on development sources, no check possible.'] = 'Sie benutzen eine Entwicklerversion von Piwigo, es kann keine Suche nach Aktualisierungen vorgenommen werden.';
+$lang['You cannot delete your account'] = "Du kannst deinen eigenen Acount nicht löschen";
+$lang['You cannot move a category in its own sub category'] = 'Sie können eine Kategorie nicht in ihre eigene Unterkategorie verschieben.';
+$lang['You need to confirm deletion'] = 'Löschen bitte bestätigen';
+$lang['add tags'] = 'Tags hinzufügen';
+$lang['adviser'] = 'Berater';
+$lang['associate to category'] = 'Mit Kategorie verbinden';
+$lang['associate to group'] = 'Mit Gruppe verbinden';
+$lang['authorized'] = 'Freigegebene Kategorien';
+$lang['cat_add'] = 'Virtuelle Kategorie hinzufügen';
+$lang['cat_comments_title'] = 'Benutzern erlauben, in ausgewählten Kategorien Kommentare zu schreiben';
+$lang['cat_error_name'] = 'Name der Kategorie darf nicht leer sein.';
+$lang['cat_lock_title'] = 'Kategorie schließen';
+$lang['cat_private'] = 'Private Kategorie';
+$lang['cat_public'] = 'öffentliche Kategorie';
+$lang['cat_representant'] = 'Bestimme ein neues zufälliges Vorschaubild';
+$lang['cat_security'] = 'öffentlich / Privat';
+$lang['cat_status_title'] = 'Berechtigungen für ausgewählte Kategorien verwalten';
+$lang['cat_upload_title'] = 'Wähle Uploadkategorie aus';
+$lang['cat_virtual_added'] = 'Virtuelle Kategorie hinzugefügt';
+$lang['cat_virtual_deleted'] = 'Virtuelle Kategorie gelöscht';
+$lang['category'] = 'Kategorie';
+$lang['conf_access'] = 'Zugangsart';
+$lang['conf_comments_title'] = 'Benutzerkommentare';
+$lang['conf_confirmation'] = 'änderungen wurden gespeichert';
+$lang['conf_display'] = 'Standartanzeige';
+$lang['conf_history_title'] = 'Statistik';
+$lang['conf_gallery_url_error'] = 'Die URL der Galerie ist falsch.';
+$lang['conf_main_title'] = 'Grundeinstellungen';
+$lang['conf_nb_comment_page_error'] = 'Anzahl Kommentare pro Seite muß zwischen 5 und 50 liegen.';
+$lang['config'] = 'Konfiguration';
+$lang['confirm'] = 'bestätigen';
+$lang['date'] = 'Datum';
+$lang['delete category'] = 'Lösche Kategorie';
+$lang['dissociate from category'] = 'Von Kategorie abtrennen';
+$lang['dissociate from group'] = 'Von Gruppe abtrennen';
+$lang['edit category permissions'] = 'Berechtigungen für Kategorie ändern';
+$lang['editcat_confirm'] = 'Kategorieinformationen erfolgreich aktualisiert.';
+$lang['editcat_uploadable'] = 'Erlaube upload';
+$lang['elements per page'] = 'Elemente pro Seite';
+$lang['elements'] = 'Elemente';
+$lang['enabled_high'] = 'High definition eingeschaltet';
+$lang['file'] = 'Datei';
+$lang['filesize'] = 'Dateigröße';
+$lang['first element added on %s'] = 'Erstes Element hinzugefügt am %s';
+$lang['forbidden'] = 'Gesperrte Kategorien';
+$lang['conf_general'] = 'Grundeinstellungen';
+$lang['global mode'] = 'Gobaler Modus';
+$lang['group "%s" added'] = 'Gruppe "%s" ninzugefügt';
+$lang['group "%s" deleted'] = 'Gruppe "%s" gelöscht';
+$lang['group "%s" updated'] = 'Gruppe "%s" aktualisiert';
+$lang['group'] = 'Gruppe';
+$lang['group_add_error1'] = 'Der Gruppenname darf kein " oder \' enthalten oder leer bleiben.';
+$lang['group_add_error2'] = 'Diesen Gruppenname gibt es schon.';
+$lang['groups'] = 'Gruppen';
+$lang['instructions'] = 'Anleitungen';
+$lang['is_high_disabled'] = '';
+$lang['is_high_enabled'] = 'High definition';
+$lang['jump to category'] = 'Gehe zu Kategorie';
+$lang['jump to image'] = 'Gehe zu Element';
+$lang['leave'] = 'Beibehalten';
+$lang['lock'] = 'Schließen';
+$lang['locked'] = 'Geschlossen';
+$lang['manage category elements'] = 'Kategorieelemente verwalten';
+$lang['manage sub-categories'] = 'Unterkategorien verwalten';
+$lang['manage'] = 'Verwalten';
+$lang['maximum height'] = 'maximale Höhe';
+$lang['maximum width'] = 'maximale Breite';
+$lang['nbm_background_treatment_redirect_second'] = 'Ausführungszeit ist beendet, Vorgang muss manuell fortgesetzt werden [Verstrichene Zeit: %d Sekunde].';
+$lang['nbm_background_treatment_redirect_seconds'] = 'Ausführungszeit ist beendet, Vorgang muss manuell fortgesetzt werden [Verstrichene Zeit: %d Sekunden].';
+$lang['nbm_break_timeout_list_user'] = 'Die vorgesehene Zeit zum versenden von E-Mail ist begrenzt. Andere Benutzer werden nicht aufgelistet.';
+$lang['nbm_break_timeout_send_mail'] = 'Die Zeit zum E-Mail versenden ist begrenzt. Nicht abgearbeitete Mails werden übersprungen';
+$lang['nbm_col_check_user_send_mail'] = 'Info-Mail schicken?';
+$lang['nbm_col_last_send'] = 'Letzter Versand';
+$lang['nbm_col_mail'] = 'email';
+$lang['nbm_col_user'] = 'Benutzer';
+$lang['nbm_complementary_mail_content'] = 'Detaillierter Inhalt der Beachrichtigungsmail';
+$lang['nbm_content_byebye'] = 'Bis bald,';
+$lang['nbm_content_goto_1'] = 'Gehe zu ';
+$lang['nbm_content_goto_2'] = '.';
+$lang['nbm_content_hello_1'] = 'Hallo ';
+$lang['nbm_content_hello_2'] = ',';
+$lang['nbm_content_new_elements'] = 'Neue Bilder wurden der Galerie hinzugefügt zwischen dem';
+$lang['nbm_content_new_elements_single'] = ' an ';
+$lang['nbm_content_new_elements_between_1'] = 'zwischen ';
+$lang['nbm_content_new_elements_between_2'] = ' und dem ';
+$lang['nbm_content_subscribe_by_admin'] = 'Der Webmaster hat dich für die E-Mailbenachrichtigung eingetragen. Das bedeutet nicht, das du "zugemüllt" wirst, sondern gelegentlich eine E-Mail über aktualisierte Bilder/Kategorien in der Bildergalerie. Die E-Mail wird nicht vom System, sondern vom Webmaster selbst ausgelöst. Falls du das als Belästigung empfindest, klicke unten einfach auf den Link "Austragen".';
+$lang['nbm_content_subscribe_by_himself'] = 'Sie sind eingetragen für die Benachrichtigung per E-Mail';
+$lang['nbm_content_subscribe_link'] = 'Zum wieder anmelden';
+$lang['nbm_content_problem_contact'] = 'Bei Problemen oder Fragen sende eine E-Mail an ';
+$lang['nbm_content_pb_contact_object'] = '[NBM] Probleme oder Fragen';
+$lang['nbm_content_unsubscribe_by_admin'] = 'Der Webmaster hat dich für die E-Mailbenachrichtigung ausgetragen';
+$lang['nbm_content_unsubscribe_by_himself'] = 'Sie haben sich ausgetragen für die Benachrichtigung per E-Mail';
+$lang['nbm_content_click_on'] = ', klicke auf diesen Link:';
+$lang['nbm_content_unsubscribe_link'] = 'Zum austragen';
+$lang['nbm_info_send_mail_as'] = 'Bei leerem Inhalt wird der Galerietitel benutzt';
+$lang['nbm_item_notification'] = 'Benachrichtigung';
+$lang['nbm_msg_error_sending_email_to'] = 'Fehler beim Versand an %s [%s].';
+$lang['nbm_msg_mail_sent_to'] = 'E-Mail versendet an %s [%s].';
+$lang['nbm_msg_n_mail_sent'] = '%d E-Mail wurde gesendet.';
+$lang['nbm_msg_n_mails_sent'] = '%d E-Mails wurden gesendet.';
+$lang['nbm_msg_n_mail_not_send'] = '%d E-Mail wurde nicht gesendet.';
+$lang['nbm_msg_n_mails_not_send'] = '%d E-Mails wurden nicht gesendet.';
+$lang['nbm_no_mail_to_send'] = 'Keine E-Mail zu versenden.';
+$lang['nbm_no_user_available_to_send_L1'] = 'Kein Benutzer verfügbar um eine E-Mail zu senden.';
+$lang['nbm_no_user_available_to_send_L2'] = 'Ein Benutzer ist dann verfügbar, wenn es neue Elemente gibt.';
+$lang['nbm_no_user_available_to_send_L3'] = 'Wenn niemand in der Mailingliste eingetragen ist, kannst du keine E-Mails versenden. (Nur der Webmaster erscheint bei Aktualisierungen in dieser Liste).';
+$lang['nbm_no_user_to send_notifications_by_mail'] = 'Kein Benutzer da um Aktualisierungen zu senden.';
+$lang['nbm_object_news'] = 'Neue Elemente wurden der Bildergalerie hinzugefügt';
+$lang['nbm_object_subscribe'] = 'Eintragen zur E-Mailbenachrichtigung';
+$lang['nbm_object_unsubscribe'] = 'Austragen zur E-Mailbenachrichtigung';
+$lang['nbm_param_mode'] = 'Parameter';
+$lang['nbm_redirect_msg'] = 'Processing treatment.'."\n\n".'Please wait...';
+$lang['nbm_repost_submit'] = 'Continue processing treatment';
+$lang['nbm_send_complementary_mail_content'] = 'Zusätzlicher Inhalt der E-Mail';
+$lang['nbm_send_detailed_content'] = 'Sende detallierten Inhalt';
+$lang['nbm_send_mail_as'] = 'Sende E-Mail als';
+$lang['nbm_send_mail_to_users'] = 'Sende Mail an';
+$lang['nbm_send_mode'] = 'Sende';
+$lang['nbm_send_options'] = 'Optionen';
+$lang['nbm_send_submit'] = 'Versand bestätigen';
+$lang['nbm_subscribe_col'] = 'Bestätigt';
+$lang['nbm_subscribe_mode'] = 'Bestätigen';
+$lang['nbm_title_param'] = 'Parameter';
+$lang['nbm_title_send'] = 'Wähle Empfänger';
+$lang['nbm_title_subscribe'] = 'Hinzufügen/Entfernen von Benutzern für die E-Mailbenachrichtigung';
+$lang['nbm_unsubscribe_col'] = 'Entfernt';
+$lang['nbm_updated_param_count'] = '%d Parameter aktualisiert.';
+$lang['nbm_updated_params_count'] = '%d Parameter aktualisiert.';
+$lang['nbm_user_change_enabled_error_on_updated_data_count'] = '%d Benutzer nicht aktualisiert.';
+$lang['nbm_users_change_enabled_error_on_updated_data_count'] = '%d Benutzer nicht aktualisiert.';
+$lang['nbm_user_change_enabled_false'] = 'Benutzer %s [%s] entfernt von der Benachrichtigungsliste.';
+$lang['nbm_user_change_enabled_true'] = 'Benutzer %s [%s] hinzugefügt zur Benachrichtigungsliste.';
+$lang['nbm_user_change_enabled_updated_data_count'] = '%d Benutzer aktualisiert.';
+$lang['nbm_users_change_enabled_updated_data_count'] = '%d Benutzer aktualisiert.';;
+$lang['nbm_user_not_change_enabled_false'] = 'Benutzer %s [%s] nicht entfernt von der Benachrichtigungsliste.';
+$lang['nbm_user_not_change_enabled_true'] = 'Benutzer %s [%s] nicht hinzugefügt zur Benachrichtigungsliste.';
+$lang['nbm_user_x_added'] = 'Benutzer %s [%s] hinzugefügt.';
+$lang['nbm_warning_subscribe_unsubscribe'] = 'WARNUNG: hinzufügen oder entfernen von Benutzern zur Mailingliste erwirkt sofort eine automatische E-Mail an den betreffenden';
+$lang['nbm_send_html_mail'] = 'Sende E-Mail im HTML-Format';
+$lang['nbm_send_recent_post_dates'] = 'Zeige die ersten Bilder als Vorschau in der E-Mail';
+$lang['nbm_info_send_recent_post_dates'] = 'Nur verfügbar, wenn die Benachrichtigungen im HTML-Format verschickt werden';
+$lang['no_write_access'] = 'kein Schreibzugriff';
+$lang['path'] = 'Pfad';
+$lang['permissions'] = 'Berechtigungen';
+$lang['private'] = 'private';
+$lang['properties'] = 'Eigenschaften';
+$lang['public'] = 'öffentlich';
+$lang['purge never used notification feeds'] = 'Lösche alle noch nicht verschickten Benachrichtigungen';
+$lang['purge sessions'] = 'Löschen Sitzungen';
+$lang['randomly represented'] = 'zufälliges Vorschaubild';
+$lang['registration_date'] = 'Registrierungsdatum';
+$lang['remote_site'] = 'Remote-Standort';
+$lang['remote_site_clean'] = 'reinigen';
+$lang['remote_site_clean_hint'] = 'Löschen Sie die Datei listing.xml Remote';
+$lang['remote_site_generate'] = 'generieren listing';
+$lang['remote_site_generate_hint'] = 'listing.xml-Datei generiert auf dem Remote-Standort';
+$lang['remote_site_local_create'] = 'Erstellen dieser Website';
+$lang['remote_site_local_found'] = 'Listing.xml lokalen Datei gefunden wurde für ';
+$lang['remote_site_local_update'] = 'lesen listing.xml lokalen und zu aktualisieren';
+$lang['remote_site_test'] = 'Test';
+$lang['remote_site_test_hint'] = 'testen Remote-Site';
+$lang['remote_site_uncorrect_url'] = 'Die URL einer Remote-Site muss mit "http://" oder "https" und darf als Zeichen, dass "/", "a-zA-Z0-9", "-" oder "_"';
+$lang['remove tags'] = 'Tags entfernen';
+$lang['repair and optimize database'] = 'Reparieren und Optimierung der Datenbank';
+$lang['selection'] = 'Auswahl';
+$lang['set to'] = 'Setzte auf';
+$lang['singly represented'] = 'festgelegtes Vorschaubild';
+$lang['site_already_exists'] = 'Diese Seite gibt es bereits';
+$lang['site_create'] = 'Erstellen Sie eine neue Remote-Site: (URL auf seine create_listing_file.php)';
+$lang['site_created'] = 'erstellt';
+$lang['site_delete'] = 'löschen';
+$lang['site_delete_hint'] = 'Entfernen dieser Seite und alle damit zusammenhängenden Daten';
+$lang['site_deleted'] = 'gelöscht';
+$lang['site_err'] = 'ein Fehler ist aufgetreten';
+$lang['site_err_remote_file_not_found'] = 'Die Datei create_listing_file.php wurde nicht gefunden auf dem Remote-Standort';
+$lang['site_local'] = 'Lokal';
+$lang['site_remote'] = 'Remote -';
+$lang['site_synchronize'] = 'synchronisieren';
+$lang['site_synchronize_hint'] = 'aktualisiert die Datenbank aus den Dateien';
+$lang['status'] = 'Status';
+$lang['storage'] = 'Verzeichnis';
+$lang['sub-categories'] = 'Unterkategorien';
+$lang['synchronize metadata'] = 'Synchronisieren von Meta-Daten';
+$lang['synchronize'] = 'synchronisieren';
+$lang['target'] = 'Ziel';
+$lang['thumbnail'] = 'Thumbnail';
+$lang['title'] = 'Titel';
+$lang['title_categories'] = 'Verwalten von Kategorien';
+$lang['title_configuration'] = 'Konfiguration von Piwigo';
+$lang['title_default'] = 'Verwaltung von Piwigo';
+$lang['title_edit_cat'] = 'Bearbeiten einer Kategorie';
+$lang['title_groups'] = 'Verwalten von Gruppen';
+$lang['title_liste_users'] = 'Liste der Benutzer';
+$lang['title_picmod'] = 'ändern der Informationen eines Bildes';
+$lang['title_thumbnails'] = 'Erstellung von Miniaturansichten';
+$lang['title_update'] = 'Synchronisierung der Datenbank aus den Dateien der';
+$lang['title_upload'] = 'Bilder warten auf Freigabe';
+$lang['tn_all'] = 'alle';
+$lang['tn_alone_title'] = 'Bilder ohne Thumbnail (JPEG-und PNG-only)';
+$lang['tn_err_height'] = 'die Höhe muss größer sein als';
+$lang['tn_err_width'] = 'die Breite muss größer sein als';
+$lang['tn_format'] = 'für das Format der Datei';
+$lang['tn_no_missing'] = 'Keine Miniaturansicht fehlt';
+$lang['tn_no_support'] = 'Bild nicht verfügbar oder wird nicht unterstützt';
+$lang['tn_params_GD'] = 'Version von GD';
+$lang['tn_params_title'] = 'Einstellung der Miniaturisierung';
+$lang['tn_results_gen_time'] = 'generiert in';
+$lang['tn_results_title'] = 'Ergebnis der Verkleinerung';
+$lang['tn_stats'] = 'Allgemeine Statistiken';
+$lang['tn_stats_max'] = 'max Zeit';
+$lang['tn_stats_mean'] = 'durchschnittliche Zeit';
+$lang['tn_stats_min'] = 'min Zeit';
+$lang['tn_stats_nb'] = 'Anzahl verkleinerter Bilder';
+$lang['tn_stats_total'] = 'Gesamtzeit';
+$lang['tn_thisformat'] = 'für dieses Dateiformat';
+$lang['unit mode'] = 'Einzelmodus';
+$lang['unlocked'] = 'Entsperrt';
+$lang['unset'] = 'Lösche Einstellung';
+$lang['up'] = 'Nach oben verschieben';
+$lang['update categories informations'] = 'Kategorieinformationen aktualisieren';
+$lang['update images informations'] = 'Bildinformationen aktualisieren';
+$lang['update'] = 'Synchronisieren';
+$lang['update_cats_subset'] = 'Auf einzelne bestehende Kategorien reduzieren';
+$lang['update_default_title'] = 'Eine Option auswählen';
+$lang['update_display_info'] = 'Sämtliche Informationen anzeigen (hinzugefügte Kategorien und Elemente, gelöschte Kategorien und Elemente)';
+$lang['update_err_pwg_version_differs'] = 'PhpWebGallery version unterscheidet sich von der Remote-Seite';
+$lang['update_err_pwg_version_differs_info'] = 'Die Version von create_listing_file.php auf der Remote-Seite und PhpWebGallery muss die gleiche sein';
+$lang['update_err_remote_listing_not_found'] = 'listing.xml Datei nicht gefunden';
+$lang['update_err_remote_listing_not_found_info'] = 'listing.xml Datei nicht gefunden auf der Remote-Seite. This file is generated by choosing the "generate listing" command in the Site manager';
+$lang['update_error_list_title'] = 'Error Liste';
+$lang['update_errors_caption'] = 'Fehlerüberschrift';
+$lang['update_infos_title'] = 'Detallierte Informationen';
+$lang['update_missing_file_or_dir'] = 'Datei/Ordner Lesefehler';
+$lang['update_missing_file_or_dir_info'] = 'Auf diese Datei/Ordner kann nicht zugegriffen werden (Entweder es existiert nicht oder der Zugriff wurde verwehrt)';
+$lang['update_missing_tn_info'] = 'Ein Bild braucht ein Vorschaubild. Das Vorschaubild muß sich im Unterverzeichnis "thumbnail" des Kategorieverzechnisses befinden. Der Dateiname des Vorschaubildes muß mit dem eingestellten Thumbnail-Vorzeichen beginnen und der Dateityp einem der folgenden entsprechen :';
+$lang['update_missing_tn_short'] = 'Fehlendes Thumbnail';
+$lang['update_nb_del_categories'] = 'Kategorien in der Datenbank gelöscht';
+$lang['update_nb_del_elements'] = 'Elemente in der Datenbank gelöscht';
+$lang['update_nb_elements_metadata_available'] = 'Elemente , deren Metadaten vorhanden sind';
+$lang['update_nb_elements_metadata_sync'] = 'Elemente mit der Meta-Datenbank syncronisiert';
+$lang['update_nb_errors'] = 'Fehler während der Synchronisation';
+$lang['update_nb_new_categories'] = 'Kategorien in der Datenbank hinzugefügt';
+$lang['update_nb_new_elements'] = 'Elemente in der Datenbank hinzugefügt';
+$lang['update_nb_upd_elements'] = 'Elemente in der Datenbank aktualisiert';
+$lang['update_part_research'] = 'Suche nach neuen Elementen in den vorhandenen Ordnern';
+$lang['update_research_added'] = 'hinzugefügt';
+$lang['update_research_deleted'] = 'gelöscht';
+$lang['update_result_metadata'] = 'Metadata Synchronisierung Ergebnisse';
+$lang['update_simulate'] = 'nur Simulation (es werden keine Elemente in der Datenbank verändert)';
+$lang['update_simulation_title'] = '[Simulation]';
+$lang['update_sync_all'] = 'Ordner und Dateien';
+$lang['update_sync_dirs'] = 'Nur Ordner';
+$lang['update_sync_files'] = 'Syncronisiere Dateistruktur mit der Datenbank';
+$lang['update_sync_metadata'] = 'Syncronisiere Metadaten mit den Informationen in der Datenbank';
+$lang['update_sync_metadata_all'] = 'auch bereits synchronisierte Elemente';
+$lang['update_used_metadata'] = 'Benutzte Metadaten';
+$lang['update_wrong_dirname_info'] = 'Der Verzeichnis- und der Dateiname muß aus Buchstaben oder den Zeichen "-", "_" oder "." bestehen';
+$lang['update_wrong_dirname_short'] = 'Falscher Dateiname';
+$lang['upload'] = 'Upload';
+$lang['user "%s" added'] = 'Benutzer "%s" hinzugefügt';
+$lang['user_status'] = 'Status des Benutzers';
+$lang['user_status_admin'] = 'Administrator';
+$lang['user_status_generic'] = 'Allgemein';
+$lang['user_status_guest'] = 'Gast';
+$lang['user_status_normal'] = 'Besucher';
+$lang['user_status_webmaster'] = 'Webmaster';
+$lang['username'] = 'Benutzername';
+$lang['users'] = 'Benutzer';
+$lang['virtual_category'] = 'Virtuelle Kategorie';
+$lang['waiting'] = 'Wartend auf Freigabe';
+$lang['is_default_group'] = 'Standard';
+$lang['toggle_is_default_group'] = 'Setze die Einstellungen der Gruppe zurück auf Voreinstellung für alle Benutzer';
+$lang['Advanced_features'] = 'Erweiterte Einstellungen';
+$lang['Elements_not_linked'] = 'Nicht verlinkte Elemente';
+$lang['special_admin_menu'] = 'Erweiterte Verwaltung';
+$lang['Duplicates'] = 'Finde Dateien mit dem gleichen Dateiname';
+
+$lang['Overall'] = 'überall';
+$lang['Year'] = 'Jahr';
+$lang['Month'] = 'Monat';
+$lang['Day'] = 'Tag';
+$lang['Pages seen'] = 'Seitenzugriffe';
+$lang['Pictures'] = 'Bilder';
+$lang['time'] = 'Zeit';
+$lang['user'] = 'Benutzer';
+$lang['IP'] = 'IP';
+$lang['image'] = 'Bilder';
+$lang['section'] = 'Abschnitt';
+$lang['tags'] = 'tags';
+$lang['conf_history_guest'] = 'Speichere Seitenaufrufe von Gästen';
+$lang['conf_history_user'] = 'Speichere Seitenaufrufe pro Benutzer';
+$lang['conf_history_admin'] = 'Speichere auch Seitenaufrufe des Administrators';
+$lang['cat_options_title'] = 'Eigenschaften';
+$lang['An information email was sent to group "%s"'] = 'Eine Info-E-Mail wurde gesendet an die Gruppe "%s';
+$lang['Send an information email to group members'] = 'Sende eine Info-E-Mail an die Mitglieder dieser Gruppe';
+$lang['Group'] = 'Gruppe';
+$lang['[%s] Come to visit the category %s'] = '[%s] Es gibt Neues im Bilderordner %s';
+$lang['Hello,'] = 'Hallo,';
+$lang['See you soon.'] = 'Bis bald.';
+$lang['Come to discover the category:'] = 'Folge dem Link und besuche den Bilderordner:';
+$lang['mail_content'] = 'Text der E-Mail';
+$lang['none'] = 'egal';
+$lang['high'] = 'hoch';
+$lang['other'] = 'anderes';
+$lang['Element type'] = 'Element Typ';
+$lang['User'] = 'Benutzer';
+$lang['Image id'] = 'Element-ID';
+$lang['Summary'] = 'Zusammenfassung';
+$lang['%d line filtered'] = '%d Zeile gefiltert';
+$lang['%d lines filtered'] = '%d Zeilen gefiltert';
+$lang['%d guest'] = '%d Gast';
+$lang['%d guests'] = '%d Gäste';
+$lang['Hour'] = 'Stunde';
+$lang['is_the_guest'] = 'Gast';
+$lang['is_the_default'] = 'Standardwerte';
+$lang['High filesize'] = 'HQ Dateigröße';
+// --------- Starting below: New or revised $lang ---- from version 1.7.1
+$lang['Guest cannot be deleted'] = 'Der Gast kann nicht gelöscht werden';
+$lang['Default user cannot be deleted'] = 'Der Standardbenutzer kann nicht gelöscht werden';
+$lang['purge history detail'] = 'Lösche History detailliert';
+$lang['purge history summary'] = 'Lösche History gesamt';
+$lang['c13y_title'] = 'überprüfung der Integrität';
+$lang['c13y_Anomaly'] = 'Anomalie';
+$lang['c13y_Correction'] = 'Korrektur';
+$lang['c13y_Automatic_correction'] = 'Automatische Korrektur';
+$lang['c13y_Impossible_automatic_correction'] = 'Automatische Korrektur nicht möglich';
+$lang['c13y_Correction_applied_success'] = 'Korrektur erfolgreich';
+$lang['c13y_Correction_applied_error'] = 'Korrektur mit Fehler';
+$lang['c13y_anomaly_count'] = '%d Anomalie entdeckt wurde.';
+$lang['c13y_anomalies_count'] = '%d Anomalien festgestellt wurden.';
+$lang['c13y_anomaly_corrected_count'] = '%d Anomalie wurde behoben.';
+$lang['c13y_anomalies_corrected_count'] = '%d Anomalien wurde behoben.';
+$lang['c13y_anomaly_not_corrected_count'] = '%d Anomalie konnte nicht behoben werden.';
+$lang['c13y_anomalies_not_corrected_count'] = '%d Anomalien konnte nicht behoben werden.';
+$lang['c13y_more_info'] = 'Gehen Sie %s oder %s für weitere Informationen';
+$lang['c13y_more_info_forum'] = 'das Forum';
+$lang['c13y_more_info_wiki'] = 'das wiki';
+$lang['c13y_exif_anomaly'] = 'Der Wert %s ist nicht korrekt weil EXIF nicht unterstützt wird';
+$lang['c13y_exif_correction'] = '%s muss auf "false" in Ihrer Datei config_local.inc.php';
+$lang['c13y_guest_non_existent'] = 'Der Benutzer "Gast" Haupt nicht mehr';
+$lang['c13y_bad_guest_status'] = 'Der Status der Benutzer "Gast" ist falsch';
+$lang['c13y_default_non_existent'] = 'Der Benutzer standardmäßig nicht mehr';
+$lang['c13y_webmaster_non_existent'] = 'Der Benutzer "Webmaster" Haupt nicht mehr';
+$lang['c13y_bad_webmaster_status'] = 'Der Status des Benutzers "Webmaster" ist falsch';
+$lang['c13y_user_created'] = 'Benutzer "%s" erstellt mit dem Passwort "%s"';
+$lang['c13y_user_status_updated'] = 'Status des Benutzers "%s" aktualisiert';
+$lang['add new elements to caddie'] = 'die neuen Elemente in den Sammelkorb';
+// --------- Starting below: New or revised $lang ---- from Butterfly
+$lang['no_display_thumbnail'] = 'Keine Anzeige';
+$lang['display_thumbnail_classic'] = 'Klassische Ansicht';
+$lang['display_thumbnail_hoverbox'] = 'Anzeige beim überflug';
+$lang['Thumbnails'] = 'Miniaturen';
+$lang['obligatory_user_mail_address'] = 'Die E-Mail-Adresse ist auch für nicht angemeldete Besucher sichtbar';
+$lang['Minimum privacy level'] = 'minimum Privacy level';
+$lang['Privacy level'] = 'Privacy level';
+$lang['Level 0'] = '---';
+$lang['Level 1'] = 'Kontakt';
+$lang['Level 2'] = 'Freunde';
+$lang['Level 4'] = 'Familie';
+$lang['Level 8'] = 'Admins';
+$lang['c13y_maintenance'] = 'prüfe erneut die Integrität';
+$lang['Check all'] = 'Alle auswählen';
+$lang['Uncheck all'] = 'Alles entfernen';
+$lang['c13y_check_auto'] = 'überprüfen Sie automatische Korrekturen';
+$lang['c13y_submit_correction'] = 'Die entsprechenden ausgewählten';
+$lang['c13y_submit_ignore'] = 'Ignorieren Sie gewählte Anomalien';
+$lang['c13y_submit_refresh'] = 'Aktualisieren';
+$lang['c13y_ignore_msg1'] = 'Der Fehler wird ignoriert bis die nächste Version der Anwendung';
+$lang['c13y_ignore_msg2'] = 'Die Korrektur der Anomalie macht die Tatsache sie ignoriert ist';
+$lang['c13y_anomaly_ignored_count'] = '%d Anomalie ignoriert wurde.';
+$lang['c13y_anomalies_ignored_count'] = '%d Anomalien ignoriert wurden.';
+$lang['plugins_need_update'] = 'Für diese Plugins ist ein Update verfügbar';
+$lang['plugins_dontneed_update'] = 'Diese Plugins sind auf dem neuesten Stand';
+$lang['plugins_cant_check'] = 'Konnte die folgenden Plugins nicht prüfen';
+$lang['plugins_actual_version'] = 'Version<br>Aktuelle';
+$lang['plugins_new_version'] = 'Version<br>verfügbar';
+$lang['plugins_auto_update'] = 'Automatisches Update';
+$lang['plugins_auto_install'] = 'Automatische Installation';
+$lang['plugins_download'] = 'Laden Sie die Datei';
+$lang['plugins_tab_list'] = 'Liste der Plugins';
+$lang['plugins_tab_update'] = 'Plugins auf Updates überprüfen';
+$lang['plugins_tab_new'] = 'Zur verfügung stehende Plugins';
+$lang['plugins_revisions'] = 'Aktuelle änderungen';
+$lang['plugins_delete'] = 'Löschen';
+$lang['plugins_confirm_install'] = 'Sind Sie sicher dass Sie dieses Plugin installieren möchten?';
+$lang['plugins_confirm_delete'] = 'Sind Sie sicher dass Sie dieses Plugin löschen möchten?';
+$lang['plugins_confirm_upgrade'] = 'Sind Sie sicher dass Sie dieses Plugin installieren möchten? Stellen sicher, dass die vorhergehende Version nicht deinstalliert werden muss.';
+$lang['plugins_upgrade_ok'] = '%s wurde erfolgreich aktualisiert.';
+$lang['plugins_install_ok'] = 'Das Plugin wurde erfolgreich installiert.';
+$lang['plugins_install_need_activate'] = 'Gehen Sie in die "Liste der Plugins" um installierte Plugins zu aktivieren.';
+$lang['plugins_temp_path_error'] = 'Temporäre Datei kann nicht erstellt .';
+$lang['plugins_dl_archive_error'] = 'Kann Archiv nicht downloaden.';
+$lang['plugins_archive_error'] = 'Kann das Archiv nicht lesen oder entpacken.';
+$lang['plugins_extract_error'] = 'Fehler beim entpacken des Archives(%s).';
+$lang['plugins_check_chmod'] = 'überprüfen Sie die Berechtigungen des Ordners "Plugins" und dessen Unterordner (CHMOD).';
+$lang['plugins_server_error'] = 'Es konnte keine Verbindung zum Server hergestellt werden.';
+$lang['Purge compiled templates'] = 'Löschen kompilierten Templates';
+$lang['Caddie is currently empty'] = 'Der Sammelkorb ist derzeit leer.';
+$lang['DEMO'] = 'Demo';
+$lang['HOME'] = 'Home Piwigo';
+$lang['FORUM'] = 'Support';
+$lang['BUGS'] = 'Bugs';
+$lang['EXTENSIONS'] = 'Erweiterungen';
+$lang['WIKI / DOC'] = 'Dokumentation';
+$lang['conf_upload_title'] = 'Download';
+$lang['Show upload link every time'] = 'Den Uploadlink immer anzeigen';
+$lang['User access level to upload'] = 'Benutzer dürfen Bilder hochladen';
+$lang['ACCESS_0'] = 'Frei';
+$lang['ACCESS_1'] = 'Alle';
+$lang['ACCESS_2'] = 'Mitglieder';
+$lang['ACCESS_3'] = 'Administratoren';
+$lang['ACCESS_4'] = 'Webmaster';
+$lang['ACCESS_5'] = 'Kein Zugriff';
+$lang['A new version of Piwigo is available.'] = 'Es steht eine neue Version von Piwigo zur Verfügung.';
+$lang['Piwigo Administration'] = 'Verwaltung von Piwigo';
+$lang['Piwigo version'] = 'Version von Piwigo';
+$lang['You are running the latest version of Piwigo.'] = 'Sie verwenden die neueste Version von Piwigo.';
+$lang['c13y_version_anomaly'] = 'Die Version %s [%s] ist installiert und ist nicht mit der erforderlichen Version kompatibel [%s]';
+$lang['c13y_version_correction'] = 'Sie müssen Ihr System zu aktualisieren, um vollen Nutzen aus der Anwendung nicht die Anwendung funktioniert nicht richtig oder gar nicht';
+$lang['Deleted on'] = 'Gelöscht am';
+$lang['Last hit'] =  'Letzter Zugriff';
+$lang['Hits'] = 'Verwendungen';
+$lang['GD library is missing'] = 'die GD-Library ist nicht vorhanden';
+$lang['conf_extents'] = 'Templates (Modelle)';
+$lang['extend_for_templates'] = 'Extend für Vorlagen';
+$lang['Replacement of original templates'] = 'Anstelle der ursprünglichen Templates von Template-Ordner an des Template-Erweiterung';
+$lang['Replacers'] = 'Stellvertreter (Templates geändert)';
+$lang['Original templates'] = 'Originales Templates';
+$lang['Optional URL keyword'] = 'Optionale Parameter in der URL';
+$lang['Templates recorded.'] = 'Die Konfiguration der Templates gespeichert wurde.';
+$lang['Optimizations completed'] = 'Alle Optimierungen wurden erfolgreich abgeschlossen.';
+$lang['Optimizations errors'] = 'Einige Optimierungen endeten mit Fehlern.';
+$lang['delete this comment'] = 'Diesen Kommentar löschen';
+$lang['link_info_image'] = 'Informationen ändern';
+$lang['edit category informations'] = 'bearbeiten die Informationen in dieser Kategorie';
+$lang['nothing'] = 'nichts';
+$lang['overrides existing values with empty ones'] = 'überschreibt vorhandene Werte mit leeren';
+$lang['manage image ranks'] = 'verwaltung der Reihenfolge der Bilder';
+$lang['Manage image ranks'] = 'Verwalten Sie die Reihenfolge der Bilder';
+$lang['Edit ranks'] = 'Die Reihenfolge ändern';
+$lang['No element in this category'] = 'Kein Eintrag in dieser Kategorie';
+$lang['Images manual order was saved'] = 'Die manuelle Reihenfolge der Bilder wurde gespeichert';
+$lang['ranks'] = 'Reihenfolge';
+$lang['Drag to re-order'] = 'Klicken und Ziehen um eine neue Reihenfolge festzulegen';
+$lang['Unable to retrieve server informations since allow_url_fopen is disabled.'] = 'Es konnte keine Verbindung zum Server, da die Funktion allow_url_fopen deaktiviert ist.';
+$lang['Quick Local Synchronization'] = 'Schnelle Synchronisierung';
+$lang['No photo can be deleted'] = 'Kein Foto kann gelöscht werden';
+$lang['Note: Only deletes photos added with pLoader'] = 'Bitte beachten: Nur über pLoader Fotos entfernt werden können';
+$lang['Delete selected photos'] = 'Fotos löschen';
+$lang['%d photo was deleted'] = '%d Foto wurde gelöscht';
+$lang['%d photos were deleted'] = '%d Fotos wurden gelöscht';
+$lang['Bound template'] = 'Verbundenes Template';
+/* TODO */ $lang['Downloads'] = 'Downloads';
+/* TODO */ $lang['Released on'] = 'Released on';
+/* TODO */ $lang['Number of downloads'] = 'Number of downloads';
+?>
Index: /tags/2.0.2/language/de_DE/common.lang.php
===================================================================
--- /tags/2.0.2/language/de_DE/common.lang.php	(revision 3278)
+++ /tags/2.0.2/language/de_DE/common.lang.php	(revision 3278)
@@ -0,0 +1,368 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Langage informations
+$lang_info['language_name'] = 'Deutsch';
+$lang_info['country'] = 'Deutschland';
+$lang_info['direction'] = 'ltr';
+$lang_info['code'] = 'de';
+$lang_info['zero_plural'] = false;
+
+$lang['%.2f (rated %d times, standard deviation = %.2f)'] = '%.2f (beachtet %d mal, Standardabweichung  = %.2f)';
+$lang['%d Kb'] = '%d Kb';
+$lang['%d category updated'] = '%d Kategorie wurde aktualisiert';
+$lang['%d categories updated'] = '%d Kategorien wurden aktualisiert';
+$lang['%d comment to validate'] = '%d Kommentar freizuschalten';
+$lang['%d comments to validate'] = '%d Kommentare freizuschalten';
+$lang['%d new comment'] = '%d neuer Kommentar';
+$lang['%d new comments'] = '%d neue Kommentare';
+$lang['%d comment'] = '%d Kommentar';
+$lang['%d comments'] = '%d Kommentare';
+$lang['%d hit'] = '%d Aufruf';
+$lang['%d hits'] = '%d Aufrufe';
+$lang['%d new element'] = '%d neues Element';
+$lang['%d new elements'] = '%d neue Elemente';
+$lang['%d new user'] = '%d neuer Benutzer';
+$lang['%d new users'] = '%d neue Benutzer';
+$lang['%d waiting element'] = '%d Element in der Warteschlange';
+$lang['%d waiting elements'] = '%d Elemente in der Warteschlange';
+$lang['About'] = 'über uns';
+$lang['All tags must match'] = 'Alle Tags müssen übereinstimmen';
+$lang['All tags'] = 'Alle Tags';
+$lang['Any tag'] = 'Beliebigen Tag';
+$lang['At least one listed rule must be satisfied.'] = 'Mindestens eine aufgelistete Regel muss übereinstimmen.';
+$lang['At least one tag must match'] = 'Mindestens ein Tag muss übereinstimmen';
+$lang['Author'] = 'Autor';
+$lang['Average rate'] = 'Durchschnittliche Bewertung';
+$lang['Categories'] = 'Kategorien';
+$lang['Category'] = 'Kategorie';
+$lang['Close this window'] = 'Dieses Fenster schließen';
+$lang['Complete RSS feed'] = 'RSS-Feeds komplett (Bilder, Kommentare)';
+$lang['Confirm Password'] = 'Neues Passwort bestätigen';
+$lang['Connection settings'] = 'Login-Einstellungen';
+$lang['Connection'] = 'Anmeldung';
+$lang['Contact webmaster'] = 'Mail an den Webmaster';
+$lang['Create a new account'] = 'Erstellen Sie ein neues Konto';
+$lang['Created on'] = 'Erstellt am';
+$lang['Creation date'] = 'Erstellungsdatum';
+$lang['Current password is wrong'] = 'aktuelles Passwort ist falsch';
+$lang['Dimensions'] = 'Abmessungen';
+$lang['Display'] = 'Anzeige';
+$lang['Each listed rule must be satisfied.'] = 'Jede aufgelistete Regel muss erfüllt sein';
+$lang['Email address is missing'] = 'Die E-Mail-Adresse fehlt';
+$lang['Email address'] = 'E-Mail-Adresse';
+$lang['Enter your personnal informations'] = 'Geben Sie Ihre persönlichen Daten an';
+$lang['Error sending email'] = 'Fehler beim Senden der Mail';
+$lang['File name'] = 'Name der Datei';
+$lang['File'] = 'Datei';
+$lang['Filesize'] = 'Dateigröße';
+$lang['Filter and display'] = 'Filtern und anzeigen';
+$lang['Filter'] = 'Filter';
+$lang['Forgot your password?'] = 'Passwort vergessen?';
+$lang['Go through the gallery as a visitor'] = 'Besuche die Galerie mit Besucherrechten';
+$lang['Help'] = 'Hilfe';
+$lang['Identification'] = 'Anmeldung';
+$lang['Image only RSS feed'] = 'Bilder RSS-Feed';
+$lang['Keyword'] = 'Stichwort';
+$lang['Links'] = 'Links';
+$lang['Mail address'] = $lang['Email addresse'];
+$lang['N/A'] = 'nicht vorhanden';
+$lang['New on %s'] = 'Neu am %s';
+$lang['New password confirmation does not correspond'] = 'Fehler bei der Bestätigung des Passwortes';
+$lang['New password sent by email'] = 'Neues Passwort per E-Mail zusenden';
+$lang['No email address'] = 'Keine E-Mail-Adresse';
+$lang['No user matches this email address'] = 'Diese E-Mail-Adresse ist nicht bekannt';
+$lang['Notification'] = 'Rss-Feed';
+$lang['Number of items'] = 'Anzahl der Elemente';
+$lang['Original dimensions'] = 'Ursprünglichen Abmessungen';
+$lang['Password forgotten'] = 'Passwort vergessen';
+$lang['Password'] = 'Passwort';
+$lang['Post date'] = 'Eintragsdatum';
+$lang['Posted on'] = 'Eingetragen am';
+$lang['Profile'] = 'Profil';
+$lang['Quick connect'] = 'Schnelle Anmeldung';
+$lang['RSS feed'] = 'RSS-Feed';
+$lang['Rate'] = 'Bewertung';
+$lang['Register'] = 'Registrieren';
+$lang['Registration'] = 'Registrierung';
+$lang['Related tags'] = 'Tags mit';
+$lang['Reset'] = 'Abbrechen';
+$lang['Retrieve password'] = 'Passwort abrufen';
+$lang['Search rules'] = 'Suchkriterien';
+$lang['Search tags'] = 'Tags suchen';
+$lang['Search'] = 'Suchen';
+$lang['See available tags'] = 'Alle verfügbaren Tags';
+$lang['Send new password'] = 'Senden mir ein neues Passwort';
+$lang['Since'] = 'Seit';
+$lang['Sort by'] = 'Sortieren nach';
+$lang['Sort order'] = 'Sortierreihenfolge';
+$lang['Tag'] = 'Tag';
+$lang['Tags'] = 'Tags';
+$lang['The RSS notification feed provides notification on news from this website : new pictures, updated categories, new comments. Use a RSS feed reader.'] = 'Der RSS-Feed teilt die Ereignisse in der Galerie mit: neue Bilder, Gruppen-Updates, neue Benutzer Kommentare. Für die Verwendung mit einem RSS-Reader.';
+$lang['Unknown feed identifier'] = 'Feed-ID unbekanntem';
+$lang['User comments'] = 'Benutzerkommentare';
+$lang['Username'] = 'Benutzername';
+$lang['Visits'] = 'Besuche';
+$lang['Webmaster'] = 'Webmaster';
+$lang['Week %d'] = 'Woche %d';
+$lang['about_page_title'] = 'über Piwigo';
+$lang['access_forbiden'] = 'Sie sind nicht berechtigt die gewünschte Seite aufzurufen';
+$lang['add to caddie'] = 'in den Sammelkorb';
+$lang['add_favorites_hint'] = 'Dieses Bild zu Ihren Favoriten hinzugefügt';
+$lang['admin'] = 'Verwaltung';
+$lang['adviser_mode_enabled'] = 'Berater-Modus aktiv';
+$lang['all'] = 'alle';
+$lang['ascending'] = 'wachsende';
+$lang['author(s) : %s'] = 'Autor(en) : %s';
+$lang['auto_expand'] = 'Entwickeln alle Kategorien';
+$lang['became available after %s (%s)'] = 'zur Verfügung gestellt nachdem die %s (%s)';
+$lang['became available before %s (%s)'] = 'zur Verfügung gestellt, bevor die %s (%s)';
+$lang['became available between %s (%s) and %s (%s)'] = 'zur Verfügung gestellt von %s (%s) und das %s (%s)';
+$lang['became available on %s'] = 'zur Verfügung gestellt am %s';
+$lang['best_rated_cat'] = 'Am besten bewertet';
+$lang['best_rated_cat_hint'] = 'zeigt am besten bewertete Bilder';
+$lang['caddie'] = 'Sammelkorb';
+$lang['calendar'] = 'Kalender';
+$lang['calendar_any'] = 'Alles';
+$lang['calendar_hint'] = 'Anzeige von Jahr zu Jahr, Monat für Monat, Tag für Tag';
+$lang['calendar_picture_hint'] = 'die Bilder des ';
+$lang['calendar_view'] = 'Anblick';
+$lang['chronology_monthly_calendar'] = 'Monatskalender';
+$lang['chronology_monthly_list'] = 'Monatliche Liste';
+$lang['chronology_weekly_list'] = 'Wöchentlichen Liste';
+$lang['click_to_redirect'] = 'Klicken Sie hier, wenn Sie nicht durch ihren Browser weitergeleitet werden.';
+$lang['comment date'] = 'Datum des Kommentars';
+$lang['comment'] = 'Kommentar';
+$lang['comment_added'] = 'Ihr Kommentar wurde gespeichert';
+$lang['comment_anti-flood'] = 'Anti-Spam-Sperre, bitte warte eine Weile, bis du den nächsten Kommentar abgibst';
+$lang['comment_not_added'] = 'Dein Kommentar wurde abgelehnt da er evtl. gesetzte Regeln verletzt';
+$lang['comment_to_validate'] = 'Ein Administrator muss deinen Beitrag freischalten bevor er sichtbar wird.';
+$lang['comment_user_exists'] = 'Dieser Benutzername ist bereits';
+$lang['comments'] = 'Kommentare';
+$lang['comments_add'] = 'Kommentar hinzufügen';
+$lang['created after %s (%s)'] = 'erstellt nach dem %s (%s)';
+$lang['created before %s (%s)'] = 'erstellt vor dem %s (%s)';
+$lang['created between %s (%s) and %s (%s)'] = 'erstellt von %s (%s) und das %s (%s)';
+$lang['created on %s'] = 'erstellt am %s';
+$lang['customize'] = 'Benutzerdaten / Layout';
+$lang['customize_page_title'] = 'Anpassung des Seitentitels ';
+$lang['day'][0] = 'Sonntag';
+$lang['day'][1] = 'Montag';
+$lang['day'][2] = 'Dienstag';
+$lang['day'][3] = 'Mittwoch';
+$lang['day'][4] = 'Donnerstag';
+$lang['day'][5] = 'Freitag';
+$lang['day'][6] = 'Samstag';
+$lang['default_sort'] = 'Standardmäßig';
+$lang['del_favorites_hint'] = 'dieses Bild löschen Favoriten';
+$lang['delete'] = 'Löschen';
+$lang['descending'] = 'absteigend';
+$lang['download'] = 'herunterladen';
+$lang['download_hint'] = 'Download dieser Datei';
+$lang['edit'] = 'bearbeiten';
+$lang['err_date'] = 'Datum falsch';
+$lang['excluded'] = 'ausgeschlossen';
+$lang['favorite_cat'] = 'Meine Favoriten';
+$lang['favorite_cat_hint'] = 'meine Lieblingsbilder';
+$lang['favorites'] = 'Favoriten';
+$lang['first_page'] = 'Erste';
+$lang['gallery_locked_message'] = 'Die Galerie ist gesperrt wegen Wartungsarbeiten. Bitte besuchen Sie uns später wieder.';
+$lang['generation_time'] = 'Seite erstellt in';
+$lang['guest'] = 'Besucher';
+$lang['hello'] = 'Hallo';
+$lang['hint_admin'] = 'nur für Administratoren';
+$lang['hint_category'] = 'zeigt die Bilder an der Wurzel dieser Kategorie';
+$lang['hint_comments'] = 'Zeige die letzten Kommentare Benutzer';
+$lang['hint_customize'] = 'das Aussehen der Galerie';
+$lang['hint_search'] = 'Suche';
+$lang['home'] = 'Startseite';
+$lang['identification'] = 'Verwaltung';
+$lang['images_available_cpl'] = 'in dieser Kategorie';
+$lang['images_available_cat'] = 'in %d Unterkategorie';
+$lang['images_available_cats'] = 'in %d Unterkategorien';
+$lang['included'] = 'enthalten';
+$lang['invalid_pwd'] = 'Passwort ungültig!';
+$lang['language'] = 'Sprache';
+$lang['last %d days'] = '%d lezte Tage';
+$lang['last_page'] = 'Letzte Seite';
+$lang['logout'] = 'Abmelden';
+$lang['mail_address'] = $lang['Email address'];
+$lang['mandatory'] = 'obligatorisch';
+$lang['maxheight'] = 'Maximale Höhe der Bilder';
+$lang['maxheight_error'] = 'Die maximale Höhe der Bilder muss mehr als 50';
+$lang['maxwidth'] = 'Maximale Breite der Bilder';
+$lang['maxwidth_error'] = 'Die Breite der Bilder muss mehr als 50';
+$lang['mode_created_hint'] = 'Anzeigen eines Kalenders nach Erstellungsdatum';
+$lang['mode_flat_hint'] = 'anzuzeigen zu flach die Kategorien und Unterkategorien';
+$lang['mode_normal_hint'] = 'Zurück zur normalen Ansicht';
+$lang['mode_posted_hint'] = 'Anzeigen eines Kalenders von Datum hinzugefügt';
+$lang['month'][10] = 'Oktober';
+$lang['month'][11] = 'November';
+$lang['month'][12] = 'Dezember';
+$lang['month'][1] = 'Januar';
+$lang['month'][2] = 'Februar';
+$lang['month'][3] = 'März';
+$lang['month'][4] = 'April';
+$lang['month'][5] = 'Mai';
+$lang['month'][6] = 'Juni';
+$lang['month'][7] = 'Juli';
+$lang['month'][8] = 'August';
+$lang['month'][9] = 'September';
+$lang['most_visited_cat'] = 'Am häufigsten gesehen';
+$lang['most_visited_cat_hint'] = 'zeigt am meisten besuchte Bilder';
+$lang['nb_image_line_error'] = 'Die Anzahl der Bilder pro Reihe muss mindestens 1 sein';
+$lang['nb_image_per_row'] = 'Anzahl der Bilder pro Zeile';
+$lang['nb_line_page_error'] = 'Die Anzahl der Zeilen pro Seite muss mindestens 1 sein';
+$lang['nb_row_per_page'] = 'Anzahl der Zeilen pro Seite';
+$lang['nbm_unknown_identifier'] = 'Identifikatoren unbekannt';
+$lang['new_password'] = 'Neues Passwort';
+$lang['new_rate'] = 'Bewerten Sie dieses Bild';
+$lang['next_page'] = 'Vorwärts';
+$lang['no_category'] = 'Startseite';
+$lang['no_rate'] = 'noch keine Bewertung';
+$lang['note_filter_day'] = 'Es werden nur Elemente angezeigt, die innerhalb des letzten Tages hochgeladen wurden.';
+$lang['note_filter_days'] = 'Es werden nur Elemente angezeigt, die innerhalb der letzten %d Tage hochgeladen wurden.';
+$lang['password updated'] = 'Passwort aktualisiert';
+$lang['periods_error'] = 'Der Zeitraum der Neuheit muss eine positive ganze Zahl';
+$lang['picture'] = 'Bild';
+$lang['picture_high'] = 'Klicken Sie auf das Bild für die Anzeige in High Definition';
+$lang['picture_show_metadata'] = 'Zeigen die Meta-Daten in der Datei';
+$lang['powered_by'] = 'Unterstützt von';
+$lang['preferences'] = 'Einstellungen';
+$lang['previous_page'] = 'Zurück';
+$lang['random_cat'] = 'Zufallsbilder';
+$lang['random_cat_hint'] = 'Anzeigen eines zufälligen Bilder';
+$lang['recent_cats_cat'] = 'Neue Kategorien';
+$lang['recent_cats_cat_hint'] = 'Kategorien anzuzeigen, die kürzlich aktualisiert oder erstellt wurden';
+$lang['recent_period'] = 'Wieviele Tage sollen Bilder als "neu" markiert werden?';
+$lang['recent_pics_cat'] = 'Die neuesten Bilder';
+$lang['recent_pics_cat_hint'] = 'zeigt die neuesten Bilder';
+$lang['redirect_msg'] = 'Umleitung ...';
+$lang['reg_err_login1'] = 'Bitte geben Sie einen Benutzernamen ein';
+$lang['reg_err_login2'] = 'Benutzername darf nicht mit einem Leerzeichen enden';
+$lang['reg_err_login3'] = 'Login dürfen nicht mit einem Leerzeichen anfangen';
+$lang['reg_err_login5'] = 'Diesen Benutzername ist bereits vergeben';
+$lang['reg_err_mail_address'] = 'E-Mail-Adresse muss in der Form xxx@yyy.eee (Beispiel: jack@altern.org)';
+$lang['reg_err_pass'] = 'Bitte geben Sie erneut Ihr Passwort ein';
+$lang['remember_me'] = 'Auto-Login';
+$lang['remove this tag'] = 'entfernen diesem Tag in der Liste';
+$lang['representative'] = 'representativ';
+$lang['return to homepage'] = 'Zurück zur Homepage';
+$lang['search_author'] = 'Suche nach Autor';
+$lang['search_categories'] = 'Suche in Kategorien';
+$lang['search_date'] = 'Suche nach Datum';
+$lang['search_date_from'] = 'Datum';
+$lang['search_date_to'] = 'Enddatum';
+$lang['search_date_type'] = 'Datumstyp';
+$lang['search_keywords'] = 'Suche nach Wort';
+$lang['search_mode_and'] = 'Suche alle Wörter';
+$lang['search_mode_or'] = 'Wörter suchen';
+$lang['search_one_clause_at_least'] = 'Abfrage leer. Kein Kriterium zur Verfügung.';
+$lang['search_options'] = 'Suchoptionen';
+$lang['search_result'] = 'Suchergebnisse';
+$lang['search_subcats_included'] = 'Suche in Unterkategorien';
+$lang['search_title'] = 'Suche';
+$lang['searched words : %s'] = 'Suchbegriffe : %s';
+$lang['send_mail'] = 'Kontakt';
+$lang['set as category representative'] = 'Als Vorschaubild dieser Kategorie';
+$lang['show_nb_comments'] = 'Zeige die Anzahl der Kommentare';
+$lang['show_nb_hits'] = 'Zeige die Anzahl der Bildaufrufe';
+$lang['slideshow'] = 'Diashow';
+$lang['slideshow_stop'] = 'Stop die Diashow';
+$lang['special_categories'] = 'Erweitert';
+$lang['sql_queries_in'] = 'SQL-Abfragen in';
+$lang['start_filter_hint'] = 'zeigt erst vor kurzem gebucht Bilder';
+$lang['stop_filter_hint'] = 'Zurück zur Anzeige aller Elemente';
+$lang['the beginning'] = 'Beginn';
+$lang['theme'] = 'Galerie-Layout';
+$lang['thumbnails'] = 'Thumbnails';
+$lang['title_menu'] = 'Menü';
+$lang['title_send_mail'] = 'Ein Kommentar auf der Website';
+$lang['today'] = 'heute';
+$lang['update_rate'] = 'Aktualisieren Ihre Bewertung';
+$lang['update_wrong_dirname'] = 'ungültiger Verzeichnisname';
+$lang['upload_advise_filesize'] = 'die Datei darf nicht größer sein als: ';
+$lang['upload_advise_filetype'] = 'das Bild muss im Dateiformat JPG, GIF, oder PNG sein';
+$lang['upload_advise_height'] = 'die maximale Bildhöhe darf nicht überschritten werden: ';
+$lang['upload_advise_thumbnail'] = 'Optional, aber empfohlen: Wählen Sie ein Miniaturbild, um zu ';
+$lang['upload_advise_width'] = 'die Breite des Bildes darf nicht überschreiten: ';
+$lang['upload_author'] = 'Autor';
+$lang['upload_cannot_upload'] = 'Das Bild kann nicht hochgeladen werden';
+$lang['upload_err_username'] = 'Nutzername fehlt';
+$lang['upload_file_exists'] = 'Diese Datei existiert bereits';
+$lang['upload_filenotfound'] = 'das Format der Datei entspricht nicht dem Bild';
+$lang['upload_forbidden'] = 'in dieser Kategorie ist ein Upload nicht erlaubt';
+$lang['upload_name'] = 'Name des Bildes';
+$lang['upload_picture'] = 'Ein Bild hochladen';
+$lang['upload_successful'] = 'Bild erfolgreich hinzugefügt, ein Administrator wird ihr Bild überprüfen und freischalten';
+$lang['upload_title'] = 'Ein Bild hinzufügen';
+$lang['useful when password forgotten'] = 'nützlich, wenn Sie ihr Passwort vergessen';
+$lang['qsearch'] = 'Schnellsuche';
+$lang['Connected user: %s'] = 'Connected Benutzer : %s';
+$lang['IP: %s'] = 'IP: %s';
+$lang['Browser: %s'] = 'Browser: %s';
+$lang['Author: %s'] = 'Autor: %s';
+$lang['Comment: %s'] = 'Kommentar: %s';
+$lang['Delete: %s'] = 'Löschen: %s';
+$lang['Validate: %s'] = 'Validierung: %s';
+$lang['Comment by %s'] = 'Kommentar von %s';
+$lang['User: %s'] = 'Benutzer: %s';
+$lang['Email: %s'] = 'E-Mail: %s';
+$lang['Admin: %s'] = 'Verwaltung: %s';
+$lang['Registration of %s'] = 'Registrierung von %s';
+$lang['Category: %s'] = 'Kategorie: %s';
+$lang['Picture name: %s'] = 'Name des Bildes: %s';
+$lang['Creation date: %s'] = 'Erstellungsdatum: %d';
+$lang['Waiting page: %s'] = 'Seite warten: %s';
+$lang['Picture uploaded by %s'] = 'Bild hochgeladen von %s';
+// --------- Starting below: New or revised $lang ---- from version 1.7.1
+$lang['guest_must_be_guest'] = 'Status der Benutzer "guest" nicht entspricht, Verwendung des Standard. Bitte kontaktieren Sie den Webmaster.';
+// --------- Starting below: New or revised $lang ---- from Butterfly (2.0)
+$lang['Administrator, webmaster and special user cannot use this method'] = 'Administrator, Webmaster und spezieller Benutzer können nicht diese Methode verwenden';
+$lang['reg_err_mail_address_dbl'] = 'Diese E-Mail-Adresse wird bereits verwendet';
+$lang['Category results for'] = 'Ergebnisse der Kategorien für';
+$lang['Tag results for'] = 'Ergebnisse der Tag für';
+$lang['from %s to %s'] = 'von %s bis %s';
+$lang['start_play'] = 'Start der Diashow';
+$lang['stop_play'] = 'Pause der Diashow';
+$lang['start_repeat'] = 'Wiederholen der Diashow';
+$lang['stop_repeat'] = 'Diashow nicht wiederholen';
+$lang['inc_period'] = 'Diashow langsamer anzeigen';
+$lang['dec_period'] = 'Diashow schneller anzeigen';
+$lang['Submit'] = 'Bestätigen';
+$lang['Yes'] = 'Ja';
+$lang['No'] = 'Nein';
+$lang['%d element']='%d Bild';
+$lang['%d elements']='%d Bilder';
+$lang['%d element are also linked to current tags'] = '%d Element ist auch mit weiteren Tags markiert';
+$lang['%d elements are also linked to current tags'] = '%d Elemente sind auch mit weiteren Tags markiert';
+$lang['See elements linked to this tag only'] = 'Zeige nur Bilder die mit diesem Tag markiert sind';
+$lang['elements posted during the last %d days'] = 'Bilder hinzugefügt während der letzten %d Tage';
+$lang['Choose an image'] = 'Wählen Sie ein Bild';
+$lang['Piwigo Help'] = 'Hilfe Piwigo';
+$lang['Rank'] = 'Rang';
+$lang['group by letters'] = 'Gruppieren nach Buchstaben';
+$lang['letters'] = 'Buchstaben';
+$lang['show tag cloud'] = 'zeigen die Tag-Wolke';
+$lang['cloud'] = 'Wolke';
+?>
Index: /tags/2.0.2/language/de_DE/help.html
===================================================================
--- /tags/2.0.2/language/de_DE/help.html	(revision 3278)
+++ /tags/2.0.2/language/de_DE/help.html	(revision 3278)
@@ -0,0 +1,335 @@
+<div class="instructions">
+<h2>Hilfe</h2>
+
+<div id="instructionPLoader" class="instructionBlock">
+  <div
+    id="pLoader_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('pLoader_header', 'pLoader_content')"
+  ><span>
+    Lade Bilder in deine Galerie mit dem Programm pLoader
+  </span></div>
+  <div
+    id="pLoader_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+<!--TODO-->    <p><a href="http://piwigo.org/ext/extension_view.php?eid=270">pLoader for Windows</a> or <a href="http://piwigo.org/ext/extension_view.php?eid=269">pLoader for Linux</a> : description, download and details about new revisions.</p>
+    <ol>
+      <li>Erstelle in deiner Piwigo Installation im Ordner "galleries" einen Ordner "upload" mit Schreibzugriff.</li>
+      <li>Installiere das Programm pLoader auf deinem Computer, starte es und trage die genaue URL zur Galerie und die Galerie-Zugangsdaten ein.</li>
+      <li>Drag'n drop Fotos von deinem Windows-Explorer in das Fenster "photo selection" vom pLoader.</li>
+      <li>Erstelle eine Kategorie und markiere sie.</li>
+      <li>Markiere einige oder alle Fotos.</li>
+      <li>Klicke den grünen Pfeil um die Bilder hochzuladen</li>
+    </ol>
+Herzlichen Glückwunsch, du hast deine erste Kategorie mit dem pLoader hochgeladen
+  </div> <!-- pLoader_content -->
+</div> <!-- instructionPLoader -->
+
+<div id="instructionFTP" class="instructionBlock">
+  <div
+    id="FTP_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('FTP_header', 'FTP_content')"
+  ><span>
+    Füge deiner Galerie Fotos per FTP hinzu
+  </span></div>
+  <div
+    id="FTP_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+
+<h3>Schnellstart</h3>
+
+<ol>
+  <li>Erstelle einen neuen Ordner auf deinem Computer.</li>  
+  <li>Kopiere einige Fotos in diesen ordner und verkleinere Sie auf eine Web-taugliche Größe. <em>Achtung</em>: Im Datei- und Ordnername dürfen nur Buchstaben, Zahlen und folgende  Sonderzeichen verwendet werden: "-", "_" oder ".". Keine Leerzeichen und andere Sonderzeichen. Desweiterem dürfen "ä", "ü", "ö" und "ß" NICHT verwendet werden.</li>
+  <li>Kopiere den Ordner mit einem FTP Programm in den Ordner "galleries" von deiner Piwigo installation.</li>
+  <li>Melde dich in deiner Galerie an und gehe auf <span class="pwgScreen">Verwaltung &raquo; Bilder &raquo; Thumbnails</span> um fehlende Thumbnails vom Server erstellen zu lassen.</li>
+  <li>Gehe zu <span class="pwgScreen">Verwaltung</span> und klicke den großen "Schnelle Syncronisation" Button.</li>
+</ol>
+
+Herzlichen Glückwunsch, du hast nun die erste Kategorie in deiner Piwigo erstellt
+
+<h3>Ordner und Dateiorganisation</h3>
+
+<ul>
+
+  <li>
+
+    <p>Die Ordner ihrer Kategorien sind in dem Verzeichnis
+"Galerie". Hier siehst du ein Beispielverzeichnisbaum einer kleinen Galerie
+(aber mit vielen Features): </p>
+  
+<pre>
+.
+| - Admin
+| - Doc
+| - Galleries
+| | - Kategorie-1
+| | | - Kategorie-1.1
+| | | | - Kategorie-1.1.1
+| | | | | - Kategorie-1.1.1.1
+| | | | | | - Pwg_high
+| | | | | | + - Mariage.jpg
+| | | | | | - Thumbnail
+| | | | | | + - TN-mariage.jpg
+| | | | | + - Mariage.jpg
+| | | | + - Kategorie-1.1.1.2
+| | | + - Kategorie-1.1.2
+| | | - Kategorie-1.2
+| | | | - Pookie.jpg
+| | | + - Thumbnail
+| | | + - TN-pookie.jpg
+| | + - Kategorie-1.3
+| + - Kategorie-2
+| | - Porcinet.gif
+| | - Pwg_representative
+| | + - Video.jpg
+| | - Thumbnail
+| | + - TN-porcinet.jpg
+| + - Video.avi
+| - Include
+| - Install
+| - Language
+| - Template
++ - Tool</pre>
+
+  </li>
+  
+<li>Jede Kategorie wird erstellt durch einen Unterordner im im Ordner 
+"Galleries". Diesr kann durch beliebig viele Unterordner erweitert werden.
+Im obigen Beispiel, Kategorie-1.1.1.1 ist auf dem Niveau 4</li>
+
+   <li>Jedes Element besteht aus einer Datei. 
+   Eine Datei zählt als Element für Piwigo, wenn die Erweiterung des Dateinamens in den
+   Konfigurationsparametern festgelegt ist <code>file_ext</code> (siehe
+   <span class="filename">Datei include / config.inc.php</span>). 
+   Eine Datei zählt als Bild, wenn die Dateiendung mit dem Konfigurationsparameter
+   <code>picture_ext</code> festgelegt wird.</li>
+
+   <li>Elemente vom Typ Bild müssen ein Thumbnail (kleines Vorschaubild) (siehe
+Abschnitt Thumbnails) besitzen.</li>
+
+   <li>Bild können Bilder im Grossformat hinterlegt sein (in einem Unterordner "Pwg_high".
+   Wie für die Datei <span class="filename">Hochzeit.jpg</span>
+im obigen Beispiel. Dem Dateinamen darf nichts vorangestellt werden.</li>
+
+   <li>Alle Elemente, die keine Bilder sind (Videos, Sounds, Textdateien, die alles, was du 
+   möchtest, ...) werden standardmäßig von einem Symbol für die Erweiterung des Dateinamens 
+   dargestellt. Optional kann selbst eine Miniaturansicht erstellt werden
+   (siehe die Datei <span
+   class = "filename">video.avi</span> im Beispiel).</li>
+
+   <li><em>Achtung</em>: der Namen für ein Verzeichnis oder eine Datei darf
+nur aus Buchstaben, Zahlen, "-", "_" oder "." bestehen. Umlaute und Sonderzeichen
+dürfen nicht verwendet werden.</li>
+
+   <li><em>Empfehlung</em>: eine Kategorie kann Elemente und Unterkategorien enthalten,
+Es ist aber empfehlenswert und übersichtlicher, wenn eine Kategorie entweder Elemente 
+<strong>oder</strong>Unterkategorien enthält.</li>
+
+   <li>Wenn du die Dateien, Bilder und Thumbnails in die richtigen Ordner hochgeladen hast, 
+logge dich ein und gehen auf<span 
+class = "pwgScreen">Verwaltung &raquo; Kategorien &raquo; synchronisieren</span>.</li>
+
+</ul>
+
+<h3>kleines Vorschaubild, Miniatur (Thumbnails)</h3>
+
+<ul>
+  
+   <li>Wie bereits erwähnt, gehört zu jedem Bild ein Thumbnail.</li>
+
+   <li>Thumbnails werden in einem Unterverzeichnis "thumbnail" jeder
+Kategorie gespeichert. Ein zu einem Bild gehörendes Thumbnail hat den gleichen Namen wie das Bild 
+mit einem vorangestelltem Präfix (siehe TN- oben im Beispielverzeichnisbaum). Dieses Präfix ist in 
+der Konfiguration festgelegt <code>prefix_thumbnail</code>
+(siehe <span class="filename">include / config.inc.php</span >).</li>
+
+   <li>Die Miniaturen brauchen nicht die gleiche Dateiendung zu haben. Ein "jpg" Bild darf ein
+"GIF" als Vorschaubild haben.</li>
+
+   <li> Es wird empfohlen, ein externes Programm für die Erstellung von
+Miniaturen zu verwenden.</li>
+
+   <li> Du kannst auch das Tool zum Erstellen von Thumbnails der Piwigo verwenden aber dies wird 
+   nicht empfohlen, da meistens die Qualität enttäuschend ist und der Server stark belastet wird.
+   Im Ernstfall kann es den Server überlasten.</li>
+
+   <li> Falls SIe doch den Webserver verwenden um Thumbnails generieren zu lassen, müssen Sie allen Kategorieordnern 
+   per CHMOD die entsprechenden Rechte zuweisen.</li>
+
+</ul>
+
+
+  </div> <!-- FTP_content -->
+</div> <!-- instructionFTP -->
+
+<div id="instructionPermissions" class="instructionBlock">
+  <div
+    id="permissions_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('permissions_header', 'permissions_content')"
+  ><span>
+    Berechtigungen
+  </span></div>
+  <div
+    id="permissions_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+
+<ul>
+
+   <li>Du kannst den Zugriff auf bestimmte Kategorien beschränken. Die Kategorien können
+öffentlich oder privat sein. Zugriffsbeschränkungen für bestimmte Benutzer oder Gruppen 
+können nur für private Kategorien eingerichtet werden.</li>
+  
+   <li>So kannst du eine einzelne öffentliche Kategorie in eine private ändern (<span
+class = "pwgScreen">Verwaltung &raquo; Kategorien &raquo; Verwalten &raquo; Bearbeiten (Icon rechts)</span>) oder
+alle Kategorien verwalten (<span
+class = "pwgScreen">Verwaltung &raquo; Kategorien &raquo; Eigenschaften &raquo; Public / Private</span>).</li>
+
+  <li>
+
+    <p>Wenn eine Ketegorie privat ist, kannst du die Berechtigungen für Gruppen und Benutzer auf 3 
+    unterschiedlichen Seiten einstellen:</p>
+
+    <ul>
+		<li><span class="pwgScreen">Verwaltung  &raquo; Verwaltung &raquo; Benutzer &raquo;
+      Aktionen</span> (jeweils ein Limk pro Benutzer)</li>
+		<li><span class="pwgScreen">Verwaltung  &raquo; Verwaltung &raquo; Gruppen &raquo;
+      Aktionen</span> (jeweils ein Link pro Gruppe)</li>
+		<li><span class="pwgScreen">Administration &raquo; Kategorien &raquo; Verwalten &raquo; Berechtigung für Kategorie ändern</span> (jeweils ein Link pro Kategorie)</li>
+    </ul>
+
+  </li>
+
+</ul>
+  </div> <!-- permissions_content --> 
+</div> <!-- instructionPermissions -->
+
+<div id="instructionGroups" class="instructionBlock">
+  <div
+    id="groups_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('groups_header', 'groups_content')"
+  ><span>
+    Benutzergruppen
+  </span></div>
+  <div
+    id="groups_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+<ul>
+
+	<li>Gruppen sind ein guter Weg, Benutzerrechte für mehrere Benutzer zugleich zu verwalten.</li>
+
+	<li>Du kannst Gruppen und Benutzer hinzufügen und erstellen unter:
+<span class="pwgScreen">Verwaltung &raquo; Verwaltung &raquo; Gruppen</span>.</li>
+
+	<li>Ein Benutzer kann mehreren Gruppen angehören. Die Freigaben der "stärksten Gruppe"
+sind relevant.
+Wenn der Benutzer "Stein" zu den Gruppen "Familie" und "Freunde" gehört und nur die Gruppe
+ "Familie" kann sich die Kategorie "Weihnachten 2003" ansehen, dann kann "Stein" kann sich 
+ dieser Kategorie ansehen.</li>
+  
+</ul>
+  </div> <!-- groups_content --> 
+</div> <!-- instructionGroups -->
+
+<div id="instructionUpload" class="instructionBlock">
+  <div
+    id="upload_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('upload_header', 'upload_content')"
+  ><span>
+    Hinzufügen von Dateien durch die Benutzer
+  </span></div>
+  <div
+    id="upload_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+<p>Benutzer können ihre eigenen Fotos hochladen.</p>
+
+<ol>
+
+    <li>Erlaube den Upload für eine physische Kategorie (ein existierender Ordner) (<span
+  class="pwgScreen">Verwaltung &raquo; Kategorien &raquo; Verwalten &raquo; bearbeite die Informationen in dieser Kategorie</span> or <span
+  class="pwgScreen">Verwaltung &raquo; Kategorien &raquo; Eigenschaften &raquo; Upload</span>). In virtuelle Kategorien kann nichts hochgeladen werden.</li>
+
+
+   <li>Gebe allen Benutzern die Berechtigung zum Upload auf freigegebene Kategorien.</li>
+</ol>
+<p>Die hinzugefügten Dateien sind durch die Benutzer nicht direkt
+sichtbar. Ein Administrator muss die hochgeladenen Fotos in <span class="pwgScreen">Verwaltung &raquo; Bilder &raquo; Wartend auf Freigabe </span>freigeben.</p>
+
+  </div> <!-- upload_content --> 
+</div> <!-- instructionUpload -->
+
+<div id="instructionCategoryLinks" class="instructionBlock">
+  <div
+    id="categoryLinks_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('categoryLinks_header', 'categoryLinks_content')"
+  ><span>
+    Verbindungen zwischen Elementen, Kategorien und virtuellen Kategorien
+  </span></div>
+  <div
+    id="categoryLinks_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+
+<ul>
+
+	<li>Fotos werden normalerweise in der Kategorie angezeigt, in der sie hochgeladen wurden.</li>
+
+	<li>Man kann Fotos auch in einer zweiten Kategorie anzeigen ohne sie zu duplizieren. Verbinde das Bild einfach mit einer anderen Kategorie auf der Seite "Information ändern" (den Link dazu kann jeder Administrator auf der Seite des Fotos selbst sehen).</li>
+
+	<li>Virtuelle Kategorien basieren auf folgendem Konzept: sie haben keinen eigenen Ordner. Erstelle eine virtuelle Kategorie unter <span class="pwgScreen">Verwaltung &raquo; Kategorien &raquo; Verwalten</span>.</li>
+
+</ul>
+  </div> <!-- categoryLinks_content --> 
+</div> <!-- instructionCategoryLinks -->
+
+<div id="instructionMisc" class="instructionBlock">
+  <div
+    id="misc_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('misc_header', 'misc_content')"
+  ><span>
+    Verschiedenes
+  </span></div>
+  <div
+    id="misc_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+
+<ul>
+  
+   <li>Nachdem du die Galerie erfolgreich erstellt habst, konfiguriere die gewünschte Anzeige über
+<span class="pwgScreen">Verwaltung &raquo; Konfiguration &raquo; Standartanzeige</span>. Jeder neu registrierte Benutzer
+bekommt diese Einstellungen als Standart vorgegeben.</li>
+
+   <li>Bei Fragen besuchen Sie bitte das Forum. Wenn ihre Frage dort nicht schon beantwortet wurde, scheuen Sie sich 
+   sie dort zu stellen.
+   Das
+<a href="http://piwigo.org/forum">Forum</a> ist auf der Website von Piwigo. Siehe 
+auch <a href="http://piwigo.org/doc">Offizielle Dokumentation von Piwigo</a> für 
+weitere Informationen. </li>
+
+   <li>Falls du eine Frage hast, die Piwigo community heisst dich herzlich Willkommen in ihrem<a
+  href="http://piwigo.org/forum">ihrem Forum.</a>.</li>
+
+</ul>
+  </div> <!-- misc_content --> 
+</div> <!-- instructionMisc -->
+
+</div>
Index: /tags/2.0.2/language/de_DE/help/advanced_feature.html
===================================================================
--- /tags/2.0.2/language/de_DE/help/advanced_feature.html	(revision 3278)
+++ /tags/2.0.2/language/de_DE/help/advanced_feature.html	(revision 3278)
@@ -0,0 +1,16 @@
+<h2>Erweiterte Funktionen</h2>
+
+<p>Liste der speziellen Funktionen für Administratoren und Experten PWG:</p>
+
+<ul>
+
+   <li>
+     <strong>Nicht verlinkte Elemente: </strong>
+     Zeigt die Bilder, die nicht mit einer virtuellen Kategorie verlinkt sind (sind aber in realen Kategorien vorhanden)
+   </li>
+   <li>
+     <strong> Finde Dateien mit dem gleichen Dateiname: </strong>
+     Findet Dateien mit dem gleichen Dateiname die in verschiedenen Ordnern gespeichert sind.
+   </li>
+
+</ul>
Index: /tags/2.0.2/language/de_DE/help/cat_modify.html
===================================================================
--- /tags/2.0.2/language/de_DE/help/cat_modify.html	(revision 3278)
+++ /tags/2.0.2/language/de_DE/help/cat_modify.html	(revision 3278)
@@ -0,0 +1,149 @@
+<h2>Bearbeiten einer Kategorie</h2>
+
+<h3>Informationen</h3>
+
+<ul>
+
+   <li><strong> Namen</strong>: Umbenennen der Kategorie (praktisch für
+   Kategorie Physik).</li>
+
+   <li><strong> Beschreibung</strong>: eine Vorstellung vom Inhalt der Kategorie,
+   Diese Angabe wird unter der Seite der Miniaturen.</li>
+
+</ul>
+
+<h3>verschieben</h3>
+
+<p>Wenn die virtuelle Klasse ist, können Sie diese zu verschieben. Verschieben eines
+Kategorie bedeutet, ändern Kategorie angeben.</p>
+
+<h3>Optionen</h3>
+
+<ul>
+
+   <li><strong>Art des Zugriffs:</strong> Verwaltung der Zugriffsrechte. Wenn du
+eine private, alle Mädchen werden private Gruppen. Wenn
+Sie besuchen eine öffentliche, allen Kategorien Mütter werden
+werden.</li>
+
+   <li><strong> sperren</strong>: die Kategorie und alle Kategorien
+Mädchen werden für Wartungsarbeiten vorübergehend nicht erreichbar.</li>
+
+   <li><strong>Kommentare</strong>: die Benutzer kommentieren
+die Elemente dieser Kategorie.</li>
+
+   <li><strong>zulassen Hinzufügen von Bildern</strong>: die Benutzer
+zum Herunterladen von Dateien. Diese Option ist nur verfügbar, wenn die
+Kategorie Physik (und nicht-virtuelle).</li>
+
+</ul>
+
+<p>Sie können diese Optionen auch die Verwaltung durch die Verwaltung der "Eigenschaften"
+(Bildschirme <span class="pwgScreen">hinzufügen</span>, <span
+class = "pwgScreen">Kommentare</span>, <span
+class = "pwgScreen">"Schützen"</span>, <span
+class = "pwgScreen">Public / Private</span>, <span
+class = "pwgScreen">Vertreter</span> ab d '<span
+class = "pwgScreen">Verwaltung, Kategorien, Eigenschaften</span >).</p>
+
+<h3>Sortieren</h3>
+
+<p>Verwenden Sie die Sortierung der Bilder Standard.</p>
+
+<p>Angabe, ob die Sortierung gilt auch für die Unterkategorien.</p>
+
+<p>Wählen Sie die Sortierung der Spalten zu verwenden, um diese Kategorie.</p>
+<ul>
+<li><strong>Erstellungsdatum</strong>: Datum der Aufnahme</li>
+<li><strong>Datum:</strong>: Datum der Synchronisierung</li>
+<li><strong>Durchschnitt (*)</strong>: der Durchschnitt werden durch die Besucher</li>
+<li><strong>Weitere Ansichten (*)</strong>: Der Besuch der Kurse können die Reihenfolge der Ansichten</li>
+<li><strong>Dateiname</strong>: Name der Datei in den Informationen oben</li>
+<li><strong>Id:</strong> internen Id (die jüngsten sind "Id" größer als die früheren).</li>
+
+</ul>
+<p><strong>(*)</strong> Achtung: Testen Sie selbst, die diese Sortierungen können unvorhersehbare Ergebnisse.</p>
+
+
+<h3>Vertreter</h3>
+
+<p>Der Vertreter einer Kategorie ist die Miniaturansicht angezeigt
+Vertretung der Kategorie auf der Hauptseite (<span
+class = "pwgScreen">category.php</span>), wenn eine Kategorie
+nur Unterkategorien und keine direkten Elemente (wie in der
+Stamm)</p>
+
+<p>Es gibt 4 Möglichkeiten zur Auswahl der Vertreter einer Kategorie:</p>
+
+<ul>
+
+   <li><span class="pwgScreen">Seite beim Anzeigen von Bildern</span>: in der Schaltflächen
+Maßnahmen, die einer von ihnen können Sie das Element angezeigt als Vertreter
+der Kategorie angezeigt. Diese Schaltfläche ist nur für die
+Administratoren.</li>
+
+   <li><span class="pwgScreen">Bearbeiten von Informationen zu einem Bild</span>
+in der Verwaltung. Dieser Bildschirm kann von <span
+class = "pwgScreen">picture.php</span> <span class="pwgScreen">oder Verwaltung von
+Los</span> im <em>Modus</em>. Finden Sie in der Hilfe auf diesem Bildschirm für die
+Details.</li>
+
+   <li><span class="pwgScreen">Verwaltung, Kategorien, Eigenschaften,
+Vertreter</span>. Finden Sie in der Hilfe für diesen Bildschirm, um die Details.</li>
+
+   <li><span class="pwgScreen">Bearbeiten einer Kategorie</span> (in diesem
+Bildschirm).</li>
+
+</ul>
+
+<p>Die Darstellung hängt von der Einstellung der Konfiguration
+<code>allow_random_representative</code> (siehe <span
+class = "filename">include / config_default.inc.php</span>).</p>
+
+<p>Standard (<code>allow_random_representative</code> auf false) jeder
+Kategorie, die mindestens ein Element wird durch ein Element
+fest. Einmal festgelegt (die Einführung der Kategorie), in dem der Vertreter ändert
+nur, wenn der Administrator den Antrag. Wenn der Vertreter nicht
+ist nicht, Sie können zu <strong>fragen Ein neuer Vertreter
+Zufall</strong>.</p>
+
+<p>Wenn die Einstellung <code>allow_random_representative</code>
+wahr ist, eine Kategorie enthalten, kann nicht von
+Vertreter bestimmt. Verwenden Sie einfach auf die Schaltfläche <strong> löschen
+Vertreter</strong>.</p>
+
+<p>Wenn die Kategorie enthält keine Anhaltspunkte (aber nur
+Unterkategorien) sie kann sich vertreten durch irgendeine
+Element auf dem Bildschirm durch <span class="pwgScreen">Informationen bearbeiten
+Ein Bild</span>. Die einzige Möglichkeit, dieses Fenster ist die Schaltfläche
+Vertreter <strong>löschen</strong>.</p>
+
+<h3>Beteiligung aller Elemente der Klasse zu einer neuen Kategorie</h3>
+
+<ul>
+
+<li><strong>Name der Kategorie virtuelle</strong>: Name der neuen Kategorie zu schaffen,
+Alle Bilder der Gruppe werden in Verbindung mit der neuen.</li>
+
+<li><strong>Branche</strong>: Wo die neue Kategorie muss,
+leer lassen, um die neue auf der Homepage.</li>
+
+</ul>
+
+<h3>Beteiligung aller Elemente der Gruppe, zu der bestehenden Klassen</h3>
+
+<ul>
+
+<li><strong>Kategorien</strong>: Kategorie wählen Ziel.</li>
+
+</ul>
+
+<h3>E-Mail senden Informationen an die Mitglieder einer Gruppe</h3>
+
+<ul>
+
+<li><strong>Gruppe</strong>: Gruppe von Empfängern</li>
+
+<li><strong>Inhalt der E-Mail:</strong> Text zu schicken.</li>
+
+</ul>  
Index: /tags/2.0.2/language/de_DE/help/cat_move.html
===================================================================
--- /tags/2.0.2/language/de_DE/help/cat_move.html	(revision 3278)
+++ /tags/2.0.2/language/de_DE/help/cat_move.html	(revision 3278)
@@ -0,0 +1,15 @@
+<h2>Verschieben von virtuellen Klassen</h2>
+
+<p>Sie können die Eltern eines virtuellen Klasse.</p>
+
+<h3>Kategorien buchen zu verschieben</h3>
+
+<p>Wählen Sie eine oder mehrere virtuelle verschoben zu werden.
+Wenn die Liste leer ist, ist, dass Sie noch keine haben erstellt.</p>
+
+<h3>Neue Kategorie angeben </h3>
+
+<p>Wählen Sie die neue Kategorie angeben (virtuelle oder physische).
+Wenn Sie noch keine Option,
+die Kategorien zu verschieben, werden wieder an die Wurzel der Kategorien.
+Sie können nicht in eine Kategorie selbst oder ihre Kinder.</p>
Index: /tags/2.0.2/language/de_DE/help/cat_options.html
===================================================================
--- /tags/2.0.2/language/de_DE/help/cat_options.html	(revision 3278)
+++ /tags/2.0.2/language/de_DE/help/cat_options.html	(revision 3278)
@@ -0,0 +1,40 @@
+<h2>Kategorie Optionen</h2>
+
+<p>Dieser Bildschirm erlaubt es dem Administrator verwalten Kategorien Option für viele
+Kategorien auf einmal.</p>
+
+<dl>
+
+  <dt>Genehmigung für das Hinzufügen</dt>
+
+  <dd>Machen Sie Kategorien hochgeladene Galerie für Besucher. Nicht nur virtuell und
+   Nicht Remote-Kategorien werden angezeigt.</dd>
+  
+  <dt>Kommentare Benutzer</dt>
+
+  <dd>Zulassen dass Benutzer durch Eingabe von Kommentaren in den Kategorien ausgewählt.
+Vererbung, ein Bild ist, wie wenn sie gehört mindestens eine kommentiert.</dd>
+  
+  <dt>Sperren</dt>
+
+  <dd>Ausgewählte Kategorien wird vorübergehend deaktiviert für die Wartung. Wenn
+   Sie sperren eine Kategorie, alle seine Kinder Kategorien werden gesperrt. Wenn Sie entsperren
+   eine Kategorie, alle ihre Muttergesellschaft Kategorien werden entsperrt.</dd>
+
+  <dt>Public / Private</dt>
+
+  <dd>Verwalten von Berechtigungen für ausgewählte Kategorien. Ausgewählte Kategorien sind
+   Privat: Sie benötigen zu genehmigen Benutzer und / oder Gruppen den Zugang zu
+   sie. Wenn Sie eine Kategorie privat, alle seine Kinder Kategorien wird
+   privat. Wenn Sie eine Kategorie aus öffentlichen, von allen seinen Eltern Kategorien wird
+   öffentlichen</dd>
+
+  <dt>Vertreter</dt>
+
+  <dd>Diese Option kann nur verwaltet, wenn Sie Konfigurations-Parameter
+   <code>allow_random_representative</code> (siehe <span
+   class="Dateiname">include/config_defaults.inc.php</span>) zu
+   <em>true</em>. Jede Kategorie kann beliebig vertreten oder einzeln
+   vertreten (durch ein eindeutiges Bild).</dd>
+
+</dl>
Index: /tags/2.0.2/language/de_DE/help/cat_perm.html
===================================================================
--- /tags/2.0.2/language/de_DE/help/cat_perm.html	(revision 3278)
+++ /tags/2.0.2/language/de_DE/help/cat_perm.html	(revision 3278)
@@ -0,0 +1,14 @@
+<h2>Befugnisse für Kategorien verwalten</h2>
+
+<p>Diese Seite zeigt ihnen an welchen Benutzern und Gruppen es 
+erlaubt bzw. verboten ist diese Kategorie anzusehen..</p>
+
+<h3>Gruppen</h3>
+
+<p>Sie können Benutzergruppen den Zugriff auf diese Kategorie 
+verbieten bzw. erlauben. Dadurch bearbeiten Sie automatisch aber auch die 
+einzelnen Rechte der den Gruppen angehörigen Benutzer.</p>
+
+<h3>Benutzer</h3>
+
+<p>Sie können individuell Benutzern den Zugang zu dieser Kategorie erlauben oder verbieten.</p>
Index: /tags/2.0.2/language/de_DE/help/configuration.html
===================================================================
--- /tags/2.0.2/language/de_DE/help/configuration.html	(revision 3278)
+++ /tags/2.0.2/language/de_DE/help/configuration.html	(revision 3278)
@@ -0,0 +1,134 @@
+<h2>Konfiguration</h2>
+
+<p>Dieser Bildschirm ermöglicht die Konfiguration einfach. Denn nur dann, wenn
+zeigten die Konfigurationseinstellungen, die ausreichen, um die Mehrheit
+Administratoren. Wenn Sie möchten, die Liste der vielen (und
+Fortgeschrittene) Einstellungen, lesen Sie die Datei <span
+class="filename">include/config_default.inc.php</span></p>
+
+<p>Dieser Bildschirm ist in mehrere Abschnitte, in denen die Einstellungen
+Thema durch.</p>
+
+<h3>Hauptsächlich</h3>
+<ul>
+
+  <li><strong>Titel der Galerie</strong>: für die RSS-Feeds und
+E-Mail-Benachrichtigung.</li>
+
+  <li><strong>Seiten Banner</strong>: HTML-Code angezeigt, im oberen Teil der
+Seiten.</li>
+
+  <li><strong>URL der Galerie</strong>: für die RSS-Feeds.</li>
+
+  <li><strong>Sperren der Galerie</strong>: Sperren der gesamten
+Galerie für Wartungsarbeiten. Nur Administratoren können den Zugriff auf die
+Galerie.</li>
+
+  <li><strong>Rating</strong>: Die Bewertung der Fotos ist möglich.</li>
+
+  <li><strong>Rating von den Besuchern</strong>: Auch nicht registrierte Benutzer können Bilder Satz.</li>
+
+  <li><strong>Lassen Sie Benutzer-Registrierung</strong>: Die Registrierung ist kostenlos für alle.</li>
+
+  <li><strong>E-Mail-Adresse ist obligatorisch für alle Nutzer</strong>: E-Mail-Adresse wird überprüft bei der Registrierung oder Profil aktualisieren, außer wenn die Maßnahme erfolgt auf Verwaltung Teil.</li>
+
+  <li><strong>E-Mail-Administratoren, wenn ein neuer Benutzer registriert</strong>: Administratoren werden erhalten für jede Registrierung.</li>
+
+</ul>
+
+<h3>Historisches</h3>
+  <p>	
+Besuche auf den Seiten <span
+class="pwgScreen">index.php</span> und <span
+class="pwgScreen">picture.php</span> werden in der
+   <code>History</code> Tabelle.</p>
+
+  <p>Besuche werden in <span class="pwgScreen">Administration, Specials, Geschichte</span>.</p>
+<ul>
+  <li><strong>Seite speichern Besuche von Gästen</strong>: Seite Besuche von Gästen werden gespeichert.</li>
+
+  <li><strong>Seite speichern Besuche von Nutzern</strong>: Besuche von registrered Benutzer gespeichert werden.</li>
+
+  <li><strong>Seite speichern Besuche von Administratoren</strong>: Seite Besuche von Administratoren gespeichert werden.</li>
+
+</ul>
+
+<h3>Kommentare</h3>
+<ul>
+
+  <li><strong>Kommentare für alle</strong>: Auch nicht registrierte Gäste können nach
+   Bemerkungen.</li>
+
+  <li><strong>Anzahl der Kommentare pro Seite</strong>.</li>
+
+  <li><strong>Validierung</strong>: Ein Administrator muss die Validierung
+Benutzer Kommentare bevor sie sichtbar in der
+öffentlichen Teil. Die Validierung der Benutzer Kommentare erfolgt in
+dem Bildschirm <span class="pwgScreen">Verwaltung, Bilder,
+Kommentare</span>.</li>
+
+  <li><strong>Administratoren benachrichtigen, wenn ein Kommentar eingetragen is</strong>:
+Sende eine E-Mail an den Administrator, wenn ein Benutzer registriert ist, die einen Kommentar validiert.</li>
+
+  <li><strong>Administratoren benachrichtigen, wenn ein Kommentar der Gültigkeitsprüfung erforderlich </strong>:
+Sende eine E-Mail an den Administrator, wenn ein Benutzer einen Kommentar registriert, die eine Validierung der Administratoren.
+Die Validierung der Benutzer Bewertungen erfolgt auf dem Bildschirm <span class="pwgScreen">Verwaltung, Bilder, Kommentare</span>.</li>
+
+</ul>
+
+<h3>Upload</h3>
+<ul>
+  <li><strong>Show-Upload-Link jedes Mal</strong>: Wenn vorhanden uploadeable Kategorien, fügen Link wird zeigen, für jede Kategorie.</li>
+  <li><strong>User-Ebene Zugang zum Hochladen</strong>: Ermöglicht zu beschränken, Upload von den Nutzern</li>
+  <li><strong>E-Mail-Verwaltung, wenn ein Bild hochgeladen</strong>: Administratoren werden erhalten für jede E-Mail Bild hochgeladen von einem Benutzer.</li>
+</ul>
+
+<h3>Standardansicht</h3>
+<p>Ändern der Standardansicht: für die Besucher nicht
+verbunden. Nachdem Sie sich angemeldet haben, diese Optionen sind überlastet durch die von
+Benutzer, es kann auf dem Bildschirm <span
+class="pwgScreen"> Profil</span>.</p>
+
+<p>Es ist möglich, diese Optionen, um die vorhandenen Benutzer,
+aber es handelt sich um einen anderen Bildschirm: <span class="pwgScreen">Verwaltung,
+Identifikation, Benutzer</span>, in dem Sie können diese
+Optionen für eine Liste der ausgewählten Benutzer.</p>
+
+<ul>
+
+  <li><strong>Sprache</strong>: nur die Labels
+Piwigo. Die Namen der Kategorien, Bild und Beschreibung sind
+nicht lokalisiert (zB mehrsprachig).</li>
+
+  <li><strong>Anzahl der Bilder pro Zeile</strong></li>
+
+  <li><strong>Anzahl der Zeilen pro Seite</strong></li>
+
+  <li><strong>Interface Thema</strong></li>
+
+  <li><strong>Jüngster Zeit</strong>: Mit dem Tag. Frist, innerhalb eines Bildes ist
+   gezeigt, wie neue. Müssen überlegen 1 Tag.</li>
+
+  <li><strong>Erweitern Sie alle Kategorien</strong>: Erweitern Sie alle Kategorien von
+   standardmäßig in das Menü? <em>Warnung</em>: diese Option ist Ressourcen verbrauchen
+   und Mai eine große angezeigt, sofern Sie eine Kategorie Baum ist enthält viele
+   Kategorien.</li>
+
+  <li><strong>Zeige die Anzahl der Kommentare</strong>: Anzeige der Anzahl der Kommentare
+   für jedes Bild auf die Vorschaubilder Seite. Resource sein.</li>
+
+  <li><strong>Anzeige der Treffer zählen</strong>: Display beobachtet Treffer auf das Bild
+   nur im Rahmen seiner Thumbnail auf die Vorschaubilder Seite.
+   Nur wenn Advanced Configuration Parameter ist: <br/>
+   $conf [ 'show_nb_hits'] = true; <br/>
+   Hinweis: Es ist false per Default.</li>
+
+  <li><strong>Maximale Breite der Bilder</strong>: maximal angezeigt
+   Breite. Wenn Bilder sind größer als diese Einstellung, werden sie auf die Größe
+   Anzeige. Wenn man bedenkt, Füllung diese Option, die Sie besser prüfen
+   Änderung der Breite der Sie Ihre Bilder statt.</li>
+
+  <li><strong>Maximale Höhe der Bilder</strong>: gleichen Bemerkungen wie für
+   vorherige Einstellung.</li>
+
+</ul>
Index: /tags/2.0.2/language/de_DE/help/extend_for_templates.html
===================================================================
--- /tags/2.0.2/language/de_DE/help/extend_for_templates.html	(revision 3278)
+++ /tags/2.0.2/language/de_DE/help/extend_for_templates.html	(revision 3278)
@@ -0,0 +1,101 @@
+<h2>Konfiguration zu "erweitern" die Templates</h2>
+
+<h3>Ziel</h3>
+<p>Festlegung der Bedingungen, die zur Ersetzung des Templates (Vorlage) ab Template-Erweiterung
+(Template "replacer" (Stellvertreter)).</p>
+
+<p>"Templates Ursprungs" aus./template/yoga (oder einem anderen Ordner wie "yoga")
+  durch einen Stellvertreter, wenn dieser im Zusammenhang mit seiner ursprünglichen Vorlage
+  (und auf freiwilliger Basis, wenn die Adresse (URL) beantragt enthält eine URL contains eine optionale Parameter in der URL ").</p>
+
+<p>Die "optionale Parameter in der URL" sind die das sie finden nach dem Namen des Moduls in die Adresse (URL).</p>
+
+<p>So ein "Optionale Parameter in der URL" kann ein "permalink" aktiv
+(siehe permalinks in unserer Dokumentation für weitere Informationen).</p>
+
+<p>Lesen Sie die `<a href="#warnings">Warnungen</a>` zu den Nutzungsbedingungen.</p>
+
+<h3>Was sind Template-Erweiterungen?</h3>
+
+<p>Diese Konfiguration ist ein leistungsfähiges Werkzeug für Einsteiger und fortgeschrittene Anwender.
+Mit dem FTP, in der Vorlage-Erweiterung Ordner, der Webmaster kann Duplikat eine Menge von
+  der verteilt. tpl-Dateien ( "Original-Vorlage") mit einem anderen Namen
+  ( "Replacer").
+ 
+  "Original-Vorlagen", aktuelle Original-Vorlagen unterstützt werden:</p>
+<ul>
+  <li><span class="filename">index.tpl</span></li>
+  <li><span class="filename">mainpage_categories.tpl</span> and/or <span class="filename">thumbnails.tpl</span></li>
+  <li><span class="filename">menubar.tpl</span></li>
+  <li><span class="filename">header.tpl</span> and/or <span class="filename">footer.tpl</span></li>
+  <li><span class="filename">picture_content.tpl</span> and/or <span class="filename">picture.tpl</span></li>
+  <!-- <li><span class="filename">slideshow.tpl</span></li> -->
+  <li><span class="filename">profile.tpl</span> and/or <span class="filename">profile_content.tpl</span></li>
+  <li><span class="filename">tags.tpl</span></li>
+  <li><span class="filename">upload.tpl</span></li>
+  <li><span class="filename">about.tpl</span></li>
+  <li><span class="filename">popuphelp.tpl</span></li>
+  <li><span class="filename">search.tpl</span> and/or <span class="filename">search_rules.tpl</span></li>
+  <li><span class="filename">nbm.tpl</span> and/or <span class="filename">notification.tpl</span></li>
+  <li><span class="filename">identification.tpl</span> and/or <span class="filename">register.tpl</span></li>
+  <li><span class="filename">redirect.tpl</span></li>
+</ul>
+
+<h3>Wo finde ich "Original-Vorlagen"?</h3>
+
+<p>Verteilte Original-Vorlagen sind in template /yoga/
+(nicht bearbeiten sie im Ort für Upgrade Perspektiven). Also mit "Original-Vorlagen",
+jeder Webmaster kann seine "replacers (benutzerdefinierte Vorlagen)".</p>
+
+<h3>Wo kann ich sparen "replacers"?</h3>
+
+<p><strong>Replacers (benutzerdefinierte Vorlagen)</strong> sind in der
+Template-Erweiterung Ordner (oder in seinen Unterordnern).
+Replacers kann eine beliebige Datei mit der Erweiterung. Tpl-Erweiterung. Zum Beispiel: <span
+class="Dateiname">template-extension/my-extension/video.tpl</span>.</p>
+
+
+<h3>Wie aktiviere ich meine "Ersatz"?</h3>
+<p>Ein <strong>Original-Vorlage</strong> sollte für jede
+  <strong>Replacer (benutzerdefinierte Vorlagen)</strong>, um die damit verbundenen Ersatz.
+  Dies ist das Ziel der "Extend für Vorlagen" in der Konfiguration Administration Menü.</p>
+
+<p>Wenn Sie ein <strong>optional URL Keyword</strong>, dann Ersatz
+werden jeweils nur auf Seiten mit diesem Keyword. Zum Beispiel: <span 
+class="pwgScreen">index.php? /<strong> most_visited</strong></span></p>
+  
+<p>Advanced-User nutzen werden Dauerlinks als <strong>optional URL Keyword</strong>.</p>
+
+<!-- TODO -->
+<p>If you select a <strong>Bound template</strong> then replacements will be operate only on this template.</p>
+
+<h3>Wie kann ich deaktivieren meine "replacers"?</h3>
+<ul>
+<li>Ausschluss der "Template Herkunft".</li>
+<li>Per FTP löschen "ersetzt".</li>
+</ul>
+<a name="warnings"></a>
+<h3>Warnhinweise</h3>
+<ul>
+
+  <li><strong>Original-Vorlage</strong> muss das "Original"-Vorlage
+   ansonsten können unvorhersehbare Ergebnisse!</li>
+
+  <li>Auf mehreren <strong>replacers (benutzerdefinierte Vorlagen)</strong> mit dem
+   gleichen <strong>Original-Vorlage</strong> und die gleichen <strong>optional URL
+   Keyword</strong> nur die letzte Replacer aktiv ist.</li>
+
+  <li>Nicht selektierte <strong>optional URL Keyword</strong> wird die aktive Replacer
+   auf jeder Vorlage Nutzung. Wie vorherigen Punkt, um können vorherigen
+   ausgewählten replacers.</li>
+
+  <li>Unterordner:
+Unterordner werden ignoriert, aber sie sind nützlich, eine Änderung der derzeitigen Reihenfolge. <br />
+distributed-Proben: für Test-Zwecke verteilt werden!
+<strong>nicht bearbeiten</strong> Erstellen Sie Ihren eigenen sind.
+</li>
+
+  <li>Am löschen eines Replacer <strong>der Original-Vorlage</strong> ist
+   sofort reaktiviert.</li>
+
+</ul>
Index: /tags/2.0.2/language/de_DE/help/group_list.html
===================================================================
--- /tags/2.0.2/language/de_DE/help/group_list.html	(revision 3278)
+++ /tags/2.0.2/language/de_DE/help/group_list.html	(revision 3278)
@@ -0,0 +1,21 @@
+<h2>Liste der Gruppen</h2>
+
+<p>Umgang mit den Eigenschaften der Gruppen.</p>
+
+<h3>Hinzufügen einer Gruppe</h3>
+
+<p>Der Administrator kann Gruppen hinzufügen.</p>
+
+<h3>Liste der Gruppen</h3>
+
+<p>Die Liste kann für jede Gruppe:</p>
+
+<ul>
+  <li>gehen an die Mitglieder Liste</li>
+  <li>gehen Sie bis Erlaubnisse</li>
+  <li>die Gruppe löschen (eine Bestätigung Checkbox)</li>
+  <li>Toggle "Standard" Status (eine Bestätigung Checkbox)</li>
+</ul>
+
+<h3>Standard-Gruppen</h3>
+<p>Standard-Gruppen sind Gruppen, in Verbindung automatisch auf neue Nutzer.</p>
Index: /tags/2.0.2/language/de_DE/help/history.html
===================================================================
--- /tags/2.0.2/language/de_DE/help/history.html	(revision 3278)
+++ /tags/2.0.2/language/de_DE/help/history.html	(revision 3278)
@@ -0,0 +1,52 @@
+<h2>Geschichte</h2>
+
+<p>Diese Bildschirme erlauben, die Browser-History in Piwigo
+  nach den Optionen, die Sie bestimmt in - Verwaltung - Allgemeine
+  - Registerkarte "Verlauf".</p>
+
+<h3>Statistik</h3>
+<ul>
+   <p>Wenn Sie sich entschieden haben, dass die Besucher der Seiten <span
+class = "pwgScreen">index.php</span> und <span
+class = "pwgScreen">picture.php</span> werden
+die in der Tabelle <code>history</code>,
+dieser Registerkarte können Sie die Anzahl der besuchten Seiten</p>
+
+<li><strong>Statistik insgesamt</strong>: Sie zeigen die Statistiken
+Pro Jahr</li>
+
+<li><strong>Statistik von einem Jahr</strong>: Sie zeigen die Statistiken
+Monaten des Jahres ausgewählt.</li>
+
+<li><strong>Statistik von einem Monat</strong>: Sie zeigen die Statistiken
+Tage des Monats gewählt.</li>
+
+<li><strong>Statistik eines Tages</strong>: Sie zeigen die Statistiken
+Stunden des Tages ausgewählt.</li>
+
+</ul>
+
+<h3>suchen</h3>
+<ul>
+   <p>Wenn Sie sich entschieden haben, dass die Besucher der Seiten <span
+class = "pwgScreen">index.php</span> und <span
+class = "pwgScreen">picture.php</span> werden
+die in der Tabelle <code>history</code>.
+  Auf dieser Registerkarte können Sie mehr über die Seiten erforscht
+  auf Ihrer Homepage mit Hilfe von verschiedenen Filtern.</p>
+ 
+<li><strong>Filter nach Datum</strong>: Wählen Sie den Bereich
+  Beobachtung, die Sie beobachten werden.</li>
+
+<li><strong>Filter Element-Art:</strong> auswählen
+Art von Element, das Sie betrachten die Tätigkeit.</li>
+
+<li><strong>Filter Benutzer</strong>: Wählen Sie den Teilnehmer aus, die Sie
+  möchten Beobachtung der Aktivität.</li>
+
+<li><strong> Filter Name der Datei</strong>: Wählen Sie den Namen der Datei, die Sie
+  möchten Beobachtung der Aktivität.</i>
+
+<li><strong>Filtern nach Bild-ID</strong>: Wählen Sie die Bild-ID, die Sie
+  möchten Beobachtung der Aktivität.</li>
+</ul>
Index: /tags/2.0.2/language/de_DE/help/index.php
===================================================================
--- /tags/2.0.2/language/de_DE/help/index.php	(revision 3278)
+++ /tags/2.0.2/language/de_DE/help/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/language/de_DE/help/maintenance.html
===================================================================
--- /tags/2.0.2/language/de_DE/help/maintenance.html	(revision 3278)
+++ /tags/2.0.2/language/de_DE/help/maintenance.html	(revision 3278)
@@ -0,0 +1,51 @@
+<h2>Wartung</h2>
+
+<p>Für die Zeit der Erzeugung der Seiten, verwendet Piwigo
+Informationen im Cache. Zum Beispiel statt, die Zahl
+der Elemente in jeder Kategorie in jeder Seite neu zu laden,
+Diese Information wird in der Datenbank. In der Theorie, die
+Information muss immer korrekt, aber manchmal kann ein Fehler
+auftreten, und die Informationen im Cache wird falsch.</p>
+
+<p>Informationen werden mit der Zeit unbrauchbar. Sie von der
+Datenbank gibt den Speicherplatz frei.</p>
+
+<ul>
+
+   <li><strong>aktualisieren die Informationen der Kategorien:</strong> Für
+jeder Kategorie, die Informationen zu kontrollieren und / oder zu aktualisieren, werden die
+folgenden: Liste der Kategorien Mütter, Anzahl der Elemente, Datum der letzten
+Element, unter den Kategorien Schwester, Position in der kompletten Baum
+Kategorien. Diese Aktion stellt sicher, auch die Kohärenz der
+Vertreter.</li>
+
+   <li><strong>aktualisieren die Informationen der Bilder:</strong> Für
+jedes Bild, die Informationen zu aktualisieren sind: kompletten Pfad zu dem
+Datei, Durchschnittsnote. <em>Achtung</em>: nicht zu verwechseln mit den
+Meta-Daten synchronisiert werden, die auf dem Bildschirm <span
+class = "pwgScreen">Verwaltung, Kategorien, synchronisieren</span> oder auf
+<span class="pwgScreen">dem Bildschirm bearbeiten Informationen eines Bildes</span>
+(zugänglich von der Seite zur Darstellung eines Bildes<span
+class = "pwgScreen">picture.php</span>).</li>
+
+   <li><strong>Reparieren und Optimierung der Datenbank:</strong>
+Für jede Tabelle der Datenbank PhpWegGallery, die von neu ordnen, Reparatur und Optimierung durchgeführt werden.
+   </li>
+
+</ul>
+
+<ul>
+   <li><strong>das Löschen des Verlaufs detail:</strong> Löscht alle Zeilen
+Tabelle <code>history</code>. Der Bildschirm <span
+class = "pwgScreen">Verwaltung, Sonderangebote, Geschichte</span> zeigt dann
+keine Informationen mehr über die Vergangenheit. <em>Achtung</em>: alle Daten
+gehen verloren, und es gibt keine Möglichkeit, diese wiederherzustellen.</li>
+
+   <li><strong>Löschen der Inhalt der Geschichte:</strong> Entfernt alle Informationen (aus der historischen detail).</li>
+
+   <li><strong>Löschen Sitzungen:</strong> "Löschen"-Sitzungen
+Abgelaufene ..</li>
+
+   <li><strong>Löschen von Arbeitsabläufen Anmeldung genutzt</strong></li>
+
+</ul>
Index: /tags/2.0.2/language/de_DE/help/notification_by_mail.html
===================================================================
--- /tags/2.0.2/language/de_DE/help/notification_by_mail.html	(revision 3278)
+++ /tags/2.0.2/language/de_DE/help/notification_by_mail.html	(revision 3278)
@@ -0,0 +1,15 @@
+<h2>Anmeldung per E-Mail</h2>
+
+<p>Dieser Bildschirm erlaubt es die Einstellungen für die E-Mail-Benachrichtigungen an die Benutzer zu konfigurieren.</p>
+
+<p>Dieser Bildschirm besteht aus 3 Registerkarten:</p>
+
+<h3>Parameter</h3>
+<p>Zugänglich nur für Webmaster, diese Registerkarte enthält Parameter für die Anmeldung per E-Mail.</p>
+
+<h3>Bestätigen</h3>
+<p>Zugänglich nur für Webmaster, die Anmeldung / Abmeldung von Benutzern zur E-Mail-Benachrichtigungen wird hier verwaltet.</p>
+
+<h3>Sende</h3>
+<p>Zugänglich nur für Webmaster und Administratoren, dieser Registerkarte können Sie E-Mails versenden und ihren personalisierten Text der E-Mail hinzufügen.</p>
+
Index: /tags/2.0.2/language/de_DE/help/permalinks.html
===================================================================
--- /tags/2.0.2/language/de_DE/help/permalinks.html	(revision 3278)
+++ /tags/2.0.2/language/de_DE/help/permalinks.html	(revision 3278)
@@ -0,0 +1,7 @@
+<h2>Permalinks</h2>
+
+<p>Permalinks werden verwendet um Wortgenaue URLs der schönsten Kategorien zu erstellen. Wenn einer Kategorie ein Permalink zugeordnet wurde, benötigt man die Kennung der Kategorie in der URL nicht mehr.</p>
+
+<p>Wenn ein Permalink gelöscht wird, können sie diesen in der History speichern, so dass er auch weiterhin funktioniert. In der Permalink history sehen Sie außerdem das Löschdatum, die Anzahl, der Links, die darauf noch verweisen und das Datum der letzten Nutzung dieses Links.</p>
+
+<p>Bitte beachten Sie das ein Permalink nur einmal vergeben werden darf. Gleiche Permalinks für mehrere Kategorien sind nicht möglich.</p>
Index: /tags/2.0.2/language/de_DE/help/search.html
===================================================================
--- /tags/2.0.2/language/de_DE/help/search.html	(revision 3278)
+++ /tags/2.0.2/language/de_DE/help/search.html	(revision 3278)
@@ -0,0 +1,26 @@
+<h2>Suche</h2>
+
+<p>Auf dieser Seite können Sie die gesamte Galerie nach Bildern durchsuchen</p>
+
+<dl>
+
+  <dt>Suche nach Wörtern</dt>
+
+  <dd>Suche nach dem eingegebenen Wörter in allen Attribute in Bezug auf die Bilder
+   in der Galerie. Verwenden Sie * als Platzhalter.</dd>
+  
+  <dt>Suche nach Autor</dt>
+
+  <dd>Verwenden Sie * als Platzhalter.</dd>
+
+  <dt>Suche nach Datum</dt>
+
+  <dd>Wählen Sie ein Startdatum und / oder ein Enddatum. Lassen Sie das 
+  Datum leer, wenn Sie ein Element suchen, was vor einem bestimmten Zeitpunkt eingestellt wurde.
+  Das Jahr muss im letzten Feld mit 4 Ziffern angegeben werden(zB 2005).</dd>
+
+  <dt>Suche in den Kategorien</dt>
+
+  <dd>Beschränken Sie die Suche auf bestimmte Kategorien.</dd>
+
+</dl>
Index: /tags/2.0.2/language/de_DE/help/site_manager.html
===================================================================
--- /tags/2.0.2/language/de_DE/help/site_manager.html	(revision 3278)
+++ /tags/2.0.2/language/de_DE/help/site_manager.html	(revision 3278)
@@ -0,0 +1,56 @@
+<h2>Remote-Sites</h2>
+
+<p>Piwigo bietet die Möglichkeit, mehrere Websites für
+Speichern der Dateien, aus denen Ihre Galerie. Dies kann nützlich sein, wenn
+Ihre Galerie befindet sich auf einem Speicherplatz begrenzt ist und Sie
+haben viele Dateien zu zeigen.</p>
+
+
+<ol>
+
+   <li>Sie die Datei <span
+class = "filename">tools / create_listing_file.php</span> durch eine Änderung der
+Abschnitt Parameter wie <code>$ conf [ 'prefix_thumbnail']</code> oder
+<code>$ conf [ 'use_exif']</code>.</li>
+
+   <li>die Datei <span
+class = "filename">tools / create_listing_file.php</span> geändert auf Ihrer Website
+Remote, im selben Verzeichnis wie die Vertreter Ihrer Verzeichnisse
+Kategorien (wie das Verzeichnis <span class="filename">Galerien</span> von
+dieser Seite) per FTP. Zum Beispiel, dass Sie Zugriff auf <span
+class = "filename">http://exemple.com/galleries/create_listing_file.php</span>.</li>
+
+   <li>Bewußt auf <span class="pwgScreen">Verwaltung, Kategorien,
+Betreiber der Seite</span>. Verlangen eine neue Website, zB <span
+class = "filename"> http://exemple.com/galleries</span>.</li>
+
+   <li>
+
+     <p>eine neue Remote-Site gespeichert wird. 4 Aktionen möglich:</p>
+
+     <ol>
+
+       <li><strong>die Liste</strong>: startet eine Remote-Abfrage für
+Generieren Sie die Remote-Liste</li>
+
+       <li><strong>synchronisieren</strong>: Gibt die Remote-Datei <span
+class = "filename">listing.xml</span> und synchronisiert mit der Datenbank
+Ort</li>
+
+       <li><strong>reinigen</strong>: Der Remote-Datei von
+List</li>
+
+       <li><strong>zerstören</strong>: Der Standort (und alle Elemente
+die damit verbundenen) in der Datenbank</li>
+
+     </ol>
+
+   </li>
+
+</ol>
+
+<!--<p>Sie können auch ausführen, indem Sie
+Sie <span class="filename">listing.xml</span> in der Hand und in der
+Verschieben Ihrem Stammverzeichnis. Sich auf <span
+class = "pwgScreen">Verwaltung, Kategorien, Remote-Sites</span>:
+Piwigo erkennt die Datei und bietet damit einverstanden sind.</p> -->
Index: /tags/2.0.2/language/de_DE/help/synchronize.html
===================================================================
--- /tags/2.0.2/language/de_DE/help/synchronize.html	(revision 3278)
+++ /tags/2.0.2/language/de_DE/help/synchronize.html	(revision 3278)
@@ -0,0 +1,17 @@
+<h2>Synchronisieren</h2>
+
+<ul>
+
+  <li>	
+Es sind 2 verschiedene Synchronisationen möglich: Verzeichnisse / Dateien und Datei-
+Metadaten. Verzeichnisse / Dateien syncronisiert die vorhandenen Dateien mit der Datenbank.
+Syncronisation von Metadaten aktualisiert dieDateiinformationen wie Dateigröße, Abmessungen 
+in Pixeln, EXIF- oder IPTC-Informationen.</li>
+
+  <li>Zuerst müssen immer die Verzeichniss- und Dateiinformationen syncronisiert werden.</li>
+
+  <li>Der Prozess der Synchronisierung kann einige Zeit in Anspruch nehmen (Abhängig von
+der Belastung des Servers und der Menge der zu verwaltenden Dateien), daher ist es
+möglich, Kategorie für Kategorie einzeln zu syncronisieren.</li>
+
+</ul>
Index: /tags/2.0.2/language/de_DE/help/thumbnail.html
===================================================================
--- /tags/2.0.2/language/de_DE/help/thumbnail.html	(revision 3278)
+++ /tags/2.0.2/language/de_DE/help/thumbnail.html	(revision 3278)
@@ -0,0 +1,36 @@
+<h2>Erstellen von Miniaturansichten (Thumbnails)</h2>
+
+<p>Erstellen von fehlenden Miniaturansichten. Die Verwendung dieser Funktion
+ist nicht zu empfehlen, wenn die Galerie ist auf einem Server gehostet
+ziert (Ressourcen des Servers sind begrenzt).</p>
+
+<dl>
+
+   <dt>Version von GD</dt>
+
+   <dd>GD ist eine Grafikbibliothek zur Manipulation von Bildern per
+PHP. Wählen Sie die Version, die auf Ihrem Server installiert ist. Wenn 
+Fehlermeldungen erscheinen, kehren Sie auf die vorherige Seite zurück
+und wählen Sie die andere Version der GD-Biliothek. Falls es überhaupt nicht
+funktionieret, ist  die GD-Biliothek nicht verfügbar.</dd>
+
+   <dt>Breite und Höhe</dt>
+
+   <dd>Bestimmt die maximale Größe der Miniaturen. Das Verhältnis
+Breite / Höhe des Originals wird beibehalten. Die Standardwerte sind
+veränderbar durch die Konfigurationseinstellungen <code>tn_width</code> und
+<code>tn_height</code> (siehe Datei <span
+class = "filename">include / config_default.inc.php</span >).</dd>
+  
+   <dt>Anzahl der zu erstellenden Miniaturen begrenzen</dt>
+
+   <dd>Bitte nicht alle Miniaturen auf einmal erstellen lassen, da
+   dies eine relativ hohe CPU-Last auf dem Server erzeugt.</dd>
+
+   <dt>Format der Datei</dt>
+
+   <dd>Die Miniaturen werden im JPEG-Format erstellt. Nur die Formate PNG und
+JPEG werden verarbeitet. Thumbnails für alle anderen Dateiformate müssen selbst 
+erstellt werden</dd>
+
+</dl>
Index: /tags/2.0.2/language/de_DE/help/user_list.html
===================================================================
--- /tags/2.0.2/language/de_DE/help/user_list.html	(revision 3278)
+++ /tags/2.0.2/language/de_DE/help/user_list.html	(revision 3278)
@@ -0,0 +1,37 @@
+<h2>Benutzer Liste</h2>
+
+<p>Auf dieser Seite können Sie registrierte Benutzer verwalten. Nur Benutzerrechte
+werden auf verschiedenen anderen Seiten verwaltet.</p>
+
+<h3>Hinzufügen eines neuen Nutzers</h3>
+
+<p>Der Administrator kann manuell Benutzer hinzufügen.</p>
+
+<h3>Benutzer Liste</h3>
+
+<p>Die Liste kann gefiltert werden nach Benutzernamen (Eingabe eines * als Platzhalter), Gruppe oder Status. 
+Die Liste kann nach Datum der Registrierung oder Benutzername in aufsteigender
+oder absteigender Reihenfolge sortiert werden.</p>
+
+<p>In diesem Fenster können bestimmte Eigenschaften von mehreren Benutzern zugleich geändert werden
+:</p>
+
+<ul>
+  <li>Benutzer löschen (Bestätigung erforderlich)</li>
+  <li>Status ändern</li>
+  <li>Mitgliedschaft in Gruppen hinzufügen oder entfernen</li>
+  <li>Anzeige-Eigenschaften ändern</li>
+  <li>weitere Eigenschaften ändern</li>
+</ul>
+
+<p>Bei Ziel wird bestimmt, ob die Änderung für markierte Benutzer (Standard) oder alle Benutzer übernommen wird.</p>
+
+<h3>Berater</h3>
+<p>Definition von Benutzer-Berater:</p>
+<ul>
+  <li>Es wird einem Benutzer der Admin-Zugang simuliert.</li>
+  <li>read-only oder nur simulieren-Zugang</li>
+</ul>
+
+<p>Es ist möglich den Berater-Modus mit der Variable $conf['allow_adviser'] einzuschalten.</p>
+<p>Wenn diese Variable als 'true'definiert ist, dann kann man einen Benutzer als Berater definieren.</p>
Index: /tags/2.0.2/language/de_DE/index.php
===================================================================
--- /tags/2.0.2/language/de_DE/index.php	(revision 3278)
+++ /tags/2.0.2/language/de_DE/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/language/de_DE/install.lang.php
===================================================================
--- /tags/2.0.2/language/de_DE/install.lang.php	(revision 3278)
+++ /tags/2.0.2/language/de_DE/install.lang.php	(revision 3278)
@@ -0,0 +1,74 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+$lang['Installation'] = 'Installation';
+$lang['Initial_config'] = 'Basis-Konfiguration';
+$lang['Default_lang'] = 'Standardsprache der Galerie';
+$lang['step1_title'] = 'Konfiguration der Datenbank';
+$lang['step2_title'] = 'Konfiguration des Administrator-Kontos';
+$lang['Start_Install'] = 'Start der Installation';
+$lang['reg_err_mail_address'] = 'Die E-Mail-Adresse muss in der Form xxx@yyy.eee (Beispiel: jack@altern.org)';
+
+$lang['install_webmaster'] = 'Administrator';
+$lang['install_webmaster_info'] = 'Benutzername des Administrators';
+
+$lang['step1_confirmation'] = 'Die Parameter sind korrekt ausgefüllt';
+$lang['step1_err_db'] = 'Die Verbindung zum Server ist OK, aber nicht die Verbindung zu dieser Datenbank';
+$lang['step1_err_server'] = 'Es konnte keine Verbindung zum Datenbankserver aufgebaut werden';
+
+$lang['step1_host'] = 'MySQL Host';
+$lang['step1_host_info'] = 'localhost, sql.multimania.com, toto.freesurf.fr';
+$lang['step1_user'] = 'Benutzer';
+$lang['step1_user_info'] = 'Benutzernamen für die MySQL Datenbank';
+$lang['step1_pass'] = 'Passwort';
+$lang['step1_pass_info'] = 'das von Ihrem Hosting-Provider';
+$lang['step1_database'] = 'Name der Datenbank';
+$lang['step1_database_info'] = 'Passwort für die MySQL Datenbank';
+$lang['step1_prefix'] = 'Vorwahl Tabellen';
+$lang['step1_prefix_info'] = 'die Namen der Tabellen mit diesem Präfix (ermöglicht eine bessere Verwaltung der Datenbank)';
+$lang['step2_err_login1'] = 'gib bitte einen Benutzernamen für den Webmaster an';
+$lang['step2_err_login3'] = 'der Benutzername des Webmasters darf nicht die Zeichen \' und " enthalten';
+$lang['step2_err_pass'] = 'Bitte wählen Sie ein Passwort';
+$lang['install_end_title'] = 'Installation abgeschlossen';
+$lang['step2_pwd'] = 'Passwort';
+$lang['step2_pwd_info'] = 'Administratorpasswort';
+$lang['step2_pwd_conf'] = 'Passwort [Bestätigung]';
+$lang['step2_pwd_conf_info'] = 'Wiederholen Sie das eingegebene Passwort';
+$lang['step1_err_copy'] = 'Kopieren Sie den rosa Text ohne die Bindestriche und fügen Sie ihn in die Datei "include / mysql.inc.php" auf dem Webserver ein (Warnung: die Datei "mysql.inc.php" darf nur die rosa Zeichen enthalten, nicht mehr und nicht weniger)';
+$lang['install_help'] = 'Brauchen Sie Hilfe? Stellen Sie Ihre Frage auf der <a href="%s"> Forum Piwigo </ a>.';
+$lang['install_end_message'] = 'Die Konfiguration der Piwigo abgeschlossen ist, hier ist der nächste Schritt<br /><br />
+* Gehen Sie zum Anmelden auf die Startseite: [ <a href="./identification.php">Identifizierung</a> ] und verwenden Sie die Login / Passwort für Webmaster<br />
+* diesem Login ermöglicht Ihnen den Zugang zu den Verwaltungs-Panel und der Bilder- und Benutzerverwaltung.';
+$lang['conf_mail_webmaster'] = 'Webmaster Mail-Adresse';
+$lang['conf_mail_webmaster_info'] = 'Kontakt E-Mailadresse (nur für angemeldete Benutzer sichtbar)';
+
+$lang['PHP 5 is required'] = 'PHP 5 ist erforderlich';
+$lang['It appears your webhost is currently running PHP %s.'] = 'Es scheint Ihr Webhost ist derzeit laufenden PHP %s.';
+$lang['Piwigo may try to switch your configuration to PHP 5 by creating or modifying a .htaccess file.'] = 'Piwigo wird versuchen um Ihre Konfiguration zu PHP 5 Schalten durch die Schaffung oder Änderung einer .Htaccess-Datei.';
+$lang['Note you can change your configuration by yourself and restart Piwigo after that.'] = 'Hinweis: Sie können Ihre Konfiguration indem manuel Schalten und starten Sie wieder dass Piwigo.';
+$lang['Try to configure PHP 5'] = 'Versuch zu konfigurieren PHP 5';
+$lang['Sorry!'] = 'Bekümmert!';
+$lang['Piwigo was not able to configure PHP 5.'] = 'Piwigo kan nicht PHP 5 zu konfigurieren.';
+$lang["You may referer to your hosting provider's support and see how you could switch to PHP 5 by yourself."] = "Sie können sich beziehen auf Ihrem Hosting-Anbieter die Unterstützung und sehen wie Sie könnte Umstellung auf PHP 5 von Ihnen.";
+$lang['Hope to see you back soon.'] = 'Hoffen, Sie bald wieder zurück.';
+?>
Index: /tags/2.0.2/language/de_DE/iso.txt
===================================================================
--- /tags/2.0.2/language/de_DE/iso.txt	(revision 3278)
+++ /tags/2.0.2/language/de_DE/iso.txt	(revision 3278)
@@ -0,0 +1,1 @@
+Deutsch [DE]
Index: /tags/2.0.2/language/de_DE/upgrade.lang.php
===================================================================
--- /tags/2.0.2/language/de_DE/upgrade.lang.php	(revision 3278)
+++ /tags/2.0.2/language/de_DE/upgrade.lang.php	(revision 3278)
@@ -0,0 +1,44 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+$lang['Upgrade'] = 'Upgrade';
+$lang['introduction message'] = 'Diese Seite schlägt vor, Ihre Datenbank auf die aktuelle Version upzugraden, die Ihre vorhandenen Daten enthält. 
+Sie benutzen zur Zeit die Version <strong>release %s</strong> (oder kompatibel).';
+$lang['Upgrade from %s to %s'] = 'Upgrade von der Version %s auf %s';
+$lang['Statistics'] = 'Statistik';
+$lang['total upgrade time'] = 'total upgrade time';
+$lang['total SQL time'] = 'total SQL time';
+$lang['SQL queries'] = 'SQL queries';
+$lang['Upgrade informations'] = 'Upgrade Informationen';
+$lang['perform a maintenance check'] = 'Führen Sie eine Datenbanküberprüfung durch in [Verwaltung>Erweiterte Einstellungen>Wartung] falls ein Problem auftritt.';
+$lang['deactivated plugins'] = 'Als Vorsichtsmaßnahme wurden folgende Plugins deaktiviert. Prüfen Sie, ob ein Update verfügbar ist oder die Plugins kompatibel zur neuen Version sind, bevor Sie diese wieder aktivieren:';
+$lang['upgrade login message'] = 'Nur Administratoren dürfen ein Upgrade durchführen. Bitte loggen Sie sich ein';
+$lang['You do not have access rights to run upgrade'] = 'Sie haben nicht die erforderlichen Rechte ein Upgrade durchzuführen';
+$lang['in include/mysql.inc.php, before ?>, insert:'] = 'In die Datei<i>include/mysql.inc.php</i>, vor <b>?></b>, bitte folgenden Text einfügen:';
+
+// Upgrade informations from upgrade_1.3.1.php
+$lang['all sub-categories of private categories become private'] = 'Alle Unterkategorien von privaten Kategorien bekommen den Status "private Kategorie"';
+$lang['user permissions and group permissions have been erased'] = 'Alle Benutzer- und Gruppenberechtigungen/beschränkungen wurden entfernt';
+$lang['only thumbnails prefix and webmaster mail saved'] = 'Es wurden nur die Thumbnail-Präfixe und die Mailadresse des Webmasters übernommen';
+
+?>
Index: /tags/2.0.2/language/en_UK/about.html
===================================================================
--- /tags/2.0.2/language/en_UK/about.html	(revision 3278)
+++ /tags/2.0.2/language/en_UK/about.html	(revision 3278)
@@ -0,0 +1,10 @@
+  <li>Piwigo is a web application giving you the possibility to
+  create an online images gallery easily.</li>
+
+  <li>Technicaly, Piwigo is fully developped with PHP (the elePHPant)
+  with a MySQL database (the SQuirreL).</li>
+
+  <li>If you have any suggestions or comments, please visit <a
+  href="http://piwigo.org">Piwigo</a> official site, and
+  its dedicated <a href="http://forum.Piwigo.net">forum</a>.</li>
+
Index: /tags/2.0.2/language/en_UK/admin.lang.php
===================================================================
--- /tags/2.0.2/language/en_UK/admin.lang.php	(revision 3278)
+++ /tags/2.0.2/language/en_UK/admin.lang.php	(revision 3278)
@@ -0,0 +1,650 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+$lang['%d association'] = '%d association';
+$lang['%d associations'] = '%d associations';
+$lang['cat_inclu_part1_S'] = '%d category including ';
+$lang['cat_inclu_part1_P'] = '%d categories including ';
+$lang['cat_inclu_part2_S'] = '%d physical';
+$lang['cat_inclu_part2_P'] = '%d physical';
+$lang['cat_inclu_part3_S'] = ' and %d virtual';
+$lang['cat_inclu_part3_P'] = ' and %d virtual';
+$lang['%d category moved'] = '%d category moved';
+$lang['%d categories moved'] = '%d categories moved';
+$lang['%d group'] = '%d group';
+$lang['%d groups'] = '%d groups';
+$lang['%d member'] = '%d member';
+$lang['%d members'] = '%d members';
+$lang['%d tag'] = '%d tag';
+$lang['%d tags'] = '%d tags';
+$lang['%d user comment rejected'] = '%d user comment rejected';
+$lang['%d user comments rejected'] = '%d user comments rejected';
+$lang['%d user comment validated'] = '%d user comment validated';
+$lang['%d user comments validated'] = '%d user comments validated';
+$lang['%d user deleted'] = '%d user deleted';
+$lang['%d users deleted'] = '%d users deleted';
+$lang['%d user'] = '%d user';
+$lang['%d users'] = '%d users';
+$lang['%d waiting for validation'] = '%d waiting for validation';
+$lang['%d waiting pictures rejected'] = '%d waiting pictures rejected';
+$lang['%d waiting pictures validated'] = '%d waiting pictures validated';
+$lang['Actions'] = 'Actions';
+$lang['Activate'] = 'Activate';
+$lang['Add/delete a permalink'] = 'Add/delete a permalink';
+$lang['Add a tag'] = 'Add a tag';
+$lang['Add a user'] = 'Add a user';
+$lang['Add group'] = 'Add group';
+$lang['Add selected elements to caddie'] = 'Add selected elements to caddie';
+$lang['Add'] = 'Add';
+$lang['Allow user registration'] = 'Allow user registration';
+$lang['Apply to subcategories'] = 'Apply to subcategories';
+$lang['Are you sure?'] = 'Are you sure?';
+$lang['Associated'] = 'Associated';
+$lang['Association to categories'] = 'Association to categories';
+$lang['Batch management'] = 'Batch management';
+$lang['Caddie management'] = 'Caddie management';
+$lang['Caddie'] = 'Caddie';
+$lang['Categories authorized thanks to group associations'] = 'Categories authorized thanks to group associations';
+$lang['Categories manual order was saved'] = 'Categories manual order was saved';
+$lang['Categories ordered alphanumerically'] = 'Categories ordered alphanumerically';
+$lang['Category elements associated to the following categories: %s'] = 'Category elements associated to the following categories: %s';
+$lang['Check for upgrade failed for unknown reasons.'] = 'Check for upgrade failed for unknown reasons.';
+$lang['Check for upgrade'] = 'Check for upgrade';
+$lang['Comments for all'] = 'Comments for all';
+$lang['Controversy'] = 'Controversy';
+$lang['Current name'] = 'Current name';
+$lang['Database'] = 'Database';
+$lang['Deactivate'] = 'Deactivate';
+$lang['Delete Representant'] = 'Delete Representant';
+$lang['Delete selected tags'] = 'Delete selected tags';
+$lang['Delete selected users'] = 'Delete selected users';
+$lang['Deletions'] = 'Deletions';
+$lang['Deny selected groups'] = 'Deny selected groups';
+$lang['Deny selected users'] = 'Deny selected users';
+$lang['Description'] = 'Description';
+$lang['Display options'] = 'Display options';
+$lang['Dissociated'] = 'Dissociated';
+$lang['Does not represent'] = 'Does not represent';
+$lang['Edit all picture informations'] = 'Edit all picture informations';
+$lang['Edit selected tags'] = 'Edit selected tags';
+$lang['Edit tags'] = 'Edit tags';
+$lang['Elements'] = 'Elements';
+$lang['Email administrators when a new user registers'] = 'Email admins when a new user registers';
+$lang['Email administrators when a valid comment is entered'] = 'Email admins when a valid comment is entered';
+$lang['Email administrators when a comment requires validation'] = 'Email admins when a comment requires validation';
+$lang['Email administrators when a picture is uploaded'] = 'Email admins when a picture is uploaded';
+$lang['Empty caddie'] = 'Empty caddie';
+$lang['Environment'] = 'Environment';
+$lang['Form'] = 'Form';
+$lang['Gallery URL'] = 'Gallery URL';
+$lang['Gallery description'] = 'Gallery description';
+$lang['Gallery title'] = 'Gallery title';
+$lang['Grant selected groups'] = 'Grant selected groups';
+$lang['Grant selected users'] = 'Grant selected users';
+$lang['Group name'] = 'Group name';
+$lang['Groups'] = 'Groups';
+$lang['Guests'] = 'Guests';
+$lang['History'] = 'History';
+$lang['Informations'] = 'Informations';
+$lang['Install'] = 'Install';
+$lang['Link all category elements to a new category'] = 'Link all category elements to a new category';
+$lang['Link all category elements to some existing categories'] = 'Link all category elements to some existing categories';
+$lang['Linked categories'] = 'Linked categories';
+$lang['Lock gallery'] = 'Lock gallery';
+$lang['Maintenance'] = 'Maintenance';
+$lang['Manage permissions for a category'] = 'Manage permissions for a category';
+$lang['Manage permissions for group "%s"'] = 'Manage permissions for group "%s"';
+$lang['Manage permissions for user "%s"'] = 'Manage permissions for user "%s"';
+$lang['Manage tags'] = 'Manage tags';
+$lang['Members'] = 'Members';
+$lang['Metadata synchronized from file'] = 'Metadata synchronized from file';
+$lang['Move categories'] = 'Move categories';
+$lang['Move'] = 'Move';
+$lang['Name'] = 'Name';
+$lang['New name'] = 'New name';
+$lang['New parent category'] = 'New parent category';
+$lang['New tag'] = 'New tag';
+$lang['No tag defined. Use Administration>Pictures>Tags'] = 'No tag defined. Use Administration>Pictures>Tags';
+$lang['Number of comments per page'] = 'Number of comments per page';
+$lang['Number of rates'] = 'Number of rates';
+$lang['Number of thumbnails to create'] = 'Number of thumbnails to create';
+$lang['Only private categories are listed'] = 'Only private categories are listed';
+$lang['Operating system'] = 'Operating system';
+$lang['Options'] = 'Options';
+$lang['Order alphanumerically'] = 'Order alphanumerically';
+$lang['Other private categories'] = 'Other private categories';
+$lang['Page banner'] = 'Page banner';
+$lang['Parent category'] = 'Parent category';
+$lang['Path'] = 'Path';
+$lang['Permalink'] = 'Permalink';
+$lang['Permalink_%s_histo_used_by_%s'] = 'Permalink %s has been previously used by category %s. Delete from the permalink history first';
+$lang['Permalink_name_rule'] = 'The permalink name must be composed of a-z, A-Z, 0-9, "-", "_" or "/". It must not be numeric or start with number followed by "-"';
+$lang['Permalink %s is already used by category %s'] = 'Permalink %s is already used by category %s';
+$lang['Permalink history'] = 'Permalink history';
+$lang['Permalinks'] = 'Permalinks';
+$lang['Permission denied'] = 'Permission denied';
+$lang['Permission granted thanks to a group'] = 'Permission granted thanks to a group';
+$lang['Permission granted'] = 'Permission granted';
+$lang['Picture informations updated'] = 'Picture informations updated';
+$lang['Plugins'] = 'Plugins';
+$lang['Position'] = 'Position';
+$lang['Preferences'] = 'Preferences';
+$lang['Properties'] = 'Properties';
+$lang['Random picture'] = 'Random picture';
+$lang['Rate date'] = 'Rate date';
+$lang['Rating by guests'] = 'Rating by guests';
+$lang['Rating'] = 'Rating';
+$lang['Reject All'] = 'Reject All';
+$lang['Reject'] = 'Reject';
+$lang['Representant'] = 'Representant';
+$lang['Representation of categories'] = 'Representation of categories';
+$lang['Representative'] = 'Representative';
+$lang['Represents'] = 'Represents';
+$lang['Save order'] = 'Save order';
+$lang['Save to permalink history'] = 'Save to permalink history';
+$lang['Select at least one category'] = 'Select at least one category';
+$lang['Select at least one picture'] = 'Select at least one picture';
+$lang['Select at least one user'] = 'Select at least one user';
+$lang['Show info'] = 'Show info';
+$lang['Site manager'] = 'Site manager';
+$lang['Status'] = 'Status';
+$lang['Statistics'] = 'Statistics';
+$lang['Storage category'] = 'Storage category';
+$lang['Sum of rates'] = 'Sum of rates';
+$lang['Tag "%s" already exists'] = 'Tag "%s" already exists';
+$lang['Tag "%s" was added'] = 'Tag "%s" was added';
+$lang['Tag selection'] = 'Tag selection';
+$lang['Take selected elements out of caddie'] = 'Take selected elements out of caddie';
+$lang['The %d following tag were deleted'] = 'The following tag were deleted';
+$lang['The %d following tags were deleted'] = 'The %d following tags were deleted';
+$lang['Unable to check for upgrade.'] = 'Unable to check for upgrade.';
+$lang['Uninstall'] = 'Uninstall';
+$lang['Use default sort order']='Use the default image sort order (defined in the configuration file)';
+$lang['User comments validation'] = 'User comments validation';
+$lang['Users'] = 'Users';
+$lang['Validate All'] = 'Validate All';
+$lang['Validate'] = 'Validate';
+$lang['Validation'] = 'Validation';
+$lang['Version'] = 'Version';
+$lang['Virtual categories movement'] = 'Virtual categories movement';
+$lang['Virtual categories to move'] = 'Virtual categories to move';
+$lang['Virtual category name'] = 'Virtual category name';
+$lang['Webmaster cannot be deleted'] = 'Webmaster cannot be deleted';
+$lang['You are running on development sources, no check possible.'] = 'You are running on development sources, no check possible.';
+$lang['You cannot delete your account'] = "You cannot delete your account";
+$lang['You cannot move a category in its own sub category'] = 'You cannot move a category in its own sub category';
+$lang['You need to confirm deletion'] = 'You need to confirm deletion';
+$lang['add tags'] = 'add tags';
+$lang['adviser'] = 'Adviser';
+$lang['associate to category'] = 'associate to category';
+$lang['associate to group'] = 'associate to group';
+$lang['authorized'] = 'Authorized';
+$lang['cat_add'] = 'Add a virtual category';
+$lang['cat_comments_title'] = 'Authorize users to add comments on selected categories';
+$lang['cat_error_name'] = 'The name of a category should not be empty';
+$lang['cat_lock_title'] = 'Lock categories';
+$lang['cat_private'] = 'Private category';
+$lang['cat_public'] = 'Public category';
+$lang['cat_representant'] = 'Find a new representant by random';
+$lang['cat_security'] = 'Public / Private';
+$lang['cat_status_title'] = 'Manage authorizations for selected categories';
+$lang['cat_upload_title'] = 'Select uploadable categories';
+$lang['cat_virtual_added'] = 'Virtual category added';
+$lang['cat_virtual_deleted'] = 'Virtual category deleted';
+$lang['category'] = 'Category';
+$lang['conf_access'] = 'Access type';
+$lang['conf_comments_title'] = 'Comments';
+$lang['conf_confirmation'] = 'Information data registered in database';
+$lang['conf_display'] = 'Default display';
+$lang['conf_history_title'] = 'History';
+$lang['conf_gallery_url_error'] = 'The gallery URL is not valid.';
+$lang['conf_main_title'] = 'Main';
+$lang['conf_nb_comment_page_error'] = 'The number of comments a page must be between 5 and 50 included.';
+$lang['config'] = 'Configuration';
+$lang['confirm'] = 'confirm';
+$lang['Date'] = 'Date';
+$lang['delete category'] = 'delete category';
+$lang['dissociate from category'] = 'dissociate from category';
+$lang['dissociate from group'] = 'dissociate from group';
+$lang['edit category permissions'] = 'edit category permissions';
+$lang['editcat_confirm'] = 'Category informations updated successfully.';
+$lang['editcat_uploadable'] = 'Authorize upload';
+$lang['elements per page'] = 'elements per page';
+$lang['elements'] = 'elements';
+$lang['enabled_high'] = 'High definition enabled';
+$lang['file'] = 'File';
+$lang['filesize'] = 'Filesize';
+$lang['first element added on %s'] = 'first element added on %s';
+$lang['forbidden'] = 'Forbidden';
+$lang['conf_general'] = 'General';
+$lang['global mode'] = 'global mode';
+$lang['group "%s" added'] = 'group "%s" added';
+$lang['group "%s" deleted'] = 'group "%s" deleted';
+$lang['group "%s" updated'] = 'group "%s" updated';
+$lang['group'] = 'group';
+$lang['group_add_error1'] = 'The name of a group must not contain " or \' or be empty.';
+$lang['group_add_error2'] = 'This name is already used by another group.';
+$lang['groups'] = 'Groups';
+$lang['instructions'] = 'Instructions';
+$lang['is_high_disabled'] = '';
+$lang['is_high_enabled'] = 'High definition';
+$lang['jump to category'] = 'jump to category';
+$lang['jump to image'] = 'jump to image';
+$lang['leave'] = 'leave';
+$lang['lock'] = 'Lock';
+$lang['locked'] = 'Locked';
+$lang['manage category elements'] = 'manage category elements';
+$lang['manage sub-categories'] = 'manage sub-categories';
+$lang['manage'] = 'Manage';
+$lang['maximum height'] = 'maximum height';
+$lang['maximum width'] = 'maximum width';
+$lang['nbm_background_treatment_redirect_second'] = 'Execution time is out, treatment must be continue [Estmated time: %d second].';
+$lang['nbm_background_treatment_redirect_seconds'] = 'Execution time is out, treatment must be continue [Estmated time: %d seconds].';
+$lang['nbm_break_timeout_list_user'] = 'Prepared time for list of users to send mail is limited. Others users are not listed.';
+$lang['nbm_break_timeout_send_mail'] = 'Time to send mail is limited. Others mails are skipped.';
+$lang['nbm_col_check_user_send_mail'] = 'To send ?';
+$lang['nbm_col_last_send'] = 'Last send';
+$lang['nbm_col_mail'] = 'email';
+$lang['nbm_col_user'] = 'User';
+$lang['nbm_complementary_mail_content'] = 'Complementary mail content';
+$lang['nbm_content_byebye'] = 'See you soon,';
+$lang['nbm_content_goto_1'] = 'Go to ';
+$lang['nbm_content_goto_2'] = '.';
+$lang['nbm_content_hello_1'] = 'Hello ';
+$lang['nbm_content_hello_2'] = ',';
+$lang['nbm_content_new_elements'] = 'New elements were added ';
+$lang['nbm_content_new_elements_single'] = ' on ';
+$lang['nbm_content_new_elements_between_1'] = 'between ';
+$lang['nbm_content_new_elements_between_2'] = ' and ';
+$lang['nbm_content_subscribe_by_admin'] = 'The webmaster has subscribed you to receiving notifications by mail.';
+$lang['nbm_content_subscribe_by_himself'] = 'You have subscribed to receiving notifications by mail.';
+$lang['nbm_content_subscribe_link'] = 'To subscribe';
+$lang['nbm_content_problem_contact'] = 'If you encounter problems or have any question, please send a message to ';
+$lang['nbm_content_pb_contact_object'] = '[NBM] Problems or questions';
+$lang['nbm_content_unsubscribe_by_admin'] = 'The webmaster has unsubscribed you from receiving notifications by mail.';
+$lang['nbm_content_unsubscribe_by_himself'] = 'You have unsubscribed from receiving notifications by mail.';
+$lang['nbm_content_click_on'] = ', click on ';
+$lang['nbm_content_unsubscribe_link'] = 'To unsubscribe';
+$lang['nbm_info_send_mail_as'] = 'With blank value, gallery title will be used';
+$lang['nbm_item_notification'] = 'Notification';
+$lang['nbm_msg_error_sending_email_to'] = 'Error when sending email to %s [%s].';
+$lang['nbm_msg_mail_sent_to'] = 'Mail sent to %s [%s].';
+$lang['nbm_msg_n_mail_sent'] = '%d mail was sent.';
+$lang['nbm_msg_n_mails_sent'] = '%d mails were sent.';
+$lang['nbm_msg_n_mail_not_send'] = '%d mail was not sent.';
+$lang['nbm_msg_n_mails_not_send'] = '%d mails were not sent.';
+$lang['nbm_no_mail_to_send'] = 'No mail to send.';
+$lang['nbm_no_user_available_to_send_L1'] = 'There is no available subscribers to mail.';
+$lang['nbm_no_user_available_to_send_L2'] = 'Subscribers could be listed (available) only if there is new elements to notify.';
+$lang['nbm_no_user_available_to_send_L3'] = 'Anyway only webmasters can see this tab and never administrators.';
+$lang['nbm_no_user_to send_notifications_by_mail'] = 'No user to send notifications by mail.';
+$lang['nbm_object_news'] = 'New elements added';
+$lang['nbm_object_subscribe'] = 'Subscribe to notification by mail';
+$lang['nbm_object_unsubscribe'] = 'Unsubscribe from notification by mail';
+$lang['nbm_param_mode'] = 'Parameter';
+$lang['nbm_redirect_msg'] = 'Processing treatment.'."\n\n".'Please wait...';
+$lang['nbm_repost_submit'] = 'Continue processing treatment';
+$lang['nbm_send_complementary_mail_content'] = 'Complementary mail content';
+$lang['nbm_send_detailed_content'] = 'Add detailed content';
+$lang['nbm_send_mail_as'] = 'Send mail as';
+$lang['nbm_send_mail_to_users'] = 'Send mail to users';
+$lang['nbm_send_mode'] = 'Send';
+$lang['nbm_send_options'] = 'Options';
+$lang['nbm_send_submit'] = 'Send';
+$lang['nbm_subscribe_col'] = 'Subscribed';
+$lang['nbm_subscribe_mode'] = 'Subscribe';
+$lang['nbm_title_param'] = 'Parameters';
+$lang['nbm_title_send'] = 'Select recipients';
+$lang['nbm_title_subscribe'] = 'Subscribe/unsubscribe users';
+$lang['nbm_unsubscribe_col'] = 'Unsubscribed';
+$lang['nbm_updated_param_count'] = '%d parameter was updated.';
+$lang['nbm_updated_params_count'] = '%d parameters were updated.';
+$lang['nbm_user_change_enabled_error_on_updated_data_count'] = '%d user was not updated.';
+$lang['nbm_users_change_enabled_error_on_updated_data_count'] = '%d users were not updated.';
+$lang['nbm_user_change_enabled_false'] = 'User %s [%s] was removed from the subscription list.';
+$lang['nbm_user_change_enabled_true'] = 'User %s [%s] was added to the subscription list.';
+$lang['nbm_user_change_enabled_updated_data_count'] = '%d user was updated.';
+$lang['nbm_users_change_enabled_updated_data_count'] = '%d users were updated.';
+$lang['nbm_user_not_change_enabled_false'] = 'User %s [%s] was not removed from the subscription list.';
+$lang['nbm_user_not_change_enabled_true'] = 'User %s [%s] was not added to the subscription list.';
+$lang['nbm_user_x_added'] = 'User %s [%s] added.';
+$lang['nbm_warning_subscribe_unsubscribe'] = 'Warning: subscribing or unsubscribing will send mails to users';
+$lang['nbm_send_html_mail'] = 'Send mail on HTML format';
+$lang['nbm_send_recent_post_dates'] = 'Include display of recent pictures group by dates';
+$lang['nbm_info_send_recent_post_dates'] = 'Available only with HTML format';
+$lang['no_write_access'] = 'no write access';
+$lang['path'] = 'path';
+$lang['permissions'] = 'Permissions';
+$lang['private'] = 'private';
+$lang['properties'] = 'Properties';
+$lang['public'] = 'public';
+$lang['purge never used notification feeds'] = 'Purge never used notification feeds';
+$lang['purge sessions'] = 'Purge sessions';
+$lang['randomly represented'] = 'randomly represented';
+$lang['registration_date'] = 'registration date';
+$lang['remote_site'] = 'Remote site';
+$lang['remote_site_clean'] = 'clean';
+$lang['remote_site_clean_hint'] = 'remove remote listing.xml file';
+$lang['remote_site_generate'] = 'generate listing';
+$lang['remote_site_generate_hint'] = 'generate file listing.xml on remote site';
+$lang['remote_site_local_create'] = 'Create this site';
+$lang['remote_site_local_found'] = 'A local listing.xml file has been found for ';
+$lang['remote_site_local_update'] = 'read local listing.xml and update';
+$lang['remote_site_test'] = 'test';
+$lang['remote_site_test_hint'] = 'test this remote site';
+$lang['remote_site_uncorrect_url'] = 'Remote site url must start by http or https and must only contain characters among "/", "a-zA-Z0-9", "-" or "_"';
+$lang['remove tags'] = 'remove tags';
+$lang['repair and optimize database'] = 'Repair and optimize database';
+$lang['selection'] = 'selection';
+$lang['set to'] = 'set to';
+$lang['singly represented'] = 'singly represented';
+$lang['site_already_exists'] = 'This site already exists';
+$lang['site_create'] = 'Create a new site : (give its URL to create_listing_file.php)';
+$lang['site_created'] = 'created';
+$lang['site_delete'] = 'delete';
+$lang['site_delete_hint'] = 'delete this site and all its attached elements';
+$lang['site_deleted'] = 'deleted';
+$lang['site_err'] = 'an error happened';
+$lang['site_err_remote_file_not_found'] = 'file create_listing_file.php on remote site was not found';
+$lang['site_local'] = 'Local';
+$lang['site_remote'] = 'Remote';
+$lang['site_synchronize'] = 'synchronize';
+$lang['site_synchronize_hint'] = 'update the database from files';
+$lang['status'] = 'status';
+$lang['storage'] = 'Directory';
+$lang['sub-categories'] = 'sub-categories';
+$lang['synchronize metadata'] = 'synchronize metadata';
+$lang['synchronize'] = 'synchronize';
+$lang['target'] = 'target';
+$lang['thumbnail'] = 'Thumbnail';
+$lang['title'] = 'title';
+$lang['title_categories'] = 'Categories management';
+$lang['title_configuration'] = 'Piwigo configuration';
+$lang['title_default'] = 'Piwigo administration';
+$lang['title_edit_cat'] = 'Edit a category';
+$lang['title_groups'] = 'Group management';
+$lang['title_liste_users'] = 'User list';
+$lang['title_picmod'] = 'Modify informations about a picture';
+$lang['title_thumbnails'] = 'Thumbnail creation';
+$lang['title_update'] = 'Database synchronization with files';
+$lang['title_upload'] = 'Pictures waiting for validation';
+$lang['tn_all'] = 'all';
+$lang['tn_alone_title'] = 'pictures without thumbnail (jpeg and png only)';
+$lang['tn_err_height'] = 'height must be a number superior to';
+$lang['tn_err_width'] = 'width must be a number superior to';
+$lang['tn_format'] = 'for the file format';
+$lang['tn_no_missing'] = 'No missing thumbnail';
+$lang['tn_no_support'] = 'Picture unreachable or no support';
+$lang['tn_params_GD'] = 'GD version';
+$lang['tn_params_title'] = 'Miniaturization parameters';
+$lang['tn_results_gen_time'] = 'generated in';
+$lang['tn_results_title'] = 'Results of miniaturization';
+$lang['tn_stats'] = 'General statistics';
+$lang['tn_stats_max'] = 'max time';
+$lang['tn_stats_mean'] = 'average time';
+$lang['tn_stats_min'] = 'min time';
+$lang['tn_stats_nb'] = 'number of miniaturized pictures';
+$lang['tn_stats_total'] = 'total time';
+$lang['tn_thisformat'] = 'for this file format';
+$lang['unit mode'] = 'unit mode';
+$lang['unlocked'] = 'Unlocked';
+$lang['unset'] = 'unset';
+$lang['up'] = 'Move up';
+$lang['update categories informations'] = 'Update categories informations';
+$lang['update images informations'] = 'Update images informations';
+$lang['update'] = 'Synchronize';
+$lang['update_cats_subset'] = 'reduce to single existing categories';
+$lang['update_default_title'] = 'Choose an option';
+$lang['update_display_info'] = 'display maximum informations (added categories and elements, deleted categories and elements)';
+$lang['update_err_pwg_version_differs'] = 'Piwigo version differs on the remote site';
+$lang['update_err_pwg_version_differs_info'] = 'Version of create_listing_file.php on the remote site and Piwigo must be the same';
+$lang['update_err_remote_listing_not_found'] = 'listing.xml file was not found';
+$lang['update_err_remote_listing_not_found_info'] = 'listing.xml file was not found on the remote site. This file is generated by choosing the "generate listing" command in the Site manager';
+$lang['update_error_list_title'] = 'Error list';
+$lang['update_errors_caption'] = 'Errors caption';
+$lang['update_infos_title'] = 'Detailed informations';
+$lang['update_missing_file_or_dir'] = 'File/directory read error';
+$lang['update_missing_file_or_dir_info'] = 'The file or directory cannot be accessed (either it does not exist or the access is denied)';
+$lang['update_missing_tn_info'] = 'a picture filetype requires a thumbnail. The thumbnail must be present in the sub-directory "thumbnail" of the category directory. The thumbnail filename must start with the configured thumbnail prefix and the extension must be among the following list :';
+$lang['update_missing_tn_short'] = 'missing thumbnail';
+$lang['update_nb_del_categories'] = 'categories deleted in the database';
+$lang['update_nb_del_elements'] = 'elements deleted in the database';
+$lang['update_nb_elements_metadata_available'] = 'images candidates for metadata synchronization';
+$lang['update_nb_elements_metadata_sync'] = 'elements informations synchronized with files metadata';
+$lang['update_nb_errors'] = 'errors during synchronization';
+$lang['update_nb_new_categories'] = 'categories added in the database';
+$lang['update_nb_new_elements'] = 'elements added in the database';
+$lang['update_nb_upd_elements'] = 'elements updated in the database';
+$lang['update_part_research'] = 'Search for new images in the directories';
+$lang['update_research_added'] = 'added';
+$lang['update_research_deleted'] = 'deleted';
+$lang['update_result_metadata'] = 'Metadata synchronization results';
+$lang['update_simulate'] = 'only perform a simulation (no change in database will be made)';
+$lang['update_simulation_title'] = '[Simulation]';
+$lang['update_sync_all'] = 'directories + files';
+$lang['update_sync_dirs'] = 'only directories';
+$lang['update_sync_files'] = 'synchronize files structure with database';
+$lang['update_sync_metadata'] = 'synchronize files metadata with database elements informations';
+$lang['update_sync_metadata_all'] = 'even already synchronized elements';
+$lang['update_used_metadata'] = 'Used metadata';
+$lang['update_wrong_dirname_info'] = 'The name of directories and files must be composed of letters, figures, "-", "_" or "."';
+$lang['update_wrong_dirname_short'] = 'wrong filename';
+$lang['upload'] = 'Upload';
+$lang['user "%s" added'] = 'user "%s" added';
+$lang['user_status'] = 'User status';
+$lang['user_status_admin'] = 'Administrator';
+$lang['user_status_generic'] = 'Generic';
+$lang['user_status_guest'] = 'Guest';
+$lang['user_status_normal'] = 'User';
+$lang['user_status_webmaster'] = 'Webmaster';
+$lang['username'] = 'username';
+$lang['users'] = 'Users';
+$lang['virtual_category'] = 'Virtual category';
+$lang['waiting'] = 'Waiting';
+$lang['is_default_group'] = 'default';
+$lang['toggle_is_default_group'] = 'Toggle \'default group\' property';
+$lang['Advanced_features'] = 'Advanced features';
+$lang['Elements_not_linked'] = 'Not linked elements';
+$lang['special_admin_menu'] = 'Specials';
+$lang['Duplicates'] = 'Files with same name in more than one physical category';
+
+$lang['Overall'] = 'Overall';
+$lang['Year'] = 'Year';
+$lang['Month'] = 'Month';
+$lang['Day'] = 'Day';
+$lang['Pages seen'] = 'Pages seen';
+$lang['Pictures'] = 'Pictures';
+$lang['time'] = 'Time';
+$lang['user'] = 'User';
+$lang['IP'] = 'IP';
+$lang['image'] = 'Element';
+$lang['section'] = 'Section';
+$lang['tags'] = 'Tags';
+$lang['conf_history_guest'] = 'Save page visits by guests';
+$lang['conf_history_user'] = 'Save page visits by users';
+$lang['conf_history_admin'] = 'Save page visits by administrators';
+$lang['cat_options_title'] = 'Properties';
+$lang['An information email was sent to group "%s"'] = 'An information email was sent to group "%s';
+$lang['Send an information email to group members'] = 'Send an information email to group members';
+$lang['Group'] = 'Group';
+$lang['[%s] Come to visit the category %s'] = '[%s] Come to visit the category %s';
+$lang['Hello,'] = 'Hello,';
+$lang['See you soon.'] = 'See you soon.';
+$lang['Come to discover the category:'] = 'Come to discover the category:';
+$lang['mail_content'] = 'Mail content';
+$lang['none'] = 'none';
+$lang['high'] = 'high';
+$lang['other'] = 'other';
+$lang['Element type'] = 'Element type';
+$lang['User'] = 'User';
+$lang['Image id'] = 'Image id';
+$lang['Summary'] = 'Summary';
+$lang['%d line filtered'] = '%d line filtered';
+$lang['%d lines filtered'] = '%d lines filtered';
+$lang['%d guest'] = '%d guest';
+$lang['%d guests'] = '%d guests';
+$lang['Hour'] = 'Hour';
+$lang['is_the_guest'] = 'guest';
+$lang['is_the_default'] = 'default values';
+$lang['High filesize'] = 'High filesize';
+// --------- Starting below: New or revised $lang ---- from version 1.7.1
+$lang['Guest cannot be deleted'] = 'Guest cannot be deleted';
+$lang['Default user cannot be deleted'] = 'Default user cannot be deleted';
+$lang['purge history detail'] = 'Purge history detail';
+$lang['purge history summary'] = 'Purge history summary';
+$lang['c13y_title'] = 'Check integrity';
+$lang['c13y_Anomaly'] = 'Anomaly';
+$lang['c13y_Correction'] = 'Correction';
+$lang['c13y_Automatic_correction'] = 'Automatic correction';
+$lang['c13y_Impossible_automatic_correction'] = 'Impossible automatic correction';
+$lang['c13y_Correction_applied_success'] = 'Correction applied with success';
+$lang['c13y_Correction_applied_error'] = 'Correction applied with error';
+$lang['c13y_anomaly_count'] = '%d anomaly has been detected.';
+$lang['c13y_anomalies_count'] = '%d anomalies have been detected.';
+$lang['c13y_anomaly_corrected_count'] = '%d anomaly has been corrected.';
+$lang['c13y_anomalies_corrected_count'] = '%d anomalies have been detected corrected.';
+$lang['c13y_anomaly_not_corrected_count'] = '%d anomaly has not been corrected.';
+$lang['c13y_anomalies_not_corrected_count'] = '%d anomalies have not been corrected.';
+$lang['c13y_more_info'] = 'Go to %s or %s for more informations';
+$lang['c13y_more_info_forum'] = 'the forum';
+$lang['c13y_more_info_wiki'] = 'the wiki';
+$lang['c13y_exif_anomaly'] = '%s value is not correct file because exif are not supported';
+$lang['c13y_exif_correction'] = '%s must be to set to false in your config_local.inc.php file';
+$lang['c13y_guest_non_existent'] = 'Main "guest" user does not exist';
+$lang['c13y_bad_guest_status'] = 'Main "guest" user status is incorrect';
+$lang['c13y_default_non_existent'] = 'Default user does not exist';
+$lang['c13y_webmaster_non_existent'] = 'Main "webmaster" user does not exist';
+$lang['c13y_bad_webmaster_status'] = 'Main "webmaster" user status is incorrect';
+$lang['c13y_user_created'] = 'User "%s" created with "%s" like password';
+$lang['c13y_user_status_updated'] = 'Status of user "%s" updated';
+$lang['add new elements to caddie'] = 'add new elements to caddie';
+// --------- Starting below: New or revised $lang ---- from Butterfly
+$lang['no_display_thumbnail'] = 'No display';
+$lang['display_thumbnail_classic'] = 'Classic display';
+$lang['display_thumbnail_hoverbox'] = 'Hoverbox display';
+$lang['Thumbnails'] = 'Thumbnails';
+$lang['obligatory_user_mail_address'] = 'Mail address is obligatory for all users';
+$lang['Minimum privacy level'] = 'Minimum privacy level';
+$lang['Privacy level'] = 'Privacy level';
+$lang['Level 0'] = '---';
+$lang['Level 1'] = 'Contacts';
+$lang['Level 2'] = 'Friends';
+$lang['Level 4'] = 'Family';
+$lang['Level 8'] = 'Admins';
+$lang['c13y_maintenance'] = 'Reinitialize check integrity';
+$lang['Check all'] = 'Check all';
+$lang['Uncheck all'] = 'Uncheck all';
+$lang['c13y_check_auto'] = 'Check automatic corrections';
+$lang['c13y_submit_correction'] = 'Apply selected corrections';
+$lang['c13y_submit_ignore'] = 'Ignore selected anomalies';
+$lang['c13y_submit_refresh'] = 'Refresh';
+$lang['c13y_ignore_msg1'] = 'The anomaly will be ignored until next application version';
+$lang['c13y_ignore_msg2'] = 'Correction the anomaly will cancel the fact that it\'s ignored';
+$lang['c13y_anomaly_ignored_count'] = '%d anomaly has been ignored.';
+$lang['c13y_anomalies_ignored_count'] = '%d anomalies have been ignored.';
+$lang['plugins_need_update'] = 'Plugins which need upgrade';
+$lang['plugins_dontneed_update'] = 'Plugins up to date';
+$lang['plugins_cant_check'] = 'Plugin versions can\'t be checked';
+$lang['plugins_actual_version'] = 'Current<br>version';
+$lang['plugins_new_version'] = 'Available<br>version';
+$lang['plugins_auto_update'] = 'Automatic upgrade';
+$lang['plugins_auto_install'] = 'Automatic installation';
+$lang['plugins_download'] = 'Download file';
+$lang['plugins_tab_list'] = 'Plugin list';
+$lang['plugins_tab_update'] = 'Check for updates';
+$lang['plugins_tab_new'] = 'Other plugins';
+$lang['plugins_revisions'] = 'Last revisions';
+$lang['plugins_delete'] = 'Delete';
+$lang['plugins_confirm_delete'] = 'Are you sure you want to delete this plugin?';
+$lang['plugins_confirm_install'] = 'Are you sure you want to install this plugin?';
+$lang['plugins_confirm_upgrade'] = 'Are you sur to install this upgrade? You must verify if this version does not need uninstallation.';
+$lang['plugins_upgrade_ok'] = '%s has been successfully upgraded.';
+$lang['plugins_install_ok'] = 'Plugin has been successfully copied';
+$lang['plugins_install_need_activate'] = 'You might go to plugin list to install and activate it.';
+$lang['plugins_temp_path_error'] = 'Can\'t create temporary file.';
+$lang['plugins_dl_archive_error'] = 'Can\'t download archive.';
+$lang['plugins_archive_error'] = 'Can\'t read or extract archive.';
+$lang['plugins_extract_error'] = 'An error occured during extraction (%s).';
+$lang['plugins_check_chmod'] = 'Please check "plugins" folder and sub-folders permissions (CHMOD).';
+$lang['plugins_server_error'] = 'Can\'t connect to server.';
+$lang['Purge compiled templates'] = 'Purge compiled templates';
+$lang['Caddie is currently empty'] = 'Caddie is currently empty';
+$lang['conf_upload_title'] = 'Upload';
+$lang['Show upload link every time'] = 'Show upload link every time';
+$lang['User access level to upload'] = 'User access level to upload';
+$lang['ACCESS_0'] = 'Free access';
+$lang['ACCESS_1'] = 'Access to all';
+$lang['ACCESS_2'] = 'Access to subscribed';
+$lang['ACCESS_3'] = 'Access to administrators';
+$lang['ACCESS_4'] = 'Access to webmasters';
+$lang['ACCESS_5'] = 'No access';
+$lang['DEMO'] = 'Demo';
+$lang['HOME'] = 'Piwigo home';
+$lang['FORUM'] = 'Support';
+$lang['BUGS'] = 'Bugs';
+$lang['EXTENSIONS'] = 'Extensions';
+$lang['WIKI / DOC'] = 'Documentation';
+$lang['A new version of Piwigo is available.'] = 'A new version of Piwigo is available.';
+$lang['Piwigo Administration'] = 'Piwigo Administration';
+$lang['Piwigo version'] = 'Piwigo version';
+$lang['You are running the latest version of Piwigo.'] = 'You are running the latest version of Piwigo.';
+$lang['c13y_version_anomaly'] = 'The version of %s [%s] installed is not compatible with the version required [%s]';
+$lang['c13y_version_correction'] = 'You need to upgrade your system to take full advantage of the application else the application will not work correctly, or not at all';
+$lang['Deleted on'] = 'Deleted on';
+$lang['Last hit'] =  'Last hit';
+$lang['Hits'] = 'Hits';
+$lang['GD library is missing'] = 'GD library is missing';
+$lang['conf_extents'] = 'Templates';
+$lang['extend_for_templates'] = 'Extend for templates';
+$lang['Replacement of original templates'] =
+ 'Replacement of original templates by customized templates from template-extension subfolder';
+$lang['Replacers'] = 'Replacers (customized templates)';
+$lang['Original templates'] = 'Original templates';
+$lang['Optional URL keyword'] = 'Optional URL keyword';
+$lang['Templates recorded.'] = 'Templates configuration has been recorded.';
+$lang['Optimizations completed'] = 'All optimizations have been successfully completed.';
+$lang['Optimizations errors'] = 'Optimizations have been completed with some errors.';
+$lang['delete this comment'] = 'delete this comment';
+$lang['link_info_image'] = 'Modify information';
+$lang['edit category informations'] = 'edit category informations';
+$lang['nothing'] = 'nothing';
+$lang['overrides existing values with empty ones'] = 'overrides existing values with empty ones';
+$lang['manage image ranks'] = 'manage image ranks';
+$lang['Manage image ranks'] = 'Manage image ranks';
+$lang['Edit ranks'] = 'Edit ranks';
+$lang['No element in this category'] = 'No element in this category';
+$lang['Images manual order was saved'] = 'Images manual order was saved';
+$lang['ranks'] = 'ranks';
+$lang['Drag to re-order'] = 'Drag to re-order';
+$lang['Unable to retrieve server informations since allow_url_fopen is disabled.'] = 'Unable to retrieve server informations since allow_url_fopen is disabled.';
+$lang['Quick Local Synchronization'] = 'Quick Local Synchronization';
+$lang['No photo can be deleted'] = 'No photo can be deleted';
+$lang['Note: Only deletes photos added with pLoader'] = 'Note: Only deletes photos added with pLoader';
+$lang['Delete selected photos'] = 'Delete selected photos';
+$lang['%d photo was deleted'] = '%d photo was deleted';
+$lang['%d photos were deleted'] = '%d photos were deleted';
+$lang['Bound template'] = 'Bound template';
+$lang['Downloads'] = 'Downloads';
+$lang['Released on'] = 'Released on';
+$lang['Number of downloads'] = 'Number of downloads';
+?>
Index: /tags/2.0.2/language/en_UK/common.lang.php
===================================================================
--- /tags/2.0.2/language/en_UK/common.lang.php	(revision 3278)
+++ /tags/2.0.2/language/en_UK/common.lang.php	(revision 3278)
@@ -0,0 +1,368 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Langage informations
+$lang_info['language_name'] = 'English';
+$lang_info['country'] = 'Great Britain';
+$lang_info['direction'] = 'ltr';
+$lang_info['code'] = 'en';
+$lang_info['zero_plural'] = true;
+
+$lang['%.2f (rated %d times, standard deviation = %.2f)'] = '%.2f (rated %d times, standard deviation = %.2f)';
+$lang['%d Kb'] = '%d Kb';
+$lang['%d category updated'] = '%d category updated';
+$lang['%d categories updated'] = '%d categories updated';
+$lang['%d comment to validate'] = '%d comment to validate';
+$lang['%d comments to validate'] = '%d comments to validate';
+$lang['%d new comment'] = '%d new comment';
+$lang['%d new comments'] = '%d new comments';
+$lang['%d comment'] = '%d comment';
+$lang['%d comments'] = '%d comments';
+$lang['%d hit'] = '%d hit';
+$lang['%d hits'] = '%d hits';
+$lang['%d new element'] = '%d new image';
+$lang['%d new elements'] = '%d new images';
+$lang['%d new user'] = '%d new user';
+$lang['%d new users'] = '%d new users';
+$lang['%d waiting element'] = '%d waiting element';
+$lang['%d waiting elements'] = '%d waiting elements';
+$lang['About'] = 'About';
+$lang['All tags must match'] = 'All tags must match';
+$lang['All tags'] = 'All tags';
+$lang['Any tag'] = 'Any tag';
+$lang['At least one listed rule must be satisfied.'] = 'At least one listed rule must be satisfied.';
+$lang['At least one tag must match'] = 'At least one tag must match';
+$lang['Author'] = 'Author';
+$lang['Average rate'] = 'Average rate';
+$lang['Categories'] = 'Categories';
+$lang['Category'] = 'Category';
+$lang['Close this window'] = 'Close this window';
+$lang['Complete RSS feed'] = 'Complete RSS feed (images, comments)';
+$lang['Confirm Password'] = 'Confirm Password';
+$lang['Connection settings'] = 'Connection settings';
+$lang['Connection'] = 'Login';
+$lang['Contact webmaster'] = 'Contact webmaster';
+$lang['Create a new account'] = 'Create a new account';
+$lang['Created on'] = 'Created on';
+$lang['Creation date'] = 'Creation date';
+$lang['Current password is wrong'] = 'Current password is wrong';
+$lang['Dimensions'] = 'Dimensions';
+$lang['Display'] = 'Display';
+$lang['Each listed rule must be satisfied.'] = 'Each listed rule must be satisfied.';
+$lang['Email address is missing'] = 'Email address is missing';
+$lang['Email address'] = 'Email address';
+$lang['Enter your personnal informations'] = 'Enter your personnal informations';
+$lang['Error sending email'] = 'Error sending email';
+$lang['File name'] = 'File name';
+$lang['File'] = 'File';
+$lang['Filesize'] = 'Filesize';
+$lang['Filter and display'] = 'Filter and display';
+$lang['Filter'] = 'Filter';
+$lang['Forgot your password?'] = 'Forgot your password?';
+$lang['Go through the gallery as a visitor'] = 'Go through the gallery as a visitor';
+$lang['Help'] = 'Help';
+$lang['Identification'] = 'Identification';
+$lang['Image only RSS feed'] = 'Image only RSS feed';
+$lang['Keyword'] = 'Keyword';
+$lang['Links'] = 'Links';
+$lang['Mail address'] = 'Mail address';
+$lang['N/A'] = 'N/A';
+$lang['New on %s'] = 'New on %s';
+$lang['New password confirmation does not correspond'] = 'New password confirmation does not correspond';
+$lang['New password sent by email'] = 'New password sent by email';
+$lang['No email address'] = 'No email address';
+$lang['No user matches this email address'] = 'No classic user matches this email address';
+$lang['Notification'] = 'Notification';
+$lang['Number of items'] = 'Number of items';
+$lang['Original dimensions'] = 'Original dimensions';
+$lang['Password forgotten'] = 'Password forgotten';
+$lang['Password'] = 'Password';
+$lang['Post date'] = 'Post date';
+$lang['Posted on'] = 'Posted on';
+$lang['Profile'] = 'Profile';
+$lang['Quick connect'] = 'Quick connect';
+$lang['RSS feed'] = 'RSS feed';
+$lang['Rate'] = 'Rate';
+$lang['Register'] = 'Register';
+$lang['Registration'] = 'Registration';
+$lang['Related tags'] = 'Related tags';
+$lang['Reset'] = 'Reset';
+$lang['Retrieve password'] = 'Retrieve password';
+$lang['Search rules'] = 'Search rules';
+$lang['Search tags'] = 'Search tags';
+$lang['Search'] = 'Search';
+$lang['See available tags'] = 'See available tags';
+$lang['Send new password'] = 'Send new password';
+$lang['Since'] = 'Since';
+$lang['Sort by'] = 'Sort by';
+$lang['Sort order'] = 'Sort order';
+$lang['Tag'] = 'Tag';
+$lang['Tags'] = 'Tags';
+$lang['The RSS notification feed provides notification on news from this website : new pictures, updated categories, new comments. Use a RSS feed reader.'] = 'The RSS notification feed provides notification on news from this website : new pictures, updated categories, new comments. Use a RSS feed reader.';
+$lang['Unknown feed identifier'] = 'Unknown feed identifier';
+$lang['User comments'] = 'User comments';
+$lang['Username'] = 'Username';
+$lang['Visits'] = 'Visits';
+$lang['Webmaster'] = 'Webmaster';
+$lang['Week %d'] = 'Week %d';
+$lang['about_page_title'] = 'About Piwigo';
+$lang['access_forbiden'] = 'You are not authorized to access the requested page';
+$lang['add to caddie'] = 'add to caddie';
+$lang['add_favorites_hint'] = 'add this image to your favorites';
+$lang['admin'] = 'Administration';
+$lang['adviser_mode_enabled'] = 'Adviser mode enabled';
+$lang['all'] = 'all';
+$lang['ascending'] = 'ascending';
+$lang['author(s) : %s'] = 'author(s) : %s';
+$lang['auto_expand'] = 'Expand all categories';
+$lang['became available after %s (%s)'] = 'posted after %s (%s)';
+$lang['became available before %s (%s)'] = 'posted before %s (%s)';
+$lang['became available between %s (%s) and %s (%s)'] = 'posted between %s (%s) and %s (%s)';
+$lang['became available on %s'] = 'posted on %s';
+$lang['best_rated_cat'] = 'Best rated';
+$lang['best_rated_cat_hint'] = 'displays best rated items';
+$lang['caddie'] = 'caddie';
+$lang['calendar'] = 'Calendar';
+$lang['calendar_any'] = 'All';
+$lang['calendar_hint'] = 'displays each day with pictures, month per month';
+$lang['calendar_picture_hint'] = 'displays pictures added on ';
+$lang['calendar_view'] = 'View';
+$lang['chronology_monthly_calendar'] = 'Monthly calendar';
+$lang['chronology_monthly_list'] = 'Monthly list';
+$lang['chronology_weekly_list'] = 'Weekly list';
+$lang['click_to_redirect'] = 'Click here if your browser does not automatically forward you';
+$lang['comment date'] = 'comment date';
+$lang['comment'] = 'Comment';
+$lang['comment_added'] = 'Your comment has been registered';
+$lang['comment_anti-flood'] = 'Anti-flood system : please wait for a moment before trying to post another comment';
+$lang['comment_not_added'] = 'Your comment has NOT been registered because it did not pass the validation rules';
+$lang['comment_to_validate'] = 'An administrator must authorize your comment before it is visible.';
+$lang['comment_user_exists'] = 'This login is already used by another user';
+$lang['comments'] = 'Comments';
+$lang['comments_add'] = 'Add a comment';
+$lang['created after %s (%s)'] = 'created after %s (%s)';
+$lang['created before %s (%s)'] = 'created before %s (%s)';
+$lang['created between %s (%s) and %s (%s)'] = 'created between %s (%s) and %s (%s)';
+$lang['created on %s'] = 'created on %s';
+$lang['customize'] = 'Customize';
+$lang['customize_page_title'] = 'Your Gallery Customization ';
+$lang['day'][0] = 'Sunday';
+$lang['day'][1] = 'Monday';
+$lang['day'][2] = 'Tuesday';
+$lang['day'][3] = 'Wednesday';
+$lang['day'][4] = 'Thursday';
+$lang['day'][5] = 'Friday';
+$lang['day'][6] = 'Saturday';
+$lang['default_sort'] = 'Default';
+$lang['del_favorites_hint'] = 'delete this image from your favorites';
+$lang['delete'] = 'Delete';
+$lang['descending'] = 'descending';
+$lang['download'] = 'download';
+$lang['download_hint'] = 'download this file';
+$lang['edit'] = 'edit';
+$lang['err_date'] = 'wrong date';
+$lang['excluded'] = 'excluded';
+$lang['favorite_cat'] = 'My favorites';
+$lang['favorite_cat_hint'] = 'displays my favorites pictures';
+$lang['favorites'] = 'Favorites';
+$lang['first_page'] = 'First';
+$lang['gallery_locked_message'] = 'The gallery is locked for maintenance. Please, come back later.';
+$lang['generation_time'] = 'Page generated in';
+$lang['guest'] = 'guest';
+$lang['hello'] = 'Hello';
+$lang['hint_admin'] = 'available for administrators only';
+$lang['hint_category'] = 'shows images at the root of this category';
+$lang['hint_comments'] = 'See last users comments';
+$lang['hint_customize'] = 'customize the appareance of the gallery';
+$lang['hint_search'] = 'search';
+$lang['home'] = 'Home';
+$lang['identification'] = 'Identification';
+$lang['images_available_cpl'] = 'in this category';
+$lang['images_available_cat'] = 'in %d sub-category';
+$lang['images_available_cats'] = 'in %d sub-categories';
+$lang['included'] = 'included';
+$lang['invalid_pwd'] = 'Invalid password!';
+$lang['language']='Language';
+$lang['last %d days'] = 'last %d days';
+$lang['last_page'] = 'Last';
+$lang['logout'] = 'Logout';
+$lang['mail_address'] = 'E-mail address';
+$lang['mandatory'] = 'obligatory';
+$lang['maxheight'] = 'Maximum height of the pictures';
+$lang['maxheight_error'] = 'Maximum height must be a number superior to 50';
+$lang['maxwidth'] = 'Maximum width of the pictures';
+$lang['maxwidth_error'] = 'Maximum width must be a number superior to 50';
+$lang['mode_created_hint'] = 'displays a calendar by creation date';
+$lang['mode_flat_hint'] = 'displays all elements in all sub-categories';
+$lang['mode_normal_hint'] = 'return to normal view mode';
+$lang['mode_posted_hint'] = 'displays a calendar by posted date';
+$lang['month'][10] = 'October';
+$lang['month'][11] = 'November';
+$lang['month'][12] = 'December';
+$lang['month'][1] = 'January';
+$lang['month'][2] = 'February';
+$lang['month'][3] = 'March';
+$lang['month'][4] = 'April';
+$lang['month'][5] = 'May';
+$lang['month'][6] = 'June';
+$lang['month'][7] = 'July';
+$lang['month'][8] = 'August';
+$lang['month'][9] = 'September';
+$lang['most_visited_cat'] = 'Most visited';
+$lang['most_visited_cat_hint'] = 'displays most visited pictures';
+$lang['nb_image_line_error'] = 'The number of images per row must be a not null scalar';
+$lang['nb_image_per_row'] = 'Number of images per row';
+$lang['nb_line_page_error'] = 'The number of rows per page must be a not null scalar';
+$lang['nb_row_per_page'] = 'Number of rows per page';
+$lang['nbm_unknown_identifier'] = 'Unknown identifier';
+$lang['new_password'] = 'New password';
+$lang['new_rate'] = 'Rate this picture';
+$lang['next_page'] = 'Next';
+$lang['no_category'] = 'Home';
+$lang['no_rate'] = 'no rate';
+$lang['note_filter_day'] = 'Elements posted within the last %d day.';
+$lang['note_filter_days'] = 'Elements posted within the last %d days.';
+$lang['password updated'] = 'password updated';
+$lang['periods_error'] = 'Recent period must be a positive integer value';
+/* DEPRECATED USED IN comments.php FOR image_id ? */ $lang['picture'] = 'picture';
+$lang['picture_high'] = 'Click on the picture to see it in high definition';
+$lang['picture_show_metadata'] = 'Show file metadata';
+$lang['powered_by'] = 'Powered by';
+$lang['preferences'] = 'Preferences';
+$lang['previous_page'] = 'Previous';
+$lang['random_cat'] = 'Random pictures';
+$lang['random_cat_hint'] = 'displays a set of random pictures';
+$lang['recent_cats_cat'] = 'Recent categories';
+$lang['recent_cats_cat_hint'] = 'displays recently updated categories';
+$lang['recent_period'] = 'Recent period';
+$lang['recent_pics_cat'] = 'Recent pictures';
+$lang['recent_pics_cat_hint'] = 'displays most recent pictures';
+$lang['redirect_msg'] = 'Redirection...';
+$lang['reg_err_login1'] = 'Please, enter a login';
+$lang['reg_err_login2'] = 'login mustn\'t end with a space character';
+$lang['reg_err_login3'] = 'login mustn\'t start with a space character';
+$lang['reg_err_login5'] = 'this login is already used';
+$lang['reg_err_mail_address'] = 'mail address must be like xxx@yyy.eee (example : jack@altern.org)';
+$lang['reg_err_pass'] = 'please enter your password again';
+$lang['remember_me'] = 'Auto login';
+$lang['remove this tag'] = 'remove this tag from the list';
+$lang['representative'] = 'representative';
+$lang['return to homepage'] = 'return to homepage';
+$lang['search_author'] = 'Search for Author';
+$lang['search_categories'] = 'Search in Categories';
+$lang['search_date'] = 'Search by Date';
+$lang['search_date_from'] = 'Date';
+$lang['search_date_to'] = 'End-Date';
+$lang['search_date_type'] = 'Kind of date';
+$lang['search_keywords'] = 'Search for words';
+$lang['search_mode_and'] = 'Search for all terms ';
+$lang['search_mode_or'] = 'Search for any terms';
+$lang['search_one_clause_at_least'] = 'Empty query. No criteria has been entered.';
+$lang['search_options'] = 'Search Options';
+$lang['search_result'] = 'Search results';
+$lang['search_subcats_included'] = 'Search in subcategories';
+$lang['search_title'] = 'Search';
+$lang['searched words : %s'] = 'searched words : %s';
+$lang['send_mail'] = 'Contact';
+$lang['set as category representative'] = 'set as category representative';
+$lang['show_nb_comments'] = 'Show number of comments';
+$lang['show_nb_hits'] = 'Show number of hits';
+$lang['slideshow'] = 'slideshow';
+$lang['slideshow_stop'] = 'stop the slideshow';
+$lang['special_categories'] = 'Specials';
+$lang['sql_queries_in'] = 'SQL queries in';
+$lang['start_filter_hint'] = 'displays only recently posted images';
+$lang['stop_filter_hint'] = 'return to the display of all images';
+$lang['the beginning'] = 'the beginning';
+$lang['theme'] = 'Interface theme';
+$lang['thumbnails'] = 'Thumbnails';
+$lang['title_menu'] = 'Menu';
+$lang['title_send_mail'] = 'A comment on your site';
+$lang['today'] = 'today';
+$lang['update_rate'] = 'Update your rating';
+$lang['update_wrong_dirname'] = 'wrong filename';
+$lang['upload_advise_filesize'] = 'the filesize of the picture must not exceed : ';
+$lang['upload_advise_filetype'] = 'the picture must be to the fileformat jpg, gif or png';
+$lang['upload_advise_height'] = 'the height of the picture must not exceed : ';
+$lang['upload_advise_thumbnail'] = 'Optional, but recommended : choose a thumbnail to associate to ';
+$lang['upload_advise_width'] = 'the width of the picture must not exceed : ';
+$lang['upload_author'] = 'Author';
+$lang['upload_cannot_upload'] = 'can\'t upload the picture on the server';
+$lang['upload_err_username'] = 'the username must be given';
+$lang['upload_file_exists'] = 'A picture\'s name already used';
+$lang['upload_filenotfound'] = 'You must choose a picture fileformat for the image';
+$lang['upload_forbidden'] = 'You can\'t upload pictures in this category';
+$lang['upload_name'] = 'Name of the picture';
+$lang['upload_picture'] = 'Upload a picture';
+$lang['upload_successful'] = 'Picture uploaded with success, an administrator will validate it as soon as possible';
+$lang['upload_title'] = 'Upload a picture';
+$lang['useful when password forgotten'] = 'useful when password forgotten';
+$lang['qsearch'] = 'Quick search';
+$lang['Connected user: %s'] = 'Connected user: %s';
+$lang['IP: %s'] = 'IP: %s';
+$lang['Browser: %s'] = 'Browser: %s';
+$lang['Author: %s'] = 'Author: %s';
+$lang['Comment: %s'] = 'Comment: %s';
+$lang['Delete: %s'] = 'Delete: %s';
+$lang['Validate: %s'] = 'Validate: %s';
+$lang['Comment by %s'] = 'Comment by %s';
+$lang['User: %s'] = 'User: %s';
+$lang['Email: %s'] = 'Email: %s';
+$lang['Admin: %s'] = 'Admin: %s';
+$lang['Registration of %s'] = 'Registration of %s';
+$lang['Category: %s'] = 'Category: %s';
+$lang['Picture name: %s'] = 'Picture name: %s';
+$lang['Creation date: %s'] = 'Creation date: %s';
+$lang['Waiting page: %s'] = 'Waiting page: %s';
+$lang['Picture uploaded by %s'] = 'Picture uploaded by %s';
+// --------- Starting below: New or revised $lang ---- from version 1.7.1
+$lang['guest_must_be_guest'] = 'Bad status for user "guest", using default status. Please notify the webmaster.';
+// --------- Starting below: New or revised $lang ---- from Butterfly (2.0)
+$lang['Administrator, webmaster and special user cannot use this method'] = 'Administrator, webmaster and special user cannot use this method';
+$lang['reg_err_mail_address_dbl'] = 'a user use already this mail address';
+$lang['Category results for'] = 'Category results for';
+$lang['Tag results for'] = 'Tag results for';
+$lang['from %s to %s'] = 'from %s to %s';
+$lang['start_play'] = 'Play of slideshow';
+$lang['stop_play'] = 'Pause of slideshow';
+$lang['start_repeat'] = 'Repeat the slideshow';
+$lang['stop_repeat'] = 'Not repeat the slideshow';
+$lang['inc_period'] = 'Reduce diaporama speed';
+$lang['dec_period'] = 'Accelerate diaporama speed';
+$lang['Submit'] = 'Submit';
+$lang['Yes'] = 'Yes';
+$lang['No'] = 'No';
+$lang['%d element']='%d image';
+$lang['%d elements']='%d images';
+$lang['%d element are also linked to current tags'] = '%d image is also linked to current tags';
+$lang['%d elements are also linked to current tags'] = '%d images are also linked to current tags';
+$lang['See elements linked to this tag only'] = 'See images linked to this tag only';
+$lang['elements posted during the last %d days'] = 'images posted during the last %d days';
+$lang['Choose an image'] = 'Choose an image';
+$lang['Piwigo Help'] = 'Piwigo Help';
+$lang['Rank'] = 'Rank';
+$lang['group by letters'] = 'group by letters';
+$lang['letters'] = 'letters';
+$lang['show tag cloud'] = 'show tag cloud';
+$lang['cloud'] = 'cloud';
+?>
Index: /tags/2.0.2/language/en_UK/help.html
===================================================================
--- /tags/2.0.2/language/en_UK/help.html	(revision 3278)
+++ /tags/2.0.2/language/en_UK/help.html	(revision 3278)
@@ -0,0 +1,310 @@
+<div class="instructions">
+<h2>Help</h2>
+
+<div id="instructionPLoader" class="instructionBlock">
+  <div
+    id="pLoader_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('pLoader_header', 'pLoader_content')"
+  ><span>
+    Add photos, the pLoader way
+  </span></div>
+  <div
+    id="pLoader_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+    <p><a href="http://piwigo.org/ext/extension_view.php?eid=270">pLoader for Windows</a> or <a href="http://piwigo.org/ext/extension_view.php?eid=269">pLoader for Linux</a> : description, download and details about new revisions.</p>
+    <ol>
+      <li>Create a directory "upload" next to directory "galleries" in your Piwigo installation, with write access.</li>
+      <li>Install pLoader on your computer, start it and fill the connection settings : your gallery URL, your username and password.</li>
+      <li>Drag'n drop photos from your directory browser into pLoader photo selection.</li>
+      <li>Create a category and select it.</li>
+      <li>Select some photos.</li>
+      <li>Click on the green arrow to transfer photos in your gallery</li>
+    </ol>
+Congratulations! You have successfuly created the first category of your photo gallery.
+  </div> <!-- pLoader_content -->
+</div> <!-- instructionPLoader -->
+
+<div id="instructionFTP" class="instructionBlock">
+  <div
+    id="FTP_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('FTP_header', 'FTP_content')"
+  ><span>
+    Add photos, the FTP way
+  </span></div>
+  <div
+    id="FTP_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+
+<h3>Quick Start</h3>
+
+<ol>
+  <li>Create a directory on your computer.</li>  
+
+  <li>Copy some photos inside this directory, resize them for web display. <em>Warning</em>: the name of directories and files must contain only letters, figures, "-", "_" or ".". No blank space, no accentuated characters.</li>
+
+  <li>With a FTP client, copy your directory in the "galleries" directory of your Piwigo installation.</li>
+
+  <li>Logon your gallery and go to <span class="pwgScreen">Administration &raquo; Pictures &raquo; Thumbnails</span> to create missing thumbnails.</li>
+
+  <li>Go to <span class="pwgScreen">Administration</span> and click on the big Synchronization button.</li>
+</ol>
+
+Congratulations! You have successfuly created the first category of your photo gallery.
+
+<h3>Directories and files organization</h3>
+<ul>
+
+  <li>
+
+    <p>Category directories are in the Piwigo directory
+    "galleries". Here follows the directory tree of a very small gallery (but
+    using many features) :</p>
+
+    <pre>
+.
+|-- admin
+|-- doc
+|-- galleries
+|   |-- category-1
+|   |   |-- category-1.1
+|   |   |   |-- category-1.1.1
+|   |   |   |   |-- category-1.1.1.1
+|   |   |   |   |   |-- pwg_high
+|   |   |   |   |   |   +-- wedding.jpg
+|   |   |   |   |   |-- thumbnail
+|   |   |   |   |   |   +-- TN-wedding.jpg
+|   |   |   |   |   +-- wedding.jpg
+|   |   |   |   +-- category-1.1.1.2
+|   |   |   +-- category-1.1.2
+|   |   |-- category-1.2
+|   |   |   |-- pookie.jpg
+|   |   |   +-- thumbnail
+|   |   |       +-- TN-pookie.jpg
+|   |   +-- category-1.3
+|   +-- category-2
+|       |-- piglet.gif
+|       |-- pwg_representative
+|       |   +-- video.jpg
+|       |-- thumbnail
+|       |   +-- TN-piglet.jpg
+|       +-- video.avi
+|-- include
+|-- install
+|-- language
+|-- template
++-- tool</pre>
+
+  </li>
+  
+  <li>Each directory under "galleries" produces a category. There is no limit on deepness.</li>
+
+  <li>Basically, an element is represented by a file. A file can be a
+  Piwigo element if its extenstion is among <code>file_ext</code>
+  configuration parameter possibilities (see <span
+  class="filename">include/config_default.inc.php</span> file). A file can
+  be a picture if its extension is among <code>picture_ext</code>
+  configuration parameter possibilities.</li>
+
+  <li>Picture elements must have an associated thumbnail (see section below
+  about thumbnails)</li>
+
+  <li>Picture elements can have a high quality file associated. As for
+  wedding.jpg in the example above. No prefix on the high quality picture.</li>
+
+  <li>Non picture elements (video, sounds, file texts, what you want...) are
+  by default represented by an icon corresponding to the filename
+  extension. Optionaly, you can associate a thumbnail and a representative
+  file (see video.avi in the example above).</li>
+
+  <li><em>Warning</em>: the name of directories and files must contain only letters, figures, "-", "_" or ".". No blank space, no accentuated characters.</li>
+
+  <li>Once files, thumbnails and representatives are correctly placed in the
+  directories, go to : <span class="pwgScreen">Administration &raquo; Categories &raquo;
+  Synchronize</span></li>
+
+</ul>
+
+<h3>Thumbnails</h3>
+<ul>
+
+  <li>Each photo must have its thumbnail.</li>
+
+  <li>Thumbnails are stored in the sub-directory "thumbnail" of the category
+  directory. The thumbnail has the same filename as the corresponding photo, with <em>TN-</em> as prefix.</li>
+
+  <li><em>Advise</em>: use an external module for thumbnails creation.</li>
+
+  <li>Even if it is not recommended (image quality, web server resource load), you can use <span
+  class="pwgScreen">Administration &raquo; Pictures &raquo; Thumbnails</span> page to create thumbnails.</li>
+
+  <li>Give write access on all category directories.</li>
+
+</ul>
+
+  </div> <!-- FTP_content -->
+</div> <!-- instructionFTP -->
+
+<div id="instructionPermissions" class="instructionBlock">
+  <div
+    id="permissions_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('permissions_header', 'permissions_content')"
+  ><span>
+    Permissions
+  </span></div>
+  <div
+    id="permissions_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+<ul>
+
+  <li>You can forbid access to categories. Switch the category access type to "private" if you want to manage permissions.</li>
+
+  <li>You can set a category to private by editing a single category (<span
+  class="pwgScreen">Administration &raquo; Categories &raquo; Manage &raquo; edit</span>) or by
+  setting options to your whole category tree (<span
+  class="pwgScreen">Administration &raquo; Categories &raquo; Properties &raquo; Public / Private</span>).</li>
+
+  <li>
+
+    <p>Once the category is private, you can manage permissions for groups
+    and users with 3 screens:</p>
+
+    <ul>
+
+      <li><span class="pwgScreen">Administration &raquo; Identification &raquo; Users &raquo;
+      permissions action</span> (one link per user)</li>
+
+      <li><span class="pwgScreen">Administration &raquo; Identification &raquo; Groups &raquo;
+      permissions action</span> (one link per group)</li>
+
+      <li><span class="pwgScreen">Administration &raquo; Categories &raquo; Manage &raquo; edit
+      category permissions action</span> (one link per category)</li>
+
+    </ul>
+
+  </li>
+
+</ul>
+  </div> <!-- permissions_content --> 
+</div> <!-- instructionPermissions -->
+
+<div id="instructionGroups" class="instructionBlock">
+  <div
+    id="groups_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('groups_header', 'groups_content')"
+  ><span>
+    Groups
+  </span></div>
+  <div
+    id="groups_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+<ul>
+
+  <li>Groups is a convenient way to set permissions for a list of users.</li>
+
+  <li>Create groups in <span class="pwgScreen">Administration &raquo;
+  Identification &raquo; Groups</span> and associate users to this group in <span
+  class="pwgScreen">Administration &raquo; Identication &raquo; Users</span>.</li>
+
+  <li>A user can belong to several groups. Authorization is stronger
+  than forbiddance : if user "jack" belongs to groups "family" and
+  "friends", and that only group "family" can see category "Christmas 2003" category then
+  "jack" will be able to see "Christmas 2003".</li>
+
+</ul>
+  </div> <!-- groups_content --> 
+</div> <!-- instructionGroups -->
+
+<div id="instructionUpload" class="instructionBlock">
+  <div
+    id="upload_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('upload_header', 'upload_content')"
+  ><span>
+    Upload by users
+  </span></div>
+  <div
+    id="upload_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+<p>Users can upload their photos too.</p>
+
+<ol>
+
+  <li>Authorize upload on any physical categories (<span
+  class="pwgScreen">Administration &raquo; Categories &raquo; Manage &raquo; edit</span> or <span
+  class="pwgScreen">Administration &raquo; Categories &raquo; Properties &raquo; Upload</span>). Virtual categories can't receive any upload.</li>
+
+  <li>Give write access on corresponding directories.</li>
+
+</ol>
+
+<p>Photos uploaded by users are not directly visible on the website. An administrator
+must validate uploaded photos in <span class="pwgScreen">Administration &raquo; Pictures &raquo; Waiting</span>.</p>
+  </div> <!-- upload_content --> 
+</div> <!-- instructionUpload -->
+
+<div id="instructionCategoryLinks" class="instructionBlock">
+  <div
+    id="categoryLinks_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('categoryLinks_header', 'categoryLinks_content')"
+  ><span>
+    Links between photos and categories, virtual categories
+  </span></div>
+  <div
+    id="categoryLinks_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+<ul>
+
+  <li>Photos are displayed in the category corresponding to the file directory.</li>
+
+  <li>You can also display a picture in several categories, without duplicating the file on your web server. Associate the photo to any category from the photo editing screen (that any administrator can reach from the photo page on the gallery side).</li>
+
+  <li>Virtual categories are based on this concept: they have no corresponding directory. Create virtual categories from <span class="pwgScreen">Administration &raquo; Categories &raquo; Manage</span>.</li>
+
+</ul>
+  </div> <!-- categoryLinks_content --> 
+</div> <!-- instructionCategoryLinks -->
+
+<div id="instructionMisc" class="instructionBlock">
+  <div
+    id="misc_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('misc_header', 'misc_content')"
+  ><span>
+    Miscellanous informations
+  </span></div>
+  <div
+    id="misc_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+<ul>
+
+  <li>As soon as you created your gallery, modify default display properties
+  in <span class="pwgScreen">Administration &raquo; Configuration &raquo;
+  Default</span>. Every new registered user will use these default configuration settings.</li>
+
+  <li>If you have any question, Piwigo community will welcome you on <a
+  href="http://piwigo.org/forum">its forum</a>.</li>
+
+</ul>
+  </div> <!-- misc_content --> 
+</div> <!-- instructionMisc -->
+
+</div>
Index: /tags/2.0.2/language/en_UK/help/advanced_feature.html
===================================================================
--- /tags/2.0.2/language/en_UK/help/advanced_feature.html	(revision 3278)
+++ /tags/2.0.2/language/en_UK/help/advanced_feature.html	(revision 3278)
@@ -0,0 +1,16 @@
+<h2>Advanced features</h2>
+
+<p>List special functionnalties for expert PWG administrator:</p>
+
+<ul>
+
+  <li>
+    <strong>Not linked elements:</strong>
+    Display images which are not associated to any virtual category.
+  </li>
+  <li>
+    <strong>Files with same name in more than one physical category:</strong>
+    Display images or any files which are found with the same filename in some categories.
+  </li>
+
+</ul>
Index: /tags/2.0.2/language/en_UK/help/cat_modify.html
===================================================================
--- /tags/2.0.2/language/en_UK/help/cat_modify.html	(revision 3278)
+++ /tags/2.0.2/language/en_UK/help/cat_modify.html	(revision 3278)
@@ -0,0 +1,141 @@
+<h2>Edit a category</h2>
+
+<h3>Informations</h3>
+
+<ul>
+
+  <li><strong>name</strong>: rename the category (a virtual rename in case 
+  of physical category).</li>
+
+  <li><strong>description</strong>: give a general idea of the content,
+  this text will be display under the thumbnail page.</li>
+
+</ul>
+
+<h3>Move</h3>
+
+<p>If the category is virtual, you can move it. Moving a category means
+changing its parent category.</p>
+
+<h3>Options</h3>
+
+<ul>
+
+  <li><strong>Access type</strong>: Permission management. If you make a
+  category private, all its child categories becomes private. If you make a
+  category public, all its parent categories becomes public.</li>
+
+  <li><strong>Lock</strong>: The category and its sub-categories will
+  temporary been disabled for maintenance.</li>
+
+  <li><strong>Comments</strong>: Authorize users to comment elements of this
+  category.</li>
+
+  <li><strong>Authorize upload</strong>: Authorize users to upload
+  files. This option is available only if category is physical (not
+  virtual).</li>
+
+</ul>
+
+<p>You can also manage these options with "Properties"
+management screen (screens <span class="pwgScreen">Upload</span>, <span
+class="pwgScreen">Comments</span>, <span class="pwgScreen">Lock</span>,
+<span class="pwgScreen">Public/Private</span>, <span
+class="pwgScreen">Representative</span> available from <span
+class="pwgScreen">Administration, Categories, Properties</span>).</p>
+
+<h3>Sort order</h3>
+
+<p>Choose if the default sort order will be used.</p>
+
+<p>Indicate if this sort order will be applied to subcategories.</p>
+
+<p>Select specific sort by columns to use with this category.</p>
+<ul>
+<li><strong>Creation date</strong>: Picture creation date</li>
+<li><strong>Post date</strong>: Synchronization date</li>
+<li><strong>Average rate (*)</strong>: Average rate could be changed by the visitor</li>
+<li><strong>Most visited (*)</strong>: The current visit change the most visited order</li>
+<li><strong>File name</strong>: Given name in informations field</li>
+<li><strong>Id</strong>: Internal Id (recent categories have an higher id than previous ones.</li>
+
+</ul>
+<p><strong>(*)</strong>Take care and test it for your self since it can give unpredictable results.</p>
+
+
+<h3>Representant</h3>
+
+<p>The representant of the category is the thumbnail displayed to represent
+the category on main page (<span class="pwgScreen">category.php</span>) when
+a category contains only sub-categories (just as the root category).</p>
+
+<p>There are 4 ways to set the representative picture of a category :</p>
+
+<ul>
+
+  <li><span class="pwgScreen">Picture page</span>: in the action buttons bar,
+  one of them let you set the displayed picture as representative for the
+  displayed category. This button is available only for administrators.</li>
+
+  <li><span class="pwgScreen">Modify informations about a picture</span> in
+  administration. This screen can be reach from <span
+  class="pwgScreen">picture.php</span> or <span class="pwgScreen">Batch
+  management</span> in <em>unit mode</em>. See the help of this screen for
+  details.</li>
+
+  <li><span class="pwgScreen">Administration, Categories, Properties,
+  Representative</span>. See the help of this screen for details.</li>
+
+  <li><span class="pwgScreen">Edit a category</span> (this screen).</li>
+
+</ul>
+
+<p>The representation depends on configuration parameter
+<code>allow_random_representative</code> (see <span
+class="filename">include/config_default.inc.php</span>).</p>
+
+<p>In default mode (<code>allow_random_representative</code> set to false)
+each category containing at least one element is represented by a fixed
+element. Once set (at category creation), the representative changes only
+when an administrator ask for it. If the representant is not appropriate,
+you can ask to <strong>Find a new representant by random</strong>.</p>
+
+<p>If configuration parameter <code>allow_random_representative</code> is
+set to true, a category containing elements can have no fixed
+representant. Just use <strong>Delete representant</strong> button.</p>
+
+<p>If the category contains no element (but only sub-categories) it can be
+represented by any element thanks to screen <span class="pwgScreen">Modify
+informations about a picture</span>. The only option on the current screen
+is to <strong>Delete representant</strong> button, after using this button,
+no representant option to set anymore.</p>
+
+<h3>Link all category elements to a new category</h3>
+
+<ul>
+
+<li><strong>Virtual category name</strong>: New category name to be created, 
+all pictures of the current category will be linked to the new one.</li>
+
+<li><strong>Parent category</strong>: Where the new category will be, 
+leave empty to create it from home.</li>
+
+</ul>
+
+<h3>Link all category elements to some existing categories</h3>
+
+<ul>
+
+<li><strong>Categories</strong>: Choose the destination category.</li>
+
+</ul>
+
+<h3>Send an information email to group members</h3>
+
+<ul>
+
+<li><strong>Group</strong>: addressees group</li>
+
+<li><strong>Mail content</strong>: Free text to be sent to them.</li>
+
+</ul>  
Index: /tags/2.0.2/language/en_UK/help/cat_move.html
===================================================================
--- /tags/2.0.2/language/en_UK/help/cat_move.html	(revision 3278)
+++ /tags/2.0.2/language/en_UK/help/cat_move.html	(revision 3278)
@@ -0,0 +1,14 @@
+<h2>Moving virtual categories</h2>
+
+<p>Only virtual categories can have a new parent category.</p>
+
+<h3>Virtual categories to move</h3>
+
+<p>Select any virtual categories you want to move. 
+If the list is empty, that mean you didn't create one.</p>
+
+<h3>New parent category</h3>
+
+<p>Select the new parent (virtual or physical). 
+If you don't, virtual selected categories will be moved to the root.
+You can't move a category to itself or to one of its child.</p>
Index: /tags/2.0.2/language/en_UK/help/cat_options.html
===================================================================
--- /tags/2.0.2/language/en_UK/help/cat_options.html	(revision 3278)
+++ /tags/2.0.2/language/en_UK/help/cat_options.html	(revision 3278)
@@ -0,0 +1,36 @@
+<h2>Category options</h2>
+
+<p>This screen lets the administrator manage categories option for many
+categories at once.</p>
+
+<dl>
+
+  <dt>Upload</dt>
+  <dd>Make categories uploadable for gallery visitors. Only non virtual and
+  non remote categories are shown.</dd>
+
+  <dt>Comments</dt>
+  <dd>Authorize users to add comments on selected categories.
+Selects the categories which are commentable. 
+An image is commentable if it belongs to at least one category that is commentable.</dd>
+
+  <dt>Lock</dt>
+  <dd>Selected categories will temporary been disabled for maintenance. If
+  you lock a category, all its child categories become locked. If you unlock
+  a category, all its parent categories become unlocked.</dd>
+
+  <dt>Public / private</dt>
+  <dd>Manage authorizations for selected categories. Selected categories are
+  private : you will need to authorize users and/or groups to access to
+  them. If you make a category private, all its child categories becomes
+  private. If you make a category public, all its parent categories becomes
+  public</dd>
+
+  <dt>Representative</dt>
+  <dd>This option can be managed only if you set configuration parameter
+  <code>allow_random_representative</code> (see <span
+  class="filename">include/config_defaults.inc.php</span>) to
+  <em>true</em>. Each category can be randomly represented or singly
+  represented (by a unique picture).</dd>
+
+</dl>
Index: /tags/2.0.2/language/en_UK/help/cat_perm.html
===================================================================
--- /tags/2.0.2/language/en_UK/help/cat_perm.html	(revision 3278)
+++ /tags/2.0.2/language/en_UK/help/cat_perm.html	(revision 3278)
@@ -0,0 +1,15 @@
+<h2>Manage permissions for a category</h2>
+
+<p>This screen is available only for a private category. Here you can select
+users and groups authorized for this category.</p>
+
+<h3>Groups</h3>
+
+<p>You can deny or grant groups for the current category. By modifying
+groups authorizations, you'll probably modify the list of users granted to
+the category thanks to group belongings.</p>
+
+<h3>Users</h3>
+
+<p>You can deny or grant individual users. Users granted thanks to group
+belongings can be denied or granted specifically.</p>
Index: /tags/2.0.2/language/en_UK/help/configuration.html
===================================================================
--- /tags/2.0.2/language/en_UK/help/configuration.html	(revision 3278)
+++ /tags/2.0.2/language/en_UK/help/configuration.html	(revision 3278)
@@ -0,0 +1,136 @@
+<h2>Configuration</h2>
+
+<p>This screen let the administrator do basic configuration. Indeed, this
+screen only shows simple configuration parameters that should be enough for
+the vast majority of administrators. If you want to see other numerous (and
+advanced) configuration parameters, read file <span
+class="filename">include/config_default.inc.php</span>.</p>
+
+<p>This screen is divided in several sections, regrouping configuration
+parameters by theme.</p>
+
+
+<h3>Main</h3>
+<ul>
+  <li><strong>Gallery title</strong>: used in RSS feed and notifications by
+email.</li>
+
+  <li><strong>Page banner</strong>: displayed on top of each public
+page.</li>
+
+  <li><strong>Gallery URL</strong>: used for the RSS feed.</li>
+
+  <li><strong>Lock gallery</strong>: Lock the entire gallery for
+  maintenance. Only administrator users will be able to reach the
+  gallery.</li>
+
+  <li><strong>Rating</strong>: Picture rating feature is enabled.</li>
+
+  <li><strong>Rating by guests</strong>: Even non registered users can rate images.</li>
+
+  <li><strong>Allow user registration</strong>: Registration is free for all.</li>
+
+  <li><strong>Mail address is obligatory for all users</strong>: Mail address will checked on registration or profile update except if the action is done on administration part.</li>
+
+  <li><strong>Email admins when a new user registers</strong>: Administrators will be received mail for each registration.</li>
+
+</ul>
+
+<h3>History</h3>
+
+  <p>Visits on pages <span
+  class="pwgScreen">category.php</span> and <span
+  class="pwgScreen">picture.php</span> will be saved in the
+  <code>history</code> table.</p>
+  
+  <p>Visits will be shown in <span
+  class="pwgScreen">Administration, Specials, History</span>.</p>
+
+<ul>
+  <li><strong>Save page visits by guests</strong>: page visits by guests will be saved.</li>
+
+  <li><strong>Save page visits by users</strong>: visits by registrered users will be saved.</li>
+
+  <li><strong>Save page visits by administrators</strong>: page visits by administrators will be saved.</li>
+
+</ul>
+
+<h3>Comments</h3>
+<ul>
+
+  <li><strong>Comments for all</strong>: Even guest not registered can post
+  comments.</li>
+
+  <li><strong>Number of comments per page</strong>.</li>
+
+  <li><strong>Validation</strong>: an administrator validate users posted
+  comments before they become visible on the site. User comments validation
+  takes place in screen <span class="pwgScreen">Administration, Pictures,
+  Comments</span>.</li>
+
+  <li><strong>Email admins when a valid comment is entered</strong>:
+Sends an email to the administrators when a user enters a comment and this comment is validated.</li>
+
+  <li><strong>Email admins when a comment requires validation</strong>:
+Sends an email to the administrators when a user enters a comment that requires validation by the admin.
+User comments validation takes place in the screen <span class="pwgScreen">Administration, Pictures, Comments</span>.</li>
+
+</ul>
+
+<!--TODO --><h3>Upload</h3>
+<ul>
+<!--TODO -->  <li><strong>Show upload link every time</strong>: If exists uploadeable categories, add link will be show for each categoy.</li>
+<!--TODO -->  <li><strong>User access level to upload</strong>: Allows to restrict upload by users</li>
+  <li><strong>Email adminis when a picture is uploaded</strong>: Administrators will be received mail for each picture uploaded by a user.</li>
+</ul>
+
+<h3>Default display</h3>
+
+<p>Here you can change display options used by default, when guest is not
+connected. Once connected, these options are overloaded by user own options
+(modifiable in <span class="pwgScreen">profile</span>).</p>
+
+<p>It is possible to change display options for all existing users, but the
+screen to consider is <span class="pwgScreen">Administration,
+Identification, Users</span>, where you can options for a selected list of
+users.</p>
+
+<ul>
+
+  <li><strong>Language</strong>: concerns only Piwigo
+  labels. Category names, picture names and all descriptions are not
+  localized.</li>
+
+  <li><strong>Number of images per row</strong></li>
+
+  <li><strong>Number of rows per page</strong></li>
+
+  <li><strong>Interface theme</strong></li>
+
+  <li><strong>Recent period</strong>: By days. Period within a picture is
+  shown as new. Must be superior to 1 day.</li>
+
+  <li><strong>Expand all categories</strong>: Expand all categories by
+  default in the menu? <em>Warning</em>: this option is resources consuming
+  and may generate a huge menu if your category tree is contains many
+  categories.</li>
+
+  <li><strong>Show number of comments</strong>: show the number of comments
+  for each picture on the thumbnails page. Resource consuming.</li>
+
+  <li><strong>Show hits count</strong>: display hits observed on picture
+  just under its thumbnail on the thumbnails page. 
+  Only when advanced configuration parameter is: <br />
+  $conf['show_nb_hits'] = true; <br />
+  Notice: it is false by default.</li>
+
+  <li><strong>Maximum width of the pictures</strong>: maximum displayed
+  width. If pictures are larger than this setting, they will be resized on
+  display. If you consider filling this option, you'd better consider
+  modifying the width of your pictures instead.</li>
+
+  <li><strong>Maximum height of the pictures</strong>: same remarks as for
+  previous setting.</li>
+
+</ul>
+
Index: /tags/2.0.2/language/en_UK/help/extend_for_templates.html
===================================================================
--- /tags/2.0.2/language/en_UK/help/extend_for_templates.html	(revision 3278)
+++ /tags/2.0.2/language/en_UK/help/extend_for_templates.html	(revision 3278)
@@ -0,0 +1,100 @@
+<h2>Extend for templates configuration</h2>
+
+<h3>Goal</h3>
+<p>Define replacement conditions for each template from template-extension
+(template called "replacer").</p>
+
+<p>"original template" from ./template/yoga (or any other than yoga)
+ will be replaced by a "replacer" if the replacer is linked to this "original template"
+ (and optionally, when the requested URL contains an "optional URL keyword").</p>
+
+<p>"Optional URL keywords" are those you can find after the module name in URLs.</p>
+
+<p>Therefore "Optional URL keywords" can be an active "permalink" 
+(see permalinks in our documentation for further explanation).</p>
+
+<p>Read: `<a href="#warnings">Warning</a>` usage conditions.</p>
+
+<h3>What are template extensions?</h3>
+
+<p>This configuration tool is powerfull for beginners and advanced users.
+By FTP, in the template-extension folder, the Webmaster can duplicate a lot of
+ the distributed .tpl files ("original template") with a different name 
+ ("replacer").
+ 
+ "Original templates", current original supported templates are:</p>
+<ul>
+  <li><span class="filename">index.tpl</span></li>
+  <li><span class="filename">mainpage_categories.tpl</span> and/or <span class="filename">thumbnails.tpl</span></li>
+  <li><span class="filename">menubar.tpl</span></li>
+  <li><span class="filename">header.tpl</span> and/or <span class="filename">footer.tpl</span></li>
+  <li><span class="filename">picture_content.tpl</span> and/or <span class="filename">picture.tpl</span></li>
+  <!-- <li><span class="filename">slideshow.tpl</span></li> -->
+  <li><span class="filename">profile.tpl</span> and/or <span class="filename">profile_content.tpl</span></li>
+  <li><span class="filename">tags.tpl</span></li>
+  <li><span class="filename">upload.tpl</span></li>
+  <li><span class="filename">about.tpl</span></li>
+  <li><span class="filename">popuphelp.tpl</span></li>
+  <li><span class="filename">search.tpl</span> and/or <span class="filename">search_rules.tpl</span></li>
+  <li><span class="filename">nbm.tpl</span> and/or <span class="filename">notification.tpl</span></li>
+  <li><span class="filename">identification.tpl</span> and/or <span class="filename">register.tpl</span></li>
+  <li><span class="filename">redirect.tpl</span></li>
+</ul>
+
+<h3>Where can I find "original templates"?</h3>
+
+<p>Distributed original templates are in template/yoga/ 
+(don't edit them in place for upgrade perspectives). So with "original templates", 
+any webmaster can create his "replacers (customized templates)".</p>
+
+<h3>Where should I save "replacers"?</h3>
+
+<p><strong>Replacers (customized templates)</strong> must be placed in the 
+template-extension folder (or its subfolders).
+Replacers can have any filename with the .tpl extension. For example: <span
+class="filename">template-extension/my-extension/video.tpl</span>.</p>
+
+
+<h3>How can I activate my "replacers"?</h3>
+<p>An <strong>original template</strong> should be assigned to each
+ <strong>replacer (customized templates)</strong> to activate the related replacements.
+ This is the goal of "Extend for templates" in the Configuration Administration menu.</p>
+
+<p>If you select an <strong>optional URL keyword</strong> then replacements 
+will be operate only on pages with this keyword. For example: <span
+  class="pwgScreen">index.php?/<strong>most_visited</strong></span></p>
+  
+<p>Advanced users will use permalinks as <strong>optional URL keyword</strong>. </p>
+
+<p>If you select a <strong>Bound template</strong> then replacements will be operate only on this template.</p>
+
+<h3>How can I deactivate my "replacers"?</h3>
+<ul>
+<li>Unselect related "Original templates".</li>
+<li>By FTP delete of "replacers".</li>
+</ul>
+<a name="warnings"></a>
+<h3>Warnings</h3>
+<ul>
+
+  <li><strong>Original template</strong> must be the "original" template 
+  otherwise you could have unpredictable results!</li>
+
+  <li>On several <strong>replacers (customized templates)</strong> with the
+  same<strong>Original template</strong> and the same <strong>optional URL 
+  keyword</strong> only the last replacer is active.</li>
+
+  <li>Unselected <strong>optional URL keyword</strong> will active the replacer
+  on any template usage. As previous point, order can override previous
+  selected replacers.</li>
+
+  <li>Subfolders:
+Subfolders are ignored but they are usefull to change current order.<br />
+distributed-samples: for test purpose are distributed! 
+<strong>Don't edit them</strong> create your own ones.
+</li>
+
+  <li>On delete of a replacer the <strong>Original template</strong> is 
+  immediately reactivated.</li>
+
+</ul>
Index: /tags/2.0.2/language/en_UK/help/group_list.html
===================================================================
--- /tags/2.0.2/language/en_UK/help/group_list.html	(revision 3278)
+++ /tags/2.0.2/language/en_UK/help/group_list.html	(revision 3278)
@@ -0,0 +1,22 @@
+<h2>Groups list</h2>
+
+<p>This is the place where you can manage defined groups.</p>
+
+<h3>Add a group</h3>
+
+<p>Administrator can add groups.</p>
+
+<h3>Groupes list</h3>
+
+<p>The list allows for each element to:</p>
+
+
+<ul>
+  <li>go to members list</li>
+  <li>go to permissions</li>
+  <li>delete the group (require a confirmation checkbox)</li>
+  <li>toggle status "default" (require a confirmation checkbox)</li>
+</ul>
+
+<h3>Default groups</h3>
+<p>Default groups are groups associated automatically to new user.</p>
Index: /tags/2.0.2/language/en_UK/help/history.html
===================================================================
--- /tags/2.0.2/language/en_UK/help/history.html	(revision 3278)
+++ /tags/2.0.2/language/en_UK/help/history.html	(revision 3278)
@@ -0,0 +1,45 @@
+<h2>History</h2>
+
+<p>These screens allows you to follow the historical navigation en Piwigo
+according to the options yo have chosen in - Administration - General - History index.</p>
+	
+<h3>Statistics</h3>
+<ul>
+  <p>If you have chosen to keep the pages visited (<span
+class="pwgScreen">index.php</span> and <span
+class="pwgScreen">picture.php</span>) in the table <code>history. </code>
+This index allow you to follow the pages visited.</p>
+	
+	<li><strong>Global statistics</strong> : you can visualize per year. </li>
+	
+	<li><strong>Yearly statistics</strong> : you can visualize per month in the year selected.</li>
+	
+	<li><strong>Monthly statistics</strong> : you can visualize per days in the month selected.</li>
+	
+	<li><strong>Dayly statistics</strong> : you can visualize per hours in the day selected.</li>
+	
+</ul>
+
+<h3>Search</h3>
+<ul>
+  <p>If you have chosen to keep the pages visited (<span
+class="pwgScreen">index.php</span> and <span
+class="pwgScreen">picture.php</span>) in the table <code>history. </code>
+This index allow to follow en details the pages visited on the site with 
+the help of different filters.</p>
+ 
+	<li><strong>Filter per date</strong> : chose interval of date you wisk
+	to observe the activity.</li>
+	
+	<li><strong>Filter per type of element</strong> : chose the type 
+	of element you wisk to observe the activity.</li>
+	
+	<li><strong>Filter per user</strong> : chose user you wisk to 
+	observe the activity.</li>
+	
+	<li><strong>Filter per name of the file</strong> : chose name of the file 
+	you	wisk to observe the activity.</li>
+	
+	<li><strong>Filter per identifying image</strong> : chose identifying image 
+	you wisk to observe the activity.</li>
+</ul>
Index: /tags/2.0.2/language/en_UK/help/index.php
===================================================================
--- /tags/2.0.2/language/en_UK/help/index.php	(revision 3278)
+++ /tags/2.0.2/language/en_UK/help/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/language/en_UK/help/maintenance.html
===================================================================
--- /tags/2.0.2/language/en_UK/help/maintenance.html	(revision 3278)
+++ /tags/2.0.2/language/en_UK/help/maintenance.html	(revision 3278)
@@ -0,0 +1,46 @@
+<h2>Maintenance</h2>
+
+<p>To optimize page generation time, Piwigo uses cached
+information. For example, instead of counting the number of pictures
+contained in each category at each page reload, this information is stored
+in the database. In theory, this information should always be correct, but
+sometimes an error can occur and cached information becomes wrong.</p>
+
+<p>Some informations become useless with time. Deleting this useless
+information from database make you save disk space.</p>
+
+<ul>
+
+  <li><strong>Update categories informations:</strong> For each category,
+  informations to update or control are the following : list of parent
+  categories, number of pictures, date of the last picture, position among
+  brother categories, position among all categories. This action also checks
+  the coherence of representative picture.</li>
+
+  <li><strong>Update images informations:</strong> For each picture,
+  informations to update are : full path to file, average
+  rate. <em>Warning</em>: do not get confuse with metadata informations
+  which can be synchronized from <span class="pwgScreen">Administration,
+  Categories, Synchronize</span> or by reaching the modification screen of a
+  single picture (through <span class="pwgScreen">Picture</span> for
+  example).</li>
+
+  <li><strong>Repair and optimize database:</strong>
+  For each table, re-odrer, repair and optimize operations are done.
+  </li>
+</ul>
+
+<ul>
+  <li><strong>Purge history detail:</strong> Delete all lines from
+  <code>history</code> table. Screen <span class="pwgScreen">Administration,
+  Specials, History</span> shows no informations anymore on past
+  history. <em>Warning</em>: all data will be lost and there is no way to
+  get informations back.</li>
+
+  <li><strong>Purge history summary:</strong> Delete all the summary information about visit history. This summary is calculated from the history detail.</li>
+
+  <li><strong>Purge sessions:</strong> Delete expired user sessions.</li>
+
+  <li><strong>Purge never used notification feeds</strong></li>
+
+</ul>
Index: /tags/2.0.2/language/en_UK/help/notification_by_mail.html
===================================================================
--- /tags/2.0.2/language/en_UK/help/notification_by_mail.html	(revision 3278)
+++ /tags/2.0.2/language/en_UK/help/notification_by_mail.html	(revision 3278)
@@ -0,0 +1,15 @@
+<h2>Notification by mail</h2>
+
+<p>This screen allows to configure and manage email notifications to users of news on your site.</p>
+
+<p>This screen is composed of 3 tabs:</p>
+
+<h3>Parameters</h3>
+<p>Available only for webmasters, this tab sets parameters of the notification by mail.</p>
+
+<h3>Subscribe</h3>
+<p>Available only for webmasters, this tab manages subscription/unsubscription of users to email notifications.</p>
+
+<h3>Envoi</h3>
+<p>Available only for webmasters and administrators, this tab allows to send mails to notify news.</p>
+
Index: /tags/2.0.2/language/en_UK/help/permalinks.html
===================================================================
--- /tags/2.0.2/language/en_UK/help/permalinks.html	(revision 3278)
+++ /tags/2.0.2/language/en_UK/help/permalinks.html	(revision 3278)
@@ -0,0 +1,7 @@
+<h2>Permalinks</h2>
+
+<p>Permalinks are used to make category urls nicer. When a category has a permalink defined, the id of the category is not required anymore in the url.</p>
+
+<p>When a permalink is deleted, you have the ability to save it to the permalink history, so that external links to PWG pages still work. In the permalink history table you can see the date when the permalink has been deleted as well as the last time when it was used and the number of times this permalink has been used.</p>
+
+<p>Note that permalinks must be unique per category. Also in the permalink history you cannot have the same permalink defined more than once.</p>
Index: /tags/2.0.2/language/en_UK/help/search.html
===================================================================
--- /tags/2.0.2/language/en_UK/help/search.html	(revision 3278)
+++ /tags/2.0.2/language/en_UK/help/search.html	(revision 3278)
@@ -0,0 +1,24 @@
+<h2>Search</h2>
+
+<p>This page let you search pictures among the whole gallery.</p>
+
+<dl>
+
+  <dt>Search for words</dt>
+  <dd>Search for entered words in all the attributes related to the pictures
+  displayed in the gallery. Use * as a wildcard for partial matches.</dd>
+
+  <dt>Search for Author</dt>
+  <dd>Use * as a wildcard for partial matches.</dd>
+
+  <dt>Search by Date</dt>
+  <dd>Select a date and/or an ending date for your query. Leave date empty
+  if you want to make a "before" query. The year must be entered in the last
+  field in the following format : 0000 (i.e. 2004)</dd>
+
+  <dt>Search in Categories</dt>
+  <dd>Select the category or categories you wish to search in. For speed all
+  subcategories can be searched by selecting the parent and setting enable
+  search subcategories below.</dd>
+
+</dl>
Index: /tags/2.0.2/language/en_UK/help/site_manager.html
===================================================================
--- /tags/2.0.2/language/en_UK/help/site_manager.html	(revision 3278)
+++ /tags/2.0.2/language/en_UK/help/site_manager.html	(revision 3278)
@@ -0,0 +1,51 @@
+<h2>Remote sites</h2>
+
+<p>Piwigo offers the possibility to use several servers to store the
+images which will compose your gallery. It can be useful if your gallery is
+installed on one limited space and that you have a big quantity of images to
+be shown.</p>
+
+<ol>
+
+  <li>edit file <span class="filename">tools/create_listing_file.php</span>,
+  by modifying parameters section such as
+  <code>$conf['prefix_thumbnail']</code> or
+  <code>$conf['use_exif']</code>.</li>
+
+  <li>place file <span class="filename">tools/create_listing_file.php</span>
+  modified on your distant website, in the same directory than your category
+  directories (as the directory <span class="filename">galleries</span> of
+  this website) by ftp. For the example, let's say that you can access <span
+  class="filename">http://example.com/galleries/create_listing_file.php</span>.</li>
+
+  <li>go to <span class="pwgScreen">administration panel, Categories, Site
+  manager</span>. Ask to create a new site, for example <span
+  class="filename">http://example.com/galleries</span>.</li>
+
+  <li>a new remote site is registered. You can perform 4 actions :
+
+    <ol>
+
+      <li><strong>generate listing</strong> : launches a distant request to
+      generate a distant file listing</li>
+
+      <li><strong>synchronize</strong> : reads the distant <span
+      class="filename">listing.xml</span> file and synchronizes with
+      database informations.</li>
+
+      <li><strong>clean</strong> : removes distant <span
+      class="filename">listing.xml</span> file.</li>
+
+      <li><strong>delete</strong> : deletes the site (and all related
+      categories and elements) in the database.</li>
+
+    </ol>
+  </li>
+</ol>
+
+<!-- <p>You can do all this by hand by generating yourself the <span
+class="filename">listing.xml</span> file, moving it from your distant server
+to you local Piwigo root directory and opening the remote site
+management screen : Piwigo will propose you to use the found
+listing.xml file.</p>-->
+
Index: /tags/2.0.2/language/en_UK/help/synchronize.html
===================================================================
--- /tags/2.0.2/language/en_UK/help/synchronize.html	(revision 3278)
+++ /tags/2.0.2/language/en_UK/help/synchronize.html	(revision 3278)
@@ -0,0 +1,13 @@
+<h2>Synchronize</h2>
+
+<p>There are 2 synchronizations possible : directories/files and file
+metadata. directories/files is about synchronizing your directories tree
+with the category tree in the database. metadata is about updating elements
+informations such as filesize, dimensions in pixels, EXIF or IPTC
+informations.</p>
+
+<p>The first synchronization must be the directories/files one.</p>
+
+<p>Synchronization process may take long (depending on your server load and
+quantity of elements to manage) so it is possible to progress by step:
+category by category.</p>
Index: /tags/2.0.2/language/en_UK/help/thumbnail.html
===================================================================
--- /tags/2.0.2/language/en_UK/help/thumbnail.html	(revision 3278)
+++ /tags/2.0.2/language/en_UK/help/thumbnail.html	(revision 3278)
@@ -0,0 +1,28 @@
+<h2>Thumbnails creation</h2>
+
+<p>This page let you create missing thumbnails.</p>
+
+<dl>
+
+  <dt>GD version</dt>
+
+  <dd>GD is the picture manipulating library for PHP. Choose the version
+  installed on your server. If you choose the wrong, you'll just have errors
+  messages, come back with your browser and choose the other version. If no
+  version works, it means your server doesn't support GD.</dd>
+
+  <dt>Width and height</dt>
+
+  <dd>Maximum dimensions that thumbnails can take. Aspect ratio is
+  maintained.</dd>
+
+  <dt>Number of thumbnails to create</dt>
+
+  <dd>Do not try to miniaturize too many pictures in the same time. Indeed, miniaturization uses a lot of CPU. If you installed Piwigo on a free provider, a too high CPU load can sometime lead to the deletion of your website.</dd>
+
+  <dt>File format</dt>
+
+  <dd>Only JPEG file format is supported for thumbnail creation. Thumbnails
+  can be created only from PNG and JPEG pictures.</dd>
+
+</dl>
Index: /tags/2.0.2/language/en_UK/help/user_list.html
===================================================================
--- /tags/2.0.2/language/en_UK/help/user_list.html	(revision 3278)
+++ /tags/2.0.2/language/en_UK/help/user_list.html	(revision 3278)
@@ -0,0 +1,43 @@
+<h2>Users list</h2>
+
+<p>This is the place where you can manage registered users. Only permissions
+are managed in different several screens.</p>
+
+<h3>Add a user</h3>
+
+<p>Administrator can manually add users.</p>
+
+<h3>Users list</h3>
+
+<p>The list can be filtered on username (use * as wildcard), group or
+status. The list can be order by registration date or username, in ascending
+or descending order.</p>
+
+<p>This screen works be managing several users at once on different actions
+:</p>
+
+<ul>
+
+  <li>delete users (require a confirmation checkbox)</li>
+
+  <li>change status</li>
+
+  <li>associate or dissociate from groups</li>
+
+  <li>modify display properties</li>
+
+  <li>modify additional properties</li>
+
+</ul>
+
+<p>The target is the set users selected (by default) or all users is
+asked.</p>
+<h3>Adviser</h3>
+<p>Definition of adviser user:</p>
+<ul>
+  <li>allow access of all screens permitted by this status</li>
+  <li>read-only or simulate-only access</li>
+</ul>
+
+<p>It's possible to assign adviser mode with variable $conf['allow_adviser'].</p>
+<p>If this variable is 'true', it's possible to define user like an adviser</p>
Index: /tags/2.0.2/language/en_UK/index.php
===================================================================
--- /tags/2.0.2/language/en_UK/index.php	(revision 3278)
+++ /tags/2.0.2/language/en_UK/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/language/en_UK/install.lang.php
===================================================================
--- /tags/2.0.2/language/en_UK/install.lang.php	(revision 3278)
+++ /tags/2.0.2/language/en_UK/install.lang.php	(revision 3278)
@@ -0,0 +1,76 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+$lang['Installation'] = 'Installation';
+$lang['Initial_config'] = 'Basic configuration';
+$lang['Default_lang'] = 'Default gallery language';
+$lang['step1_title'] = 'Database configuration';
+$lang['step2_title'] = 'Admin configuration';
+$lang['Start_Install'] = 'Start Install';
+$lang['reg_err_mail_address'] = 'mail address must be like xxx@yyy.eee (example : jack@altern.org)';
+
+$lang['install_webmaster'] = 'Webmaster login';
+$lang['install_webmaster_info'] = 'It will be shown to the visitors. It is necessary for website administration';
+
+$lang['step1_confirmation'] = 'Parameters are correct';
+$lang['step1_err_db'] = 'Connection to server succeed, but it was impossible to connect to database';
+$lang['step1_err_server'] = 'Can\'t connect to server';
+$lang['step1_err_copy_2'] = 'The next step of the installation is now possible';
+$lang['step1_err_copy_next'] = 'next step';
+$lang['step1_err_copy'] = 'Copy the text in pink between hyphens and paste it into the file "include/mysql.inc.php"(Warning : mysql.inc.php must only contain what is in pink, no line return or space character)';
+
+$lang['step1_host'] = 'MySQL host';
+$lang['step1_host_info'] = 'localhost, sql.multimania.com, toto.freesurf.fr';
+$lang['step1_user'] = 'User';
+$lang['step1_user_info'] = 'user login given by your host provider';
+$lang['step1_pass'] = 'Password';
+$lang['step1_pass_info'] = 'user password given by your host provider';
+$lang['step1_database'] = 'Database name';
+$lang['step1_database_info'] = 'also given by your host provider';
+$lang['step1_prefix'] = 'Database table prefix';
+$lang['step1_prefix_info'] = 'database tables names will be prefixed with it (enables you to manage better your tables)';
+$lang['step2_err_login1'] = 'enter a login for webmaster';
+$lang['step2_err_login3'] = 'webmaster login can\'t contain characters \' or "';
+$lang['step2_err_pass'] = 'please enter your password again';
+$lang['install_end_title'] = 'Installation finished';
+$lang['step2_pwd'] = 'Webmaster password';
+$lang['step2_pwd_info'] = 'Keep it confidential, it enables you to access administration panel';
+$lang['step2_pwd_conf'] = 'Password [confirm]';
+$lang['step2_pwd_conf_info'] = 'verification';
+$lang['install_help'] = 'Need help ? Ask your question on <a href="%s">Piwigo message board</a>.';
+$lang['install_end_message'] = 'The configuration of Piwigo is finished, here is the next step<br /><br />
+* go to the identification page and use the login/password given for webmaster<br />
+* this login will enable you to access to the administration panel and to the instructions in order to place pictures in your directories';
+$lang['conf_mail_webmaster'] = 'Webmaster mail address';
+$lang['conf_mail_webmaster_info'] = 'Visitors will be able to contact site administrator with this mail';
+
+$lang['PHP 5 is required'] = 'PHP 5 is required';
+$lang['It appears your webhost is currently running PHP %s.'] = 'It appears your webhost is currently running PHP %s.';
+$lang['Piwigo may try to switch your configuration to PHP 5 by creating or modifying a .htaccess file.'] = 'Piwigo may try to switch your configuration to PHP 5 by creating or modifying a .htaccess file.';
+$lang['Note you can change your configuration by yourself and restart Piwigo after that.'] = 'Note you can change your configuration by yourself and restart Piwigo after that.';
+$lang['Try to configure PHP 5'] = 'Try to configure PHP 5';
+$lang['Sorry!'] = 'Sorry!';
+$lang['Piwigo was not able to configure PHP 5.'] = 'Piwigo was not able to configure PHP 5.';
+$lang["You may referer to your hosting provider's support and see how you could switch to PHP 5 by yourself."] = "You may referer to your hosting provider's support and see how you could switch to PHP 5 by yourself.";
+$lang['Hope to see you back soon.'] = 'Hope to see you back soon.';
+?>
Index: /tags/2.0.2/language/en_UK/iso.txt
===================================================================
--- /tags/2.0.2/language/en_UK/iso.txt	(revision 3278)
+++ /tags/2.0.2/language/en_UK/iso.txt	(revision 3278)
@@ -0,0 +1,1 @@
+English [UK]
Index: /tags/2.0.2/language/en_UK/upgrade.lang.php
===================================================================
--- /tags/2.0.2/language/en_UK/upgrade.lang.php	(revision 3278)
+++ /tags/2.0.2/language/en_UK/upgrade.lang.php	(revision 3278)
@@ -0,0 +1,44 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+$lang['Upgrade'] = 'Upgrade';
+$lang['introduction message'] = 'This page proposes to upgrade your database corresponding to your old version of Piwigo to the current version.
+The upgrade assistant thinks you are currently running a <strong>release %s</strong> (or equivalent).';
+$lang['Upgrade from %s to %s'] = 'Upgrade from version %s to %s';
+$lang['Statistics'] = 'Statistics';
+$lang['total upgrade time'] = 'total upgrade time';
+$lang['total SQL time'] = 'total SQL time';
+$lang['SQL queries'] = 'SQL queries';
+$lang['Upgrade informations'] = 'Upgrade informations';
+$lang['perform a maintenance check'] = 'Perform a maintenance check in [Administration>Specials>Maintenance] if you encounter any problem.';
+$lang['deactivated plugins'] = 'As a precaution, following plugins have been deactivated. You must check for plugins upgrade before reactiving them:';
+$lang['upgrade login message'] = 'Only administrator can run upgrade: please sign in below.';
+$lang['You do not have access rights to run upgrade'] = 'You do not have access rights to run upgrade';
+$lang['in include/mysql.inc.php, before ?>, insert:'] = 'In <i>include/mysql.inc.php</i>, before <b>?></b>, insert:';
+
+// Upgrade informations from upgrade_1.3.1.php
+$lang['all sub-categories of private categories become private'] = 'All sub-categories of private categories become private';
+$lang['user permissions and group permissions have been erased'] = 'User permissions and group permissions have been erased';
+$lang['only thumbnails prefix and webmaster mail saved'] = 'Only thumbnails prefix and webmaster mail address have been saved from previous configuration';
+
+?>
Index: /tags/2.0.2/language/es_ES/about.html
===================================================================
--- /tags/2.0.2/language/es_ES/about.html	(revision 3278)
+++ /tags/2.0.2/language/es_ES/about.html	(revision 3278)
@@ -0,0 +1,8 @@
+  <li>Piwigo es una aplicación web que permite crear fácilmente una galería de imágenes en línea.</li>
+
+  <li>Técnicamente, Piwigo es desarrollado en PHP con una base de datos MySQL.</li>
+
+  <li>Si usted tiene sugerencias o comentarios, visita  <a
+  href="http://piwigo.org">sitio oficial</a>.</li>
+
+  
Index: /tags/2.0.2/language/es_ES/admin.lang.php
===================================================================
--- /tags/2.0.2/language/es_ES/admin.lang.php	(revision 3278)
+++ /tags/2.0.2/language/es_ES/admin.lang.php	(revision 3278)
@@ -0,0 +1,647 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+$lang['%d association'] = '%d asociación';
+$lang['%d associations'] = '%d asociaciones';
+$lang['cat_inclu_part1_S'] = '%d categoría entre las cuales ';
+$lang['cat_inclu_part1_P'] = '%d categorías entre las cuates ';
+$lang['cat_inclu_part2_S'] = '%d físico';
+$lang['cat_inclu_part2_P'] = '%d físicos';
+$lang['cat_inclu_part3_S'] = ' et %d virtual';
+$lang['cat_inclu_part3_P'] = ' et %d virtuales';
+$lang['%d category moved'] = '%d categoría trasladada';
+$lang['%d categories moved'] = '%d categorías trasladadas';
+$lang['%d group'] = '%d grupo';
+$lang['%d groups'] = '%d grupos';
+$lang['%d member'] = '%d miembro';
+$lang['%d members'] = '%d miembros';
+$lang['%d tag'] = '%d tag';
+$lang['%d tags'] = '%d tags';
+$lang['%d user comment rejected'] = '%d comentario de utilizador rechazado';
+$lang['%d user comments rejected'] = '%d comentarios de utilizadores rechazados';
+$lang['%d user comment validated'] = '%d comentario de utilizador validado';
+$lang['%d user comments validated'] = '%d comentarios de utilizadores validados';
+$lang['%d user deleted'] = '%d utilizador suprimido';
+$lang['%d users deleted'] = '%d utilizadores suprimidos';
+$lang['%d user'] = '%d utilizador';
+$lang['%d users'] = '%d utilizadores';
+$lang['%d waiting for validation'] = '%d en espera de validación';
+$lang['%d waiting pictures rejected'] = '%d imágenes en espera rechazadas';
+$lang['%d waiting pictures validated'] = '%d imágenes en espera validadas';
+$lang['Actions'] = 'Acciones';
+$lang['Activate'] = 'Acelerar';
+$lang['Add/delete a permalink'] = 'Añadir / borrar un lazo permanente';
+$lang['Add a tag'] = 'Añadir un tag';
+$lang['Add a user'] = 'Añadir un utilizador';
+$lang['Add group'] = 'Añadir un grupo';
+$lang['Add selected elements to caddie'] = 'Añadir los elementos seleccionados a la cesta';
+$lang['Add'] = 'Añadir';
+$lang['Allow user registration'] = 'Permitir el registro de los utilizadores';
+$lang['Apply to subcategories'] = 'Aplicar a subcategorías';
+$lang['Are you sure?'] = '¿ Seguro?';
+$lang['Associated'] = 'Asociada a';
+$lang['Association to categories'] = 'Asociación a las categorías';
+$lang['Batch management'] = 'Gestión por premio';
+$lang['Caddie management'] = 'Gestión de la cesta';
+$lang['Caddie'] = 'Cesta';
+$lang['Categories authorized thanks to group associations'] = 'Categorías accesibles gracias a la pertenencia a los grupos';
+$lang['Categories manual order was saved'] = 'La orden manual de las categorías ha sido salvaguardada';
+$lang['Categories ordered alphanumerically'] = 'Categorías ordenadas alfabético - numéricamente';
+$lang['Category elements associated to the following categories: %s'] = 'Los elementos de la categoría han sido asociados con las categorías siguientes : %s';
+$lang['Check for upgrade failed for unknown reasons.'] = 'La comprobación de la última versión sobre el servidor fue suspendida por una razón desconocida.';
+$lang['Check for upgrade'] = 'Última versión';
+$lang['Comments for all'] = 'Comentarios para todos';
+$lang['Controversy'] = 'Controversia';
+$lang['Current name'] = 'Nombre corriente';
+$lang['Database'] = 'Base de datos';
+$lang['Deactivate'] = 'Desactivar';
+$lang['Delete Representant'] = 'Suprimir al representante';
+$lang['Delete selected tags'] = 'Suprimir los tags seleccionados';
+$lang['Delete selected users'] = 'Suprimir los utilizadores seleccionados';
+$lang['Deletions'] = 'Supresiones';
+$lang['Deny selected groups'] = 'Prohibir el acceso a los grupos seleccionados';
+$lang['Deny selected users'] = 'Prohibirles el acceso a los utilizadores seleccionados';
+$lang['Description'] = 'Descripción';
+$lang['Display options'] = 'Opciones de fijación';
+$lang['Dissociated'] = 'Separada de';
+$lang['Does not represent'] = 'No representes';
+$lang['Edit all picture informations'] = 'Modificar todas las informaciones atadas(vinculadas) a esta imagen';
+$lang['Edit selected tags'] = 'Editar los tags seleccionadas';
+$lang['Edit tags'] = 'Editar los tags';
+$lang['Elements'] = 'Elementos';
+$lang['Email administrators when a new user registers'] = 'Notificar a los administradores en el momento de la inscripción de un utilizador';
+$lang['Email administrators when a valid comment is entered'] = 'Notificar a los administradores cuando un comentario es registrado';
+$lang['Email administrators when a comment requires validation'] = 'Notificar a los administradores cuando un comentario requiere su validación';
+$lang['Email administrators when a picture is uploaded'] = 'Notificar a los administradores cuando una imagen es cargada';
+$lang['Empty caddie'] = 'Vaciar la cesta';
+$lang['Environment'] = 'Medio ambiente';
+$lang['Form'] = 'Formulario';
+$lang['Gallery URL'] = 'URL de la galería';
+$lang['Gallery description'] = 'Descripción de la galería';
+$lang['Gallery title'] = 'Título de la galería';
+$lang['Grant selected groups'] = 'Dar el acceso a los grupos seleccionados';
+$lang['Grant selected users'] = 'Darles el acceso a los utilizadores seleccionados';
+$lang['Group name'] = 'Nombre del grupo';
+$lang['Groups'] = 'Grupos';
+$lang['Guests'] = 'Invitados';
+$lang['History'] = 'histórico';
+$lang['Informations'] = 'Informaciones';
+$lang['Install'] = 'Instalar';
+$lang['Link all category elements to a new category'] = 'Vincular todos los elementos de la categoría con una nueva categoría';
+$lang['Link all category elements to some existing categories'] = 'Vincular odos los elementos de la categoría existentes';
+$lang['Linked categories'] = 'Categorías asociadas';
+$lang['Lock gallery'] = 'Encerrar la galería';
+$lang['Maintenance'] = 'Mantenimiento';
+$lang['Manage permissions for a category'] = 'Administrar las autorizaciones para una categoría';
+$lang['Manage permissions for group "%s"'] = 'Administrar las autorizaciones para el grupo "%s"';
+$lang['Manage permissions for user "%s"'] = 'Administrar las autorizaciones para el utilizador "%s"';
+$lang['Manage tags'] = 'Administrar los tags';
+$lang['Members'] = 'Miembros';
+$lang['Metadata synchronized from file'] = 'Meta-datos sincronizadas a partir del fichero';
+$lang['Move categories'] = 'Desplazar las categorías';
+$lang['Move'] = 'Desplazar';
+$lang['Name'] = 'Nombre';
+$lang['New name'] = 'Nuevo nombre';
+$lang['New parent category'] = 'Nueva categoría allegada';
+$lang['New tag'] = 'Nuevo tag';
+$lang['No tag defined. Use Administration>Pictures>Tags'] = 'Ninguna tag definida. Utilizar la pantalla Adminstration> Imágenes> tags';
+$lang['Number of comments per page'] = 'Número de comentarios por página';
+$lang['Number of rates'] = 'Número de notas';
+$lang['Number of thumbnails to create'] = 'Número de miniaturas que hay que crear';
+$lang['Only private categories are listed'] = 'Sólo las categorías particulares son puestas en una lista';
+$lang['Operating system'] = 'Systema de explotación';
+$lang['Options'] = 'Opciones';
+$lang['Order alphanumerically'] = 'Ordenar alfabético - numéricamente';
+$lang['Other private categories'] = 'Otras categorías particulares';
+$lang['Page banner'] = 'Bandera de las páginas';
+$lang['Parent category'] = 'Categoría allegada';
+$lang['Path'] = 'Camino';
+$lang['Permalink'] = 'Lazo permanente';
+$lang['Permalink_%s_histo_used_by_%s'] = 'El lazo permanente %s ha sido utilizado anteriormente por la categoría %s. Por favor, bórrelo de la reseña histórica de los lazos permanentes';
+$lang['Permalink_name_rule'] = 'El lazo permanente debe contener carácteres sólo entre " Tiene - zA-Z0-9 ", "-" o "_". No debe ser numérico o comenzar con un número seguido por "-"';
+$lang['Permalink %s is already used by category %s'] = 'El lazo permanente %s es ya utilizado por la categoría %s';
+$lang['Permalink history'] = 'Reseña histórica de los lazos permanentes';
+$lang['Permalinks'] = 'Lazos permanentes';
+$lang['Permission denied'] = 'Acceso prohibido';
+$lang['Permission granted thanks to a group'] = 'Acceso autorizado gracias a la pertenencia a los grupos';
+$lang['Permission granted'] = 'Acceso autorizado';
+$lang['Picture informations updated'] = 'Informaciones puestas al día de la imagen';
+$lang['Plugins'] = 'Plugins';
+$lang['Position'] = 'Posición';
+$lang['Preferences'] = 'Preferencias';
+$lang['Properties'] = 'Propiedades';
+$lang['Random picture'] = 'Al azar';
+$lang['Rate date'] = 'Data de notación';
+$lang['Rating by guests'] = 'Notación por los visitadores';
+$lang['Rating'] = 'Notación';
+$lang['Reject All'] = 'Rechazar todo';
+$lang['Reject'] = 'Rechazar';
+$lang['Representant'] = 'Representante';
+$lang['Representation of categories'] = 'Representación de las categorías';
+$lang['Representative'] = 'Representante';
+$lang['Represents'] = 'Representa';
+$lang['Save order'] = 'Salvaguardar la orden';
+$lang['Save to permalink history'] = 'Salvaguardar en la reseña histórica de los lazos permanentes';
+$lang['Select at least one category'] = 'Seleccionar por lo menos una categoría';
+$lang['Select at least one picture'] = 'Seleccionar por lo menos una imagen';
+$lang['Select at least one user'] = 'Seleccionar por lo menos a un utilizador';
+$lang['Show info'] = 'Mostrar las informaciones';
+$lang['Site manager'] = 'Gerente de los sitios';
+$lang['Status'] = 'Estatuto';
+$lang['Statistics'] = 'Estadísticas';
+$lang['Storage category'] = 'Categoría de almacenamiento';
+$lang['Sum of rates'] = 'Suma notas';
+$lang['Tag "%s" already exists'] = 'El tag "%s" ya existe';
+$lang['Tag "%s" was added'] = 'El tag "%s" ha sido añadida';
+$lang['Tag selection'] = 'Selección de tags';
+$lang['Take selected elements out of caddie'] = 'Sacar los elementos seleccionados de la cesta';
+$lang['The %d following tag were deleted'] = 'El tag siguiente ha sido suprimido';
+$lang['The %d following tags were deleted'] = 'Los %d tags siguientes han sido suprimidos';
+$lang['Unable to check for upgrade.'] = 'Imposible conocer la última versión.';
+$lang['Uninstall'] = 'Desinstalar';
+$lang['Use default sort order']='Utilizar la orden de selección de las imágenes por defecto (definido en el fichero de configuración)';
+$lang['User comments validation'] = 'Validación de los comentarios de utilizadores';
+$lang['Users'] = 'Utilizadores';
+$lang['Validate All'] = 'Validar todo';
+$lang['Validate'] = 'Validar';
+$lang['Validation'] = 'Validación';
+$lang['Version'] = 'Versión';
+$lang['Virtual categories movement'] = 'Desplazamiento de categorías virtuales';
+$lang['Virtual categories to move'] = 'Categorías virtuales que hay que desplazar';
+$lang['Virtual category name'] = 'Nombre de la categoría virtual';
+$lang['Webmaster cannot be deleted'] = 'El webmestre no puede ser suprimido';
+$lang['You are running on development sources, no check possible.'] = 'Usted trabaja con las fuentes de desarrollo, imposible verificar la última versión.';
+$lang['You cannot delete your account'] = "Usted no puede suprimir su cuenta";
+$lang['You cannot move a category in its own sub category'] = 'Usted no puede desplazar una categoría en su propia subcategoría';
+$lang['You need to confirm deletion'] = 'Usted debe confirmar la supresión';
+$lang['add tags'] = 'Añadir los tags';
+$lang['adviser'] = 'Consejero';
+$lang['associate to category'] = 'asociar con la categoría';
+$lang['associate to group'] = 'asociar con grupo';
+$lang['authorized'] = 'Autorizados';
+$lang['cat_add'] = 'Añadir una categoría virtual';
+$lang['cat_comments_title'] = 'Autorizar a los utilizadores a añadir comentarios en las categorías seleccionadas';
+$lang['cat_error_name'] = 'El nombre de la categoría no debe estar vacío';
+$lang['cat_lock_title'] = 'Encerrar las categorías';
+$lang['cat_private'] = 'Categoría particular';
+$lang['cat_public'] = 'Categoría pública';
+$lang['cat_representant'] = 'Encontrar a un nuevo representante al azar';
+$lang['cat_security'] = 'Pública / Particular';
+$lang['cat_status_title'] = 'Administrar el tipo de acceso para las categorías seleccionadas';
+$lang['cat_upload_title'] = 'Seleccionar las categorías autorizadas al añadido';
+$lang['cat_virtual_added'] = 'Categoría virtual añadida';
+$lang['cat_virtual_deleted'] = 'Categoría virtual suprimida';
+$lang['category'] = 'Categoría';
+$lang['conf_access'] = 'Tipo de acceso';
+$lang['conf_comments_title'] = 'Comentarios';
+$lang['conf_confirmation'] = 'Informaciones registradas en la base de datos';
+$lang['conf_display'] = 'Fijación por defecto';
+$lang['conf_history_title'] = 'Reseña histórica';
+$lang['conf_gallery_url_error'] = 'La dirección de la galería no es válida.';
+$lang['conf_main_title'] = 'Directora de colegio';
+$lang['conf_nb_comment_page_error'] = 'El número de comentarios de utilizadores por página debe ser comprendido entre 5 y 50.';
+$lang['config'] = 'Configuración';
+$lang['confirm'] = 'Confirmar';
+$lang['Date'] = 'Fecha';
+$lang['delete category'] = 'Suprimir la categoría';
+$lang['dissociate from category'] = 'Disociar la categoría';
+$lang['dissociate from group'] = 'Disociar el grupo';
+$lang['edit category permissions'] = 'Modificar los permisos de la categoría';
+$lang['editcat_confirm'] = 'Las informaciones de la categoría han sido puestas al día con éxito.';
+$lang['editcat_uploadable'] = 'Autorizar el añadido de imágenes';
+$lang['elements per page'] = 'Elementos por página';
+$lang['elements'] = 'Elementos';
+$lang['enabled_high'] = 'Alta definición activo';
+$lang['file'] = 'Fichero';
+$lang['filesize'] = 'Peso';
+$lang['first element added on %s'] = 'el primer elemento añadido %s';
+$lang['forbidden'] = 'entredicho';
+$lang['conf_general'] = 'Ensayo general';
+$lang['global mode'] = 'modo global';
+$lang['group "%s" added'] = 'grupo "%s" añadido';
+$lang['group "%s" deleted'] = 'grupo "%s" suprimido';
+$lang['group "%s" updated'] = 'grupo "%s" puestos al día';
+$lang['group'] = 'grupo';
+$lang['group_add_error1'] = 'El nombre del grupo no debe contener "or \' y no debe estar vacío.';
+$lang['group_add_error2'] = 'Este nombre es ya utilizado por otro grupo.';
+$lang['groups'] = 'Grupos';
+$lang['instructions'] = 'Instrucciones';
+$lang['is_high_disabled'] = '';
+$lang['is_high_enabled'] = 'Alta definición';
+$lang['jump to category'] = 'Ir en la categoría';
+$lang['jump to image'] = 'Ir a la imagen';
+$lang['leave'] = 'dejar';
+$lang['lock'] = 'Encerrar';
+$lang['locked'] = 'Encerrado';
+$lang['manage category elements'] = 'administrar los elementos de la categoría';
+$lang['manage sub-categories'] = 'administrar las subcategorías';
+$lang['manage'] = 'Administrar';
+$lang['maximum height'] = 'Altura máxima';
+$lang['maximum width'] = 'Anchura máxima';
+$lang['nbm_background_treatment_redirect_second'] = 'Ser sobrepasado el tiempo de ejecución, el tratamiento debe continuar [el Tiempo estimado: %d el segundo].';
+$lang['nbm_background_treatment_redirect_seconds'] = 'Ser sobrepasado el tiempo de ejecución, el tratamiento debe continuar [el Tiempo estimado: %d secundas].';
+$lang['nbm_break_timeout_list_user'] = 'El tiempo de preparación de la lista de los utilizadores para el envío es limitado. Otros utilizadores no son puestos en una lista.';
+$lang['nbm_break_timeout_send_mail'] = 'El tiempo de envío del mails es limitado. Otros envíos de mail han sido ignorados.';
+$lang['nbm_col_check_user_send_mail'] = '¿ Enviar?';
+$lang['nbm_col_last_send'] = 'Último envío';
+$lang['nbm_col_mail'] = 'e-mail';
+$lang['nbm_col_user'] = 'Utilizador';
+$lang['nbm_complementary_mail_content'] = 'Contenido complementario en el mail';
+$lang['nbm_content_byebye'] = 'Hasta pronto,';
+$lang['nbm_content_goto_1'] = 'Cita sobre ';
+$lang['nbm_content_goto_2'] = '.';
+$lang['nbm_content_hello_1'] = 'Buenos días ';
+$lang['nbm_content_hello_2'] = ',';
+$lang['nbm_content_new_elements'] = 'Los nuevos elementos han sido añadidos ';
+$lang['nbm_content_new_elements_single'] = ' el ';
+$lang['nbm_content_new_elements_between_1'] = 'entre él ';
+$lang['nbm_content_new_elements_between_2'] = ' y él ';
+$lang['nbm_content_subscribe_by_admin'] = 'Usted acaba de ser inscrito por el webmaster del sitio para recibir la notificación por mail.';
+$lang['nbm_content_subscribe_by_himself'] = 'Usted acaba de inscribirse para recibir la notificación por mail.';
+$lang['nbm_content_subscribe_link'] = 'Para inscribirse';
+$lang['nbm_content_problem_contact'] = 'En caso de problemas o en caso de cuestiones, enviar un mail a ';
+$lang['nbm_content_pb_contact_object'] = '[NBM] Problemas o de cuestiones';
+$lang['nbm_content_unsubscribe_by_admin'] = 'Usted acaba de ser désinscrit por el webmaster del sitio para recibir la notificación por mail.';
+$lang['nbm_content_unsubscribe_by_himself'] = 'Usted viene de usted désinscrire para recibir la notificación por mail.';
+$lang['nbm_content_click_on'] = ', Haga clic sobre ';
+$lang['nbm_content_unsubscribe_link'] = 'Para usted desinscribirse';
+$lang['nbm_info_send_mail_as'] = 'Sin valor, el título de la galería será utilizado';
+$lang['nbm_item_notification'] = 'Notificación';
+$lang['nbm_msg_error_sending_email_to'] = 'Error en el momento del envío del mail a %s [%s].';
+$lang['nbm_msg_mail_sent_to'] = 'Mail enviado a %s [%s].';
+$lang['nbm_msg_n_mail_sent'] = '%s mail ha sido enviado.';
+$lang['nbm_msg_n_mails_sent'] = '%s mails han sido enviados.';
+$lang['nbm_msg_n_mail_not_send'] = '%s mail no ha sido enviado.';
+$lang['nbm_msg_n_mails_not_send'] = '%s mails no han sido enviados.';
+$lang['nbm_no_mail_to_send'] = 'No de mail a enviar.';
+$lang['nbm_no_user_available_to_send_L1'] = 'No hay utilizador que notifica por mail.';
+$lang['nbm_no_user_available_to_send_L2'] = 'Un utilizador tiene que notificar si los nuevos elementos están disponibles para este utilizador.';
+$lang['nbm_no_user_available_to_send_L3'] = 'Puede así como él no tengo allí ningún utilizador inscrito (sólo el webmaster tiene acceso a este inglete).';
+$lang['nbm_no_user_to send_notifications_by_mail'] = 'Ningún utilizador para enviar notificaciones por mails.';
+$lang['nbm_object_news'] = 'Nuevos elementos añadidos';
+$lang['nbm_object_subscribe'] = 'Inscripción a la notificación por mail';
+$lang['nbm_object_unsubscribe'] = 'Désinscription a la notificación por mail';
+$lang['nbm_param_mode'] = 'Parametraje';
+$lang['nbm_redirect_msg'] = 'Tratamiento corriente.'."\n".'Por favor, espere...';
+$lang['nbm_repost_submit'] = 'Continuar el tratamiento corriente...';
+$lang['nbm_send_complementary_mail_content'] = 'Contenido complementario del mail';
+$lang['nbm_send_detailed_content'] = 'Añadido de un contenido detallado';
+$lang['nbm_send_mail_as'] = 'Enviar el mail como';
+$lang['nbm_send_mail_to_users'] = 'Envío de mail a los utilizadores';
+$lang['nbm_send_mode'] = 'Envío';
+$lang['nbm_send_options'] = 'Opciones';
+$lang['nbm_send_submit'] = 'Enviar';
+$lang['nbm_subscribe_col'] = 'Inscritos';
+$lang['nbm_subscribe_mode'] = 'Inscripción';
+$lang['nbm_title_param'] = 'Parámetros';
+$lang['nbm_title_send'] = 'Selección de los envíos';
+$lang['nbm_title_subscribe'] = 'Inscribir / desinscribir a los utilizadores';
+$lang['nbm_unsubscribe_col'] = 'Inscritos';
+$lang['nbm_updated_param_count'] = '%d parámetro ha sido puesto al día.';
+$lang['nbm_updated_params_count'] = '%d parámetros han sido puestos al día.';
+$lang['nbm_user_change_enabled_error_on_updated_data_count'] = '%d utilizador no ha sido puesto al día.';
+$lang['nbm_users_change_enabled_error_on_updated_data_count'] = '%d Utilizadores no han sido puestos al día.';
+$lang['nbm_user_change_enabled_false'] = 'El utilizador %s [%s] ha sido suprimido por la lista de los inscritos.';
+$lang['nbm_user_change_enabled_true'] = 'El utilizador %s [%s] ha sido añadido a la lista de los inscritos.';
+$lang['nbm_user_change_enabled_updated_data_count'] = '%d utilizador ha sido puesto al día.';
+$lang['nbm_users_change_enabled_updated_data_count'] = '%d utilizadores han sido puestos al día.';
+$lang['nbm_user_not_change_enabled_false'] = 'El utilizador %s [%s] no ha sido suprimido por la lista de los inscritos.';
+$lang['nbm_user_not_change_enabled_true'] = 'El utilizador %s [%s] no ha sido añadido a la lista de los inscritos.';
+$lang['nbm_user_x_added'] = 'Utilizador %s [%s] añadido.';
+$lang['nbm_warning_subscribe_unsubscribe'] = 'Cuidado, la inscripción o anaulación de inscripción lleve del envío de mails a los utilizadores concernidos';
+$lang['nbm_send_html_mail'] = 'Enviar el mail al tamaño HTML';
+$lang['nbm_send_recent_post_dates'] = 'Incluir la fijación de las últimas imágenes agrupadas por fechas';
+$lang['nbm_info_send_recent_post_dates'] = 'Disponible únicamente con tamaño HTML';
+$lang['no_write_access'] = 'ningún acceso en escritura';
+$lang['path'] = 'camino';
+$lang['permissions'] = 'Permisos';
+$lang['private'] = 'intimidad';
+$lang['properties'] = 'Propiedades';
+$lang['public'] = 'público';
+$lang['purge never used notification feeds'] = 'Purgar los flujos jamás utilizados de notificación';
+$lang['purge sessions'] = 'Purgar las sesiones';
+$lang['randomly represented'] = 'Representando al azar';
+$lang['registration_date'] = 'Data de registro';
+$lang['remote_site'] = 'Sitio distante';
+$lang['remote_site_clean'] = 'limpiar';
+$lang['remote_site_clean_hint'] = 'Suprimir el fichero listing.xml distante';
+$lang['remote_site_generate'] = 'generar el listado';
+$lang['remote_site_generate_hint'] = 'generar el fichero listing.xml sobre el sitio distante';
+$lang['remote_site_local_create'] = 'Crear este sitio';
+$lang['remote_site_local_found'] = 'Un fichero listing.xml local ha sido encontrado para ';
+$lang['remote_site_local_update'] = 'Leer el listing.xml local y poner al día';
+$lang['remote_site_test'] = 'testar';
+$lang['remote_site_test_hint'] = 'testar este sitio distante';
+$lang['remote_site_uncorrect_url'] = 'EL URL del sitio distante debe comenzar por "http " o "https" y debe contener carácteres sólo entre "/", " a- zA-Z0-9 ", "-" o "_"';
+$lang['remove tags'] = 'suprimir los tags';
+$lang['repair and optimize database'] = 'Reparar y optimizar la base de datos';
+$lang['selection'] = 'Selección';
+$lang['set to'] = 'Cambiarlo';
+$lang['singly represented'] = 'representante fijo';
+$lang['site_already_exists'] = 'Este sitio ya existe';
+$lang['site_create'] = 'Crear un nuevo sitio distante: (dar su URL hacia create_listing_file.php)';
+$lang['site_created'] = 'Creado';
+$lang['site_delete'] = 'suprimir';
+$lang['site_delete_hint'] = 'suprimir este sitio y todas las informaciones asociadas';
+$lang['site_deleted'] = 'suprimido';
+$lang['site_err'] = 'Un error sobrevino';
+$lang['site_err_remote_file_not_found'] = 'el fichero create_listing_file.php es imposible de encontrar sobre el sitio distante';
+$lang['site_local'] = 'Local';
+$lang['site_remote'] = 'Distante';
+$lang['site_synchronize'] = 'Sincronizar';
+$lang['site_synchronize_hint'] = 'pone al día la base de datos a partir de los ficheros';
+$lang['status'] = 'Estatuto';
+$lang['storage'] = 'Repertorio';
+$lang['sub-categories'] = 'subcategorías';
+$lang['synchronize metadata'] = 'Sincronizar los méta-datos';
+$lang['synchronize'] = 'sincronizar';
+$lang['target'] = 'blanco';
+$lang['thumbnail'] = 'miniatura';
+$lang['title'] = 'título';
+$lang['title_categories'] = 'Gestión de las categorías';
+$lang['title_configuration'] = 'Configuración de Piwigo';
+$lang['title_default'] = 'Administración de Piwigo';
+$lang['title_edit_cat'] = 'Modificar una categoría';
+$lang['title_groups'] = 'Gestión de los grupos';
+$lang['title_liste_users'] = 'Lista utilizadores';
+$lang['title_picmod'] = 'Modificar las informaciones de una imagen';
+$lang['title_thumbnails'] = 'Creación de las miniaturas';
+$lang['title_update'] = 'Sincronización de la base de datos a partir de los ficheros';
+$lang['title_upload'] = 'Imágenes en espera de validación';
+$lang['tn_all'] = 'todo';
+$lang['tn_alone_title'] = 'imagen sin miniatura (jpeg y png únicamente)';
+$lang['tn_err_height'] = 'La altura debe un entero superior a';
+$lang['tn_err_width'] = 'La anchura debe ser un entero superior a';
+$lang['tn_format'] = 'para el tamaño de fichero';
+$lang['tn_no_missing'] = 'Ninguna miniatura falta';
+$lang['tn_no_support'] = 'Imagen inaccesible o no sostenida';
+$lang['tn_params_GD'] = 'versión de GD';
+$lang['tn_params_title'] = 'Parámetro de miniaturización';
+$lang['tn_results_gen_time'] = 'generada de allí';
+$lang['tn_results_title'] = 'Los resultados de la miniaturización';
+$lang['tn_stats'] = 'Estadísticas generales';
+$lang['tn_stats_max'] = 'El tiempo máximo';
+$lang['tn_stats_mean'] = 'El tiempo medio';
+$lang['tn_stats_min'] = 'El tiempo mínimo';
+$lang['tn_stats_nb'] = 'número de miniaturas creadas';
+$lang['tn_stats_total'] = 'el tiempo total';
+$lang['tn_thisformat'] = 'para este tamaño de fichero';
+$lang['unit mode'] = 'modo unitario';
+$lang['unlocked'] = 'quitada el cierre';
+$lang['unset'] = 'Vaciar';
+$lang['up'] = 'Desplazar hacia arriba';
+$lang['update categories informations'] = 'Poner al día las informaciones de las categorías';
+$lang['update images informations'] = 'Poner al día las informaciones de las imágenes';
+$lang['update'] = 'Sincronizar';
+$lang['update_cats_subset'] = 'Únicamente tratar una categoría';
+$lang['update_default_title'] = 'Escoger una opción';
+$lang['update_display_info'] = 'Fijar un máximo de informaciones (categorías añadidas, elementos añadidos, categorías y elementos suprimidos)';
+$lang['update_err_pwg_version_differs'] = 'La versión Piwigo sobre el sitio distante es diferente';
+$lang['update_err_pwg_version_differs_info'] = 'La versión de create_listing_file.php sobre la sitio distante y Piwigo debe ser lo mismo';
+$lang['update_err_remote_listing_not_found'] = 'El fichero listing.xml es imposible de encontrar';
+$lang['update_err_remote_listing_not_found_info'] = 'el fichero listing.xml es imposible de encontrar sobre el sitio distante. Este fichero está generado escogiendo el encargo " generar el listado " en el gerente de sitios';
+$lang['update_error_list_title'] = 'Lista errores';
+$lang['update_errors_caption'] = 'Leyenda de los errores';
+$lang['update_infos_title'] = 'Informaciones detalladas';
+$lang['update_missing_file_or_dir'] = 'Error de abertura fichero / repertorio';
+$lang['update_missing_file_or_dir_info'] = 'El fichero o el repertorio no puede ser accesible (o sea no existe, o sea el acceso es negado)';
+$lang['update_missing_tn_info'] = 'Cada fichero lleno de imágenes requiere una miniatura. La miniatura debe estar presente en el subdirectorio " thumbnail " del repertorio de la categoría. El nombre del fichero de la miniatura debe comenzar con parámetro de configuración "prefix_thumbnail" y la extensión del nombre del fichero debe estar entre la lista siguiente:';
+$lang['update_missing_tn_short'] = 'falta la miniatura ';
+$lang['update_nb_del_categories'] = 'categorías suprimidas de la base de datos';
+$lang['update_nb_del_elements'] = 'Elementos suprimidos de la base de datos';
+$lang['update_nb_elements_metadata_available'] = 'Llena de imágenes a candidatas a la sincronización con los méta-datos';
+$lang['update_nb_elements_metadata_sync'] = 'Informaciones de las imágenes sincronizadas con los méta-datos';
+$lang['update_nb_errors'] = 'errores sobrevenidos durante la sincronización';
+$lang['update_nb_new_categories'] = 'categorías añadidas a la base de datos';
+$lang['update_nb_new_elements'] = 'elementos añadidos a la base de datos';
+$lang['update_nb_upd_elements'] = 'elementos puestos al día en la base de datos';
+$lang['update_part_research'] = 'Buscar las nuevas imágenes en los repertorios';
+$lang['update_research_added'] = 'añadido';
+$lang['update_research_deleted'] = 'suprimido';
+$lang['update_result_metadata'] = 'El resultado de la sincronización de los méta-datos';
+$lang['update_simulate'] = 'Únicamente simular (ningún cambio en la base de datos será efectuado)';
+$lang['update_simulation_title'] = '[Simulation]';
+$lang['update_sync_all'] = 'repertorios + ficheros';
+$lang['update_sync_dirs'] = 'repertorios únicamente';
+$lang['update_sync_files'] = 'sincronizar la estructura de los ficheros con la base de datos';
+$lang['update_sync_metadata'] = 'sincronizar las informaciones de los elementos en la base de datos a partir de los méta-datos de los ficheros';
+$lang['update_sync_metadata_all'] = 'hasta los elementos ya sincronizados';
+$lang['update_used_metadata'] = 'Méta-datos empleadas';
+$lang['update_wrong_dirname_info'] = 'El nombre de los repertorios y de los ficheros debe estar constituido sólo por letras, por cifras, de "-", "_" y "."';
+$lang['update_wrong_dirname_short'] = 'nombre de fichero erróneo';
+$lang['upload'] = 'Añadido';
+$lang['user "%s" added'] = 'utilizador "%s" añadido';
+$lang['user_status'] = 'Estatuto del utilizador';
+$lang['user_status_admin'] = 'Administrador';
+$lang['user_status_generic'] = 'Genérico';
+$lang['user_status_guest'] = 'Invitado';
+$lang['user_status_normal'] = 'Visitador';
+$lang['user_status_webmaster'] = 'Webmestre';
+$lang['username'] = 'nombre utilizador';
+$lang['users'] = 'Utilizadores';
+$lang['virtual_category'] = 'Categoría virtual';
+$lang['waiting'] = 'En espera';
+$lang['is_default_group'] = 'por defecto';
+$lang['toggle_is_default_group'] = 'Invertir la propiedad \'grupo por defecto\'';
+$lang['Advanced_features'] = 'Funciones avanzadas';
+$lang['Elements_not_linked'] = 'Elementos no atados';
+$lang['special_admin_menu'] = 'Especiales';
+$lang['Duplicates'] = 'Ficheros que llevan el mismo nombre en varias categorías físicas';
+$lang['Overall'] = 'Vista global';
+$lang['Year'] = 'Año';
+$lang['Month'] = 'Mes';
+$lang['Day'] = 'Día';
+$lang['Pages seen'] = 'Páginas vistas';
+$lang['Pictures'] = 'Imágenes';
+$lang['time'] = 'Hora';
+$lang['user'] = 'utilizador';
+$lang['IP'] = 'IP';
+$lang['image'] = 'Imágenes';
+$lang['section'] = 'sección';
+$lang['tags'] = 'tags';
+$lang['conf_history_guest'] = 'Registrar las páginas visitadas por los invitados';
+$lang['conf_history_user'] = 'Registrar las páginas visitadas por los utilizadores';
+$lang['conf_history_admin'] = 'Registrar las páginas visitadas por los administradores';
+$lang['cat_options_title'] = 'Propiedades';
+$lang['An information email was sent to group "%s"'] = 'Un mail de informaciones ha sido enviado a los miembros del grupo';
+$lang['Send an information email to group members'] = 'Enviarles un mail de informaciones a los miembros de un grupo';
+$lang['Group'] = 'Groupe';
+$lang['[%s] Come to visit the category %s'] = '[%s] Venga para visitar la categoría %s';
+$lang['Hello,'] = 'Buenos días,';
+$lang['See you soon.'] = 'Hasta pronto.';
+$lang['Come to discover the category:'] = 'Venga para descubrir la categoría:';
+$lang['mail_content'] = 'Contenido del mail';
+$lang['none'] = 'Ninguno';
+$lang['high'] = 'alto';
+$lang['other'] = 'Otro';
+$lang['Element type'] = "Tipo de elemento";
+$lang['User'] = 'Utilizador';
+$lang['Image id'] = 'Identificando imagen';
+$lang['Summary'] = 'Resumen';
+$lang['%d line filtered'] = '%d línea filtrada';
+$lang['%d lines filtered'] = '%d Líneas filtradas';
+$lang['%d guest'] = '%d invitado';
+$lang['%d guests'] = '%d Invitados';
+$lang['Hour'] = 'Hora';
+$lang['is_the_guest'] = 'Invitado';
+$lang['is_the_default'] = 'valores por defecto';
+$lang['High filesize'] = 'Talla del fichero HR';
+$lang['Guest cannot be deleted'] = 'No se puede suprimir el invitado';
+$lang['Default user cannot be deleted'] = 'No se puede suprimie al usuario por defecto';
+$lang['purge history detail'] = 'Vaciar el histórico';
+$lang['purge history summary'] = 'Vaciar el sumario del histórico';
+$lang['c13y_title'] = 'Control de integridad';
+$lang['c13y_Anomaly'] = 'Anomalía';
+$lang['c13y_Correction'] = 'Corrección';
+$lang['c13y_Automatic_correction'] = 'Corrección automática';
+$lang['c13y_Impossible_automatic_correction'] = 'Corrección automática imposible';
+$lang['c13y_Correction_applied_success'] = 'Corrección lograda';
+$lang['c13y_Correction_applied_error'] = 'Corrección erronea';
+$lang['c13y_anomaly_count'] = '%d anomalía ha sido detectada.';
+$lang['c13y_anomalies_count'] = '%d anomalías han sido detectadas.';
+$lang['c13y_anomaly_corrected_count'] = '%d anomalía ha sido corregida.';
+$lang['c13y_anomalies_corrected_count'] = '%d anomalías han sido corregidas.';
+$lang['c13y_anomaly_not_corrected_count'] = '%d anomalía no pudo ser corregida.';
+$lang['c13y_anomalies_not_corrected_count'] = '%d anomalías no pudieron ser corregidas.';
+$lang['c13y_more_info'] = 'Vaya sobre %s o %s para más informaciones';
+$lang['c13y_more_info_forum'] = 'El foro';
+$lang['c13y_more_info_wiki'] = 'El wiki';
+$lang['c13y_exif_anomaly'] = 'El valor de %s no es correcto porque el extejo no es sostenido';
+$lang['c13y_exif_correction'] = '%s debe ser puesto a "false" en su fichero config_local.inc.php';
+$lang['c13y_guest_non_existent'] = 'El utilizador "invitado" principal no existe más';
+$lang['c13y_bad_guest_status'] = 'El estatuto del utilizador "invitado" principal es incorrecto';
+$lang['c13y_default_non_existent'] = 'El utilizador por defecto no existe más';
+$lang['c13y_webmaster_non_existent'] = 'El utilizador " webmestre " principal no existe más';
+$lang['c13y_bad_webmaster_status'] = 'El estatuto del utilizador " webmestre " principal es incorrecto';
+$lang['c13y_user_created'] = 'Utilizador "%s" creado con como palabra de paso "%s"';
+$lang['c13y_user_status_updated'] = 'Estatuto del utilizador "%s" puesto al día';
+$lang['add new elements to caddie'] = 'añadir los nuevos elementos a la cesta';
+// --------- Starting below: New or revised $lang ---- from Butterfly (
+$lang['no_display_thumbnail'] = 'Ninguna fijación';
+$lang['display_thumbnail_classic'] = 'Fijación clásica';
+$lang['display_thumbnail_hoverbox'] = 'Fijación en el momento del sobrevuelo';
+$lang['Thumbnails'] = 'Miniaturas';
+$lang['obligatory_user_mail_address'] = 'La dirección mail es obligatoria para todos los utilizadores';
+$lang['Minimum privacy level'] = 'Nivel mínimo de carácter confidencial';
+$lang['Privacy level'] = 'Nivel de carácter confidencial';
+$lang['Level 0'] = '---';
+$lang['Level 1'] = 'Contactos';
+$lang['Level 2'] = 'Amigos';
+$lang['Level 4'] = 'Familia';
+$lang['Level 8'] = 'Admins';
+$lang['c13y_maintenance'] = 'Reinicializar los controles de integridad';
+$lang['Check all'] = 'Todo verificado';
+$lang['Uncheck all'] = 'Soltar todo';
+$lang['c13y_check_auto'] = 'Puntear las correcciones automáticas';
+$lang['c13y_submit_correction'] = 'Aplicar las correcciones seleccionadas';
+$lang['c13y_submit_ignore'] = 'Ignorar las anomalías seleccionadas';
+$lang['c13y_submit_refresh'] = 'Refrescar';
+$lang['c13y_ignore_msg1'] = 'La anomalía será ignorada hasta la versión próxima de la aplicación';
+$lang['c13y_ignore_msg2'] = 'La corrección de la anomalía anulará el hecho de que sea ignorada';
+$lang['c13y_anomaly_ignored_count'] = '%d anomalía ha sido ignorada.';
+$lang['c13y_anomalies_ignored_count'] = '%d anomalías han sido ignoradas.';
+$lang['plugins_need_update'] = 'Plugins que necesita una postura al día ';
+$lang['plugins_dontneed_update'] = 'Plugins al día';
+$lang['plugins_cant_check'] = 'Imposible verificar el plugins siguiente';
+$lang['plugins_actual_version'] = 'Versión<br>actual';
+$lang['plugins_new_version'] = 'Versión<br>disponible';
+$lang['plugins_auto_update'] = 'Puesta al día automático';
+$lang['plugins_auto_install'] = 'Instalación automática';
+$lang['plugins_download'] = 'Descargar el fichero';
+$lang['plugins_tab_list'] = 'Lista plugins';
+$lang['plugins_tab_update'] = 'Verificar las puestas al día';
+$lang['plugins_tab_new'] = 'Otro plugins disponible';
+$lang['plugins_revisions'] = 'Últimas revisiones';
+$lang['plugins_delete'] = 'Suprimir';
+$lang['plugins_confirm_install'] = '¿ Es seguro de querer instalar este plugin?';
+$lang['plugins_confirm_delete'] = '¿ Es seguro de querer suprimir este plugin?';
+$lang['plugins_confirm_upgrade'] = ' ¿ Es sobre querer instalar esta postura al día? Usted debe verifique que esta postura al día no necesita de désinstalación.';
+$lang['plugins_upgrade_ok'] = '%s ha sido puesto al día con éxito.';
+$lang['plugins_install_ok'] = 'El plugin ha sido copiado con éxito';
+$lang['plugins_install_need_activate'] = 'Cita en la lista del plugins para instalarlo y acelerarlo.';
+$lang['plugins_temp_path_error'] = 'Imposible crear un fichero temporal.';
+$lang['plugins_dl_archive_error'] = 'Imposible recuperar el archivo.';
+$lang['plugins_archive_error'] = 'Imposible leer o extraer el archivo.';
+$lang['plugins_extract_error'] = 'Un error sobrevino durante la extracción de los ficheros (%s).';
+$lang['plugins_check_chmod'] = 'Verifique los autorizaciones del expediente " plugins " y de sus subexpedientes (CHMOD).';
+$lang['plugins_server_error'] = 'Imposible conectarse al servidor.';
+$lang['Purge compiled templates'] = 'Purgar el templates compilado';
+$lang['Caddie is currently empty'] = 'La cesta actualmente está vacía';
+$lang['conf_upload_title'] = 'Descargar';
+$lang['Show upload link every time'] = 'Fijar el lazo de añadido de imagen todo el tiempo';
+$lang['User access level to upload'] = 'Nivel de acceso usuario para cargar';
+$lang['ACCESS_0'] = 'Acceso libre';
+$lang['ACCESS_1'] = 'Acceso todos';
+$lang['ACCESS_2'] = 'Acceso inscritos';
+$lang['ACCESS_3'] = 'Acceso administradores';
+$lang['ACCESS_4'] = 'Acceso webmestres';
+$lang['ACCESS_5'] = 'Ningún acceso';
+$lang['DEMO'] = 'Demo';
+$lang['HOME'] = 'Acogida Piwigo';
+$lang['FORUM'] = 'Ayuda';
+$lang['BUGS'] = 'Bugs';
+$lang['EXTENSIONS'] = 'Extensiones';
+$lang['WIKI / DOC'] = 'Documentación';
+$lang['A new version of Piwigo is available.'] = 'Una nueva versión de Piwigo está disponible.';
+$lang['Piwigo Administration'] = 'Administración de Piwigo';
+$lang['Piwigo version'] = 'Versión de Piwigo';
+$lang['You are running the latest version of Piwigo.'] = 'Usted utiliza la última versión de Piwigo.';
+$lang['c13y_version_anomaly'] = 'La versión de  %s [%s] instalada no es compatible con la versión requiseès [%s]';
+$lang['c13y_version_correction'] = 'Usted debe poner al día su sistema para sacar provecho plenamente de la aplicación si no la aplicación no funcionará correctamente, incluso en absoluto';
+$lang['Deleted on'] = 'Borrado';
+$lang['Last hit'] =  'Último acceso';
+$lang['Hits'] = 'Utilizaciones';
+$lang['GD library is missing'] = 'La biblioteca GD es faltante';
+$lang['conf_extents'] = 'Templates (Modelos)';
+$lang['extend_for_templates'] = 'Extender el templates';
+$lang['Replacement of original templates'] = 'Sustitución del templates de origen por su templates adaptados por el expediente  template-extension';
+$lang['Replacers'] = 'Los sustitutos (templates modificados)';
+$lang['Original templates'] = 'Templates de origen';
+$lang['Optional URL keyword'] = 'Parámetro facultativo del URL';
+$lang['Templates recorded.'] = 'La configuración del templates ha sido registrada.';
+$lang['Optimizations completed'] = 'Todas las optimizaciones han sido realizadas con éxito.';
+$lang['Optimizations errors'] = 'Ciertas optimizaciones se acabaron con errores.';
+$lang['delete this comment'] = 'Borrar este comentario';
+$lang['link_info_image'] = 'Modificar las informaciones';
+$lang['edit category informations'] = 'editar las informaciones de esta categoría';
+$lang['nothing'] = 'nada';
+$lang['overrides existing values with empty ones'] = 'Ignora valores existentes con vacíos';
+$lang['manage image ranks'] = 'Administrar la orden de las imágenes';
+$lang['Manage image ranks'] = 'Administrar la orden de las imágenes';
+$lang['Edit ranks'] = 'Modificar la orden';
+$lang['No element in this category'] = 'Ningún elemento en esta categoría';
+$lang['Images manual order was saved'] = 'La orden manual de las imágenes ha sido salvada';
+$lang['ranks'] = 'Filas';
+$lang['Drag to re-order'] = 'Hacer clic deslizar para reorganizar';
+$lang['Unable to retrieve server informations since allow_url_fopen is disabled.'] = 'Imposible conectarse en el server porque la función allow_url_fopen es desactivada.';
+$lang['Quick Local Synchronization'] = 'Sincronización Rápida';
+$lang['No photo can be deleted'] = 'Ninguna foto puede ser suprimida';
+$lang['Note: Only deletes photos added with pLoader'] = 'Nota: las únicas las fotos aumentadas vía pLoader pueden ser suprimidas';
+$lang['Delete selected photos'] = 'Suprimir las fotos';
+$lang['%d photo was deleted'] = '%d foto ha sido suprimida';
+$lang['%d photos were deleted'] = '%d fotos han sido suprimidas';
+$lang['Bound template'] = 'Template relacionado ';
+$lang['Downloads'] = 'Descargar';
+$lang['Released on'] = 'Añadido';
+$lang['Number of downloads'] = 'Número de descargar';
+?>
Index: /tags/2.0.2/language/es_ES/common.lang.php
===================================================================
--- /tags/2.0.2/language/es_ES/common.lang.php	(revision 3278)
+++ /tags/2.0.2/language/es_ES/common.lang.php	(revision 3278)
@@ -0,0 +1,369 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Langage informations
+$lang_info['language_name'] = 'Español';
+$lang_info['country'] = 'España';
+$lang_info['direction'] = 'ltr';
+$lang_info['code'] = 'es';
+$lang_info['zero_plural'] = false;
+
+$lang['%.2f (rated %d times, standard deviation = %.2f)'] = '%.2f (noté %d fois, écart type = %.2f)';
+$lang['%d Kb'] = '%d Ko';
+$lang['%d category updated'] = '%d Categoría actualizada';
+$lang['%d categories updated'] = '%d Actualización categorías';
+$lang['%d comment to validate'] = '%d Comentario usuario que hay que validar';
+$lang['%d comments to validate'] = '%d Validar comentarios del usuario';
+$lang['%d new comment'] = '%d Nuevo comentario usuario';
+$lang['%d new comments'] = '%d nuevos comentarios del usuario';
+$lang['%d comment'] = '%d Comentario';
+$lang['%d comments'] = '%d Comentarios';
+$lang['%d hit'] = 'Vista  %d Veces';
+$lang['%d hits'] = 'Vista  %d Veces';
+$lang['%d new element'] = '%d nuevo elemento';
+$lang['%d new elements'] = '%d nuevos Elementos';
+$lang['%d new user'] = '%d nuevo usuario';
+$lang['%d new users'] = '%d nuevos usuarios';
+$lang['%d waiting element'] = '%d elemento en espera';
+$lang['%d waiting elements'] = '%d elementos en espera';
+$lang['About'] = 'Acerca de';
+$lang['All tags must match'] = 'Todos los tags deben corresponder';
+$lang['All tags'] = 'Todos los tags';
+$lang['Any tag'] = 'Cualquier tag';
+$lang['At least one listed rule must be satisfied.'] = 'Por lo menos una regla enumerada debe ser correcta.';
+$lang['At least one tag must match'] = 'Por lo menos uno de los tags debe corresponder';
+$lang['Author'] = 'Autor';
+$lang['Average rate'] = 'Nota media';
+$lang['Categories'] = 'Categorías';
+$lang['Category'] = 'Categoría';
+$lang['Close this window'] = 'Cerrar la ventana';
+$lang['Complete RSS feed'] = 'Flujo RSS completo (imágenes, comentarios)';
+$lang['Confirm Password'] = 'Confirmar la contraseña';
+$lang['Connection settings'] = 'Parámetros de la conexión';
+$lang['Connection'] = 'Conexión';
+$lang['Contact webmaster'] = 'Contactar el webmastre';
+$lang['Create a new account'] = 'Crear una nueva cuenta';
+$lang['Created on'] = 'Creada el';
+$lang['Creation date'] = 'Fecha de creación';
+$lang['Current password is wrong'] = 'La contraseña actual es incorrecta';
+$lang['Dimensions'] = 'Dimensiones';
+$lang['Display'] = 'Monstrar';
+$lang['Each listed rule must be satisfied.'] = 'Cada regla mencionada debe ser correcta';
+$lang['Email address is missing'] = 'Falta su dirección electrónica';
+$lang['Email address'] = 'Dirección electrónica';
+$lang['Enter your personnal informations'] = 'Sus datos personales';
+$lang['Error sending email'] = 'Error de envío';
+$lang['File name'] = 'Nombre del fichero';
+$lang['File'] = 'Fichero';
+$lang['Filesize'] = 'Tamaño';
+$lang['Filter and display'] = 'Filtrar y mostrar';
+$lang['Filter'] = 'Filtro';
+$lang['Forgot your password?'] = 'Contraseña olvidada ?';
+$lang['Go through the gallery as a visitor'] = 'Recorrer la galería como visitante';
+$lang['Help'] = 'Ayuda';
+$lang['Identification'] = 'Identificación';
+$lang['Image only RSS feed'] = 'Flujo RSS de las imágenes';
+$lang['Keyword'] = 'Palabra clave';
+$lang['Links'] = 'Enlaces';
+$lang['Mail address'] = $lang['Email address'];
+$lang['N/A'] = 'no disponible';
+$lang['New on %s'] = 'Nuevo el %s';
+$lang['New password confirmation does not correspond'] = 'La nueva confirmación de la contraseña no corresponde';
+$lang['New password sent by email'] = 'Nueva contraseña enviada por correo electrónico';
+$lang['No email address'] = 'Ninguna dirección electrónica';
+$lang['No user matches this email address'] = 'Esta dirección electrónica no corresponde a ningún usuario';
+$lang['Notification'] = 'Notificación';
+$lang['Number of items'] = 'Número de artículos';
+$lang['Original dimensions'] = 'Dimensiones originales';
+$lang['Password forgotten'] = 'Contraseña olvidada';
+$lang['Password'] = 'Contraseña';
+$lang['Post date'] = 'Añadido el día';
+$lang['Posted on'] = 'Añadido el';
+$lang['Profile'] = 'Perfil';
+$lang['Quick connect'] = 'Conexión rápida';
+$lang['RSS feed'] = 'flux RSS';
+$lang['Rate'] = 'Nota';
+$lang['Register'] = 'Regístrese';
+$lang['Registration'] = 'Registro';
+$lang['Related tags'] = 'Tags relacionados';
+$lang['Reset'] = 'Anular';
+$lang['Retrieve password'] = 'Recuperar la contraseña';
+$lang['Search rules'] = 'Criterios de búsqueda';
+$lang['Search tags'] = 'Buscar tags';
+$lang['Search'] = 'Buscar';
+$lang['See available tags'] = 'Ver los tags disponibles';
+$lang['Send new password'] = 'Enviar una nueva contraseña';
+$lang['Since'] = 'Desde';
+$lang['Sort by'] = 'Clasificar según';
+$lang['Sort order'] = 'Orden de Clasificación';
+$lang['Tag'] = 'Tag';
+$lang['Tags'] = 'Tags';
+$lang['The RSS notification feed provides notification on news from this website : new pictures, updated categories, new comments. Use a RSS feed reader.'] = 'El flujo RSS notifica los eventos de la galería : nuevas imágenes, categorías actualizadas, nuevos comentarios del usuario. Lo debe utilizar con un lector de flujo RSS.';
+$lang['Unknown feed identifier'] = 'Identificador del flujo RSS desconocido';
+$lang['User comments'] = 'Comentarios del usuario';
+$lang['Username'] = 'Nombre del usuario';
+$lang['Visits'] = 'Visitas';
+$lang['Webmaster'] = 'Webmastre';
+$lang['Week %d'] = 'Semana %d';
+$lang['about_page_title'] = 'Acerca de Piwigo';
+$lang['access_forbiden'] = 'Usted no esta autorizado a ver la pagina pedida';
+$lang['add to caddie'] = 'Agregar al carrito';
+$lang['add_favorites_hint'] = 'agregar esta imagen en sus favoritos';
+$lang['admin'] = 'Administración';
+$lang['adviser_mode_enabled'] = 'Modo consejero activo';
+$lang['all'] = 'todo';
+$lang['ascending'] = 'ascendiente';
+$lang['author(s) : %s'] = 'autor(es) : %s';
+$lang['auto_expand'] = 'Desarrollar todas las categorías';
+$lang['became available after %s (%s)'] = 'puesto a disposición del %s (%s)';
+$lang['became available before %s (%s)'] = 'puesto a disposición después %s (%s)';
+$lang['became available between %s (%s) and %s (%s)'] = 'puesto a disposición entre él %s (%s) y el %s (%s)';
+$lang['became available on %s'] = 'disponible el %s';
+$lang['best_rated_cat'] = 'Mejores notas';
+$lang['best_rated_cat_hint'] = 'mostrar las imagenes con las mejores notas';
+$lang['caddie'] = 'Carrito';
+$lang['calendar'] = 'Calendario';
+$lang['calendar_any'] = 'Todo';
+$lang['calendar_hint'] = 'Mostrar año por año, mes por mes, día por día';
+$lang['calendar_picture_hint'] = 'Mostrar las imágenes desde ';
+$lang['calendar_view'] = 'Vista';
+$lang['chronology_monthly_calendar'] = 'Calendario mensual';
+$lang['chronology_monthly_list'] = 'Lista mensual';
+$lang['chronology_weekly_list'] = 'Lista semanal';
+$lang['click_to_redirect'] = 'Pulse aquí si su navegador no lo envía a la página requerida.';
+$lang['comment date'] = 'Fecha del comentario';
+$lang['comment'] = 'Comentario';
+$lang['comment_added'] = 'Su comentario ha sido inscripto';
+$lang['comment_anti-flood'] = 'Systema anti-abuso : gracias de esperar antes de agregar un nuevo comentario';
+$lang['comment_not_added'] = 'Su comentario no ha sido registrado porque no verifica las reglas de validación';
+$lang['comment_to_validate'] = 'El administrador debe activar su comentario para que sea visible.';
+$lang['comment_user_exists'] = 'Este nombre de usuario ya existe, pruebe otro';
+$lang['comments'] = 'Comentarios';
+$lang['comments_add'] = 'Agregar comentario';
+$lang['created after %s (%s)'] = 'Creado después del %s (%s)';
+$lang['created before %s (%s)'] = 'creado antes del %s (%s)';
+$lang['created between %s (%s) and %s (%s)'] = 'creado entre el %s (%s) y el %s (%s)';
+$lang['created on %s'] = 'creado el %s';
+$lang['customize'] = 'Personalizar';
+$lang['customize_page_title'] = 'Personalización de su pantalla ';
+$lang['day'][0] = 'Domingo';
+$lang['day'][1] = 'Lunes';
+$lang['day'][2] = 'Martes';
+$lang['day'][3] = 'Miércoles';
+$lang['day'][4] = 'Jueves';
+$lang['day'][5] = 'Viernes';
+$lang['day'][6] = 'Sábado';
+$lang['default_sort'] = 'Por defecto';
+$lang['del_favorites_hint'] = 'borrar esta imágen de sus favoritos';
+$lang['delete'] = 'Suprimir';
+$lang['descending'] = 'Descendiente';
+$lang['download'] = 'descargar';
+$lang['download_hint'] = 'descargar este fichero';
+$lang['edit'] = 'Editar';
+$lang['err_date'] = 'Fecha errónea';
+$lang['excluded'] = 'Excluidos';
+$lang['favorite_cat'] = 'Mis favoritos';
+$lang['favorite_cat_hint'] = 'Mostrar mis imágenes favoritas';
+$lang['favorites'] = 'Favoritas';
+$lang['first_page'] = 'Primera';
+$lang['gallery_locked_message'] = 'La galería esta en manutención. Vuelva más tarde.';
+$lang['generation_time'] = 'Página generada en';
+$lang['guest'] = 'Visitante';
+$lang['hello'] = 'Hola';
+$lang['hint_admin'] = 'disponible solamente para los administradores';
+$lang['hint_category'] = 'mostrar las imágenes a la raíces de esta categoría';
+$lang['hint_comments'] = 'Ver los últimos comentarios de los usuarios';
+$lang['hint_customize'] = 'personalizar aspecto de la galería';
+$lang['hint_search'] = 'Buscar';
+$lang['home'] = 'Inicio';
+$lang['identification'] = 'Identificación';
+$lang['images_available_cpl'] = 'en esta categoría';
+$lang['images_available_cat'] = 'en %d subcategoría';
+$lang['images_available_cats'] = 'en %d subcategorías';
+$lang['included'] = 'incluidos';
+$lang['invalid_pwd'] = 'Contraseña incorrecta !';
+$lang['language'] = 'Lengua';
+$lang['last %d days'] = '%d últimos días';
+$lang['last_page'] = 'Último';
+$lang['logout'] = 'Desconexión';
+$lang['mail_address'] = $lang['Email address'];
+$lang['mandatory'] = 'obligatorio';
+$lang['maxheight'] = 'Altura máxima de las imágenes';
+$lang['maxheight_error'] = 'La altura máxima de las imágenes no debe ser superiora 50';
+$lang['maxwidth'] = 'Ancho máximo de las imágenes';
+$lang['maxwidth_error'] = 'El ancho máximo de las imágenes no debe ser superior à 50';
+$lang['mode_created_hint'] = 'mostrar el calendario por fecha de creación';
+$lang['mode_flat_hint'] = 'Fijar a plato los elementos de las categorías y de las subcategorías';
+$lang['mode_normal_hint'] = 'vuelve a la vista normal';
+$lang['mode_posted_hint'] = 'mostrar el calendario por fecha de agregación';
+$lang['month'][10] = 'Octubre';
+$lang['month'][11] = 'Noviembre';
+$lang['month'][12] = 'Diciembre';
+$lang['month'][1] = 'Enero';
+$lang['month'][2] = 'Febrero';
+$lang['month'][3] = 'Marzo';
+$lang['month'][4] = 'Abril';
+$lang['month'][5] = 'Mayo';
+$lang['month'][6] = 'Junio';
+$lang['month'][7] = 'Julio';
+$lang['month'][8] = 'Agosto';
+$lang['month'][9] = 'Septiembre';
+$lang['most_visited_cat'] = 'Imágenes más vistas';
+$lang['most_visited_cat_hint'] = 'mostrar las imágenes más vistas';
+$lang['nb_image_line_error'] = 'La cantidad de imágenes por línea debe ser un número entero no nulo';
+$lang['nb_image_per_row'] = 'Cantidad de miniaturas por línea';
+$lang['nb_line_page_error'] = 'La cantidad de líneas por pagina debe ser un numero entero no nulo';
+$lang['nb_row_per_page'] = 'Cantidad de líneas por pagina';
+$lang['nbm_unknown_identifier'] = 'Usuario desconocido';
+$lang['new_password'] = 'Nueva contraseña';
+$lang['new_rate'] = 'Vote por esta imagen';
+$lang['next_page'] = 'Siguiente';
+$lang['no_category'] = 'Inicio';
+$lang['no_rate'] = 'sin nota';
+$lang['note_filter_day'] = 'El conjunto de los elementos es filtrado para fijar sólo los elementos recientes por lo menos de %d dia.';
+$lang['note_filter_days'] = 'El conjunto de los elementos es filtrado para fijar sólo los elementos recientes de menos de %d dias.';
+$lang['password updated'] = 'contraseña actualizada';
+$lang['periods_error'] = 'El período de novedad debe ser un numero entero positivo';
+$lang['picture'] = 'imagen';
+$lang['picture_high'] = 'Pulse sobre la imagen para ver en alta resolución';
+$lang['picture_show_metadata'] = 'Muestre los meta-datos del fichero';
+$lang['powered_by'] = 'Distribuido por';
+$lang['preferences'] = 'Preferencias';
+$lang['previous_page'] = 'Precedente';
+$lang['random_cat'] = 'Imágenes aleatorias';
+$lang['random_cat_hint'] = 'mostrar un grupo aleatorio de imágenes';
+$lang['recent_cats_cat'] = 'Últimas categorías';
+$lang['recent_cats_cat_hint'] = 'mostrar las categorías recientement actualizadas o creadas';
+$lang['recent_period'] = 'Período reciente';
+$lang['recent_pics_cat'] = 'Últimas imágenes';
+$lang['recent_pics_cat_hint'] = 'Mostrar las imágenes más recientes';
+$lang['redirect_msg'] = 'Redirección...';
+$lang['reg_err_login1'] = 'Por favor, ponga un nombre de usuario';
+$lang['reg_err_login2'] = 'el nombre de usuario no debe terminar por un espacio';
+$lang['reg_err_login3'] = 'el nombre de usuario no debe empezar por un espacio';
+$lang['reg_err_login5'] = 'Este nombre de usuario ya está utilizado';
+$lang['reg_err_mail_address'] = 'Su dirección electrónica debe ser del formato xxx@yyy.eee (ejemplo : jack@altern.org)';
+$lang['reg_err_pass'] = 'Por favor, escriba nuevamente su contraseña';
+$lang['remember_me'] = 'Conexión automática';
+$lang['remove this tag'] = 'quitar este tag de la lista';
+$lang['representative'] = 'representante';
+$lang['return to homepage'] = 'Volver a la página de inicio';
+$lang['search_author'] = 'Buscar por autor';
+$lang['search_categories'] = 'Buscar bajo categorías';
+$lang['search_date'] = 'Buscar por fecha';
+$lang['search_date_from'] = 'Fecha';
+$lang['search_date_to'] = 'Hasta la fecha';
+$lang['search_date_type'] = 'Tipo de fecha';
+$lang['search_keywords'] = 'Buscar por palabra';
+$lang['search_mode_and'] = 'Buscar todas las palabras';
+$lang['search_mode_or'] = 'Buscar una de las palabras';
+$lang['search_one_clause_at_least'] = 'Demanda vacía. Ningún criterio surtido..';
+$lang['search_options'] = 'Opciones de búsqueda';
+$lang['search_result'] = 'Resultados de la búsqueda';
+$lang['search_subcats_included'] = 'Buscar en las subcategorías';
+$lang['search_title'] = 'Búsqueda';
+$lang['searched words : %s'] = 'buscar palabras : %s';
+$lang['send_mail'] = 'Contactar';
+$lang['set as category representative'] = 'elegir como representante de esta categoría';
+$lang['show_nb_comments'] = 'Mostrar la cantidad de comentarios';
+$lang['show_nb_hits'] = 'Mostrar el número de visualizaciones';
+$lang['slideshow'] = 'diaporama';
+$lang['slideshow_stop'] = 'parar el diaporama';
+$lang['special_categories'] = 'Herramientas';
+$lang['sql_queries_in'] = 'pedidos SQL en';
+$lang['start_filter_hint'] = 'Fijar sólo los elementos recientes';
+$lang['stop_filter_hint'] = 'Regresar a la fijación de todos los elementos';
+$lang['the beginning'] = 'el principio';
+$lang['theme'] = 'Tema';
+$lang['thumbnails'] = 'Miniaturas';
+$lang['title_menu'] = 'Menú';
+$lang['title_send_mail'] = 'Una opinión sobre esta pagina';
+$lang['today'] = 'hoy';
+$lang['update_rate'] = 'Actualizar nota';
+$lang['update_wrong_dirname'] = 'Mal nombre de repertorio';
+$lang['upload_advise_filesize'] = 'El peso de la imagen debe sobrepasar : ';
+$lang['upload_advise_filetype'] = 'El tamaño de la imagen debe ser jpg, png ou gif';
+$lang['upload_advise_height'] = 'La altura de la imagen no debe sobrepasar : ';
+$lang['upload_advise_thumbnail'] = 'Opcional, pero recomendado: escoger una miniatura que hay que asociar ';
+$lang['upload_advise_width'] = 'La anchura de la imagen no debe sobrepasar : ';
+$lang['upload_author'] = 'Autor';
+$lang['upload_cannot_upload'] = 'Imposible trasladar el fichero sobre el camarero(servidor)';
+$lang['upload_err_username'] = 'Falta el nombre de usuario';
+$lang['upload_file_exists'] = 'este fichero ya existe';
+$lang['upload_filenotfound'] = 'el formato del fichero no es valido';
+$lang['upload_forbidden'] = 'imposible de agregar la imagen en esta categoría';
+$lang['upload_name'] = 'Nombre de la imagen';
+$lang['upload_picture'] = 'Agregar una imagen';
+$lang['upload_successful'] = 'Imagen agregada , un administrador la debe controlar para que esta sea visible';
+$lang['upload_title'] = 'Agregar una imagen';
+$lang['useful when password forgotten'] = 'Útil en caso de perdida de contraseña';
+$lang['qsearch'] = 'Búsqueda rápida';
+$lang['Connected user: %s'] = 'Utilizador conectado: %s';
+$lang['IP: %s'] = 'IP: %s';
+$lang['Browser: %s'] = 'Navegante: %s';
+$lang['Author: %s'] = 'Autor: %s';
+$lang['Comment: %s'] = 'Comentario: %s';
+$lang['Delete: %s'] = 'Supresión: %s';
+$lang['Validate: %s'] = 'Validación: %s';
+$lang['Comment by %s'] = 'Comentario por %s';
+$lang['User: %s'] = 'Utilizador: %s';
+$lang['Email: %s'] = 'Email: %s';
+$lang['Admin: %s'] = 'Administración: %s';
+$lang['Registration of %s'] = 'Registro de %s';
+$lang['Category: %s'] = 'Categoría: %s';
+$lang['Picture name: %s'] = 'Nombre de la imagen: %s';
+$lang['Creation date: %s'] = 'Data de creación: %d';
+$lang['Waiting page: %s'] = 'Página en espera: %s';
+$lang['Picture uploaded by %s'] = 'Imagen cargada por %s';
+// --------- Starting below: New or revised $lang ---- from version 1.7.1
+$lang['guest_must_be_guest'] = 'Estatuto del utilizador " guest " no conforme, la utilización del estatuto por defecto. Por favor, prevenga el webmestre.';
+// --------- Starting below: New or revised $lang ---- from Butterfly (2.0)
+$lang['Administrator, webmaster and special user cannot use this method'] = 'Administrador, webmestre y utilizador especial no pueden utilizar este método';
+$lang['reg_err_mail_address_dbl'] = 'Un utilizador ya utiliza esta dirección e-mail';
+$lang['Category results for'] = 'Los resultados de las categorías para';
+$lang['Tag results for'] = 'Los resultados de los tags para';
+$lang['from %s to %s'] = 'de %s a %s';
+$lang['start_play'] = 'Lectura del diaporama';
+$lang['stop_play'] = 'Pausa del diaporama';
+$lang['start_repeat'] = 'Repetir el diaporama';
+$lang['stop_repeat'] = 'No repetir el diaporama ';
+$lang['inc_period'] = 'Disminuir la velocidad del diaporama';
+$lang['dec_period'] = 'Acelerar la velocidad del diaporama';
+$lang['Submit'] = 'Validar';
+$lang['Yes'] = 'Si';
+$lang['No'] = 'No';
+$lang['%d element']='%d imágen';
+$lang['%d elements']='%d imágenes';
+$lang['%d element are also linked to current tags'] = '%d imagen es también vinculada a los tags corrientes';
+$lang['%d elements are also linked to current tags'] = '%d imagenes son igualmente vinculadas a los tags corrientes';
+$lang['See elements linked to this tag only'] = 'Ver las imágenes relacionadas únicamente a este tag';
+$lang['elements posted during the last %d days'] = 'esta imagen tiene menos de %d dias';
+$lang['Choose an image'] = 'Elegir una imagen';
+$lang['Piwigo Help'] = 'Ayuda de Piwigo';
+$lang['Rank'] = 'Fila';
+$lang['group by letters'] = 'Reagrupar por letras';
+$lang['letters'] = 'letras';
+$lang['show tag cloud'] = 'mostrar la nube de tags';
+$lang['cloud'] = 'nube';
+
+?>
Index: /tags/2.0.2/language/es_ES/help.html
===================================================================
--- /tags/2.0.2/language/es_ES/help.html	(revision 3278)
+++ /tags/2.0.2/language/es_ES/help.html	(revision 3278)
@@ -0,0 +1,296 @@
+<div class="instructions">
+<h2>Ayudante</h2>
+
+<div id="instructionPLoader" class="instructionBlock">
+  <div
+    id="pLoader_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('pLoader_header', 'pLoader_content')"
+  ><span>
+    Añadir fotos con pLoader
+  </span></div>
+  <div
+    id="pLoader_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+    <p><a href="http://piwigo.org/ext/extension_view.php?eid=270">pLoader para Windows</a> o <a href="http://piwigo.org/ext/extension_view.php?eid=269">pLoader para Linux</a> : descripción, cargamiento y detalles de nuevas revisiones.</p>
+    <ol>
+      <li>Cree un repertorio " upload " al lado del repertorio " galleries " sobre su instalación de Piwigo, con un acceso en escritura.</li>
+      <li>Instale pLoader sobre su ordenador, Arranque y cumpla los parámetros de conexión : URL de su galería, su nombre de usuario y su contraseña.</li>
+      <li>Añada fotos en la selección por resbalar / depositar desde su navegador de ficheros.</li>
+      <li>Cree una categoría y seleccione.</li>
+      <li>Seleccione fotos.</li>
+      <li>Haga clic en el flêche verde para cargar las fotos en su galería.</li>
+    </ol>
+    <p>¡ Bravo! Usted creó con éxito la primera categoría de su galería.</p>
+  </div> <!-- pLoader_content -->
+</div> <!-- instructionPLoader -->
+
+<div id="instructionFTP" class="instructionBlock">
+  <div
+    id="FTP_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('FTP_header', 'FTP_content')"
+  ><span>
+    Añadir fotos por FTP
+  </span></div>
+  <div
+    id="FTP_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+
+<h3>Comienzo rápido</h3>
+
+<ol>
+  <li>Cree un repertorio sobre su ordenador.</li>
+
+  <li>Copie fotos dentro de este repertorio, luego redimensione para una fijación sobre web. <em>Atención</em> : El nombre de los repertorios y de los ficheros debe contener sólo letras, cifras y los carácteres  "-", "_" y ".". Ningún espacio o de carácteres acentuados.</li>
+
+  <li>Con un cliente FTP, copie el repertorio en el repertorio " galleries " de su instalación de Piwigo.</li>
+
+  <li>Conecte usted a su instalación de Piwigo y rinde usted sobre <span class="pwgScreen">Administración &raquo; Imágenes &raquo; Miniaturas</span> para crear las miniaturas faltantes.</li>
+
+  <li>Rinda usted sobre <span class="pwgScreen">Administración</span> y haga clic en el grueso botón de sincronización.</li>
+</ol>
+
+<p>¡ Bravo! Usted creó con éxito la primera categoría de su galería.</p>
+
+<h3>Organización de los repertorios y de los ficheros</h3>
+
+<ul>
+
+  <li>
+
+    <p>Los repertorios que representan las categorías están en el repertorio " galleries ". Más abajo el árbol de los repertorios de una galería muy pequeña (pero utilizando numerosos carácteres funcionales): </p>
+  
+<pre>
+.
+|-- admin
+|-- doc
+|-- galleries
+|   |-- categoría-1
+|   |   |-- categoría-1.1
+|   |   |   |-- categoría-1.1.1
+|   |   |   |   |-- categoría-1.1.1.1
+|   |   |   |   |   |-- pwg_high
+|   |   |   |   |   |   +-- mariage.jpg
+|   |   |   |   |   |-- thumbnail
+|   |   |   |   |   |   +-- TN-mariage.jpg
+|   |   |   |   |   +-- mariage.jpg
+|   |   |   |   +-- categoría-1.1.1.2
+|   |   |   +-- categoría-1.1.2
+|   |   |-- categoría-1.2
+|   |   |   |-- pookie.jpg
+|   |   |   +-- thumbnail
+|   |   |       +-- TN-pookie.jpg
+|   |   +-- categoría-1.3
+|   +-- categoría-2
+|       |-- porcinet.gif
+|       |-- pwg_representative
+|       |   +-- video.jpg
+|       |-- thumbnail
+|       |   +-- TN-porcinet.jpg
+|       +-- video.avi
+|-- include
+|-- install
+|-- language
+|-- template
++-- tool</pre>
+
+  </li>
+  
+  <li>Fundamentalmente, una categoría es representada por un repertorio a cualquier nivel bajo el repertorio " galleries " de su instalación de Piwigo. Cada categoría puede contener tantos subniveles como deseado. En el ejemplo más arriba, categoría-1.1.1.1 está en un nivel 4 de profundidad.</li>
+
+  <li>Fundamentalmente, un elemento es representado por un fichero. Un fichero puede ser un elemento para Piwigo si la extensión del nombre del fichero está entre la lista del parámetro de configuración <code>file_ext</code> (Ver 
+  fichero <span class="filename">include/config.inc.php</span>). Un fichero puede ser una imagen si su extensión está entre el parámetro de configuración
+<code>picture_ext</code>.</li>
+
+  <li>Los elementos de tipo llena de imágenes deben tener una miniatura asociada (ver la sección siguiente a propósito de las miniaturas).</li>
+
+  <li>Los elementos de tipo llena de imágenes pueden tener uno llena de imágenes en gran tamaño asociado. Así como para el fichero <span class="filename">mariage.jpg</span>
+En el ejemplo más arriba. Ningún prefijo es necesario sobre el nombre del fichero.</li>
+
+  <li>Los elementos no imagen (vídeos, sonidos, archivos de texto, todo lo que usted quiere) por defecto han representado por icono que corresponde a la extensión del nombre del fichero. Optionnellement, una miniatura y un representante pueden ser asociados (ver el fichero <span
+class="filename">video.avi</span> en el ejemplo).</li>
+
+  <li><em>Atención</em> : El nombre de un repertorio o de un fichero debe ser constado sólo por cartas(letras), por cifras, de "-", "_" o ".". Ningún espacio o de carácteres acentuados.</li>
+
+  <li><em>Consejo</em> : Una categoría puede contener elementos y subcategorías a la vez. Sin embargo, es fuertemente aconsejado para cada categoría escoger contener elementos <strong>Entonces</strong>
+Subcategorías.</li>
+
+  <li>En cuanto los ficheros, las miniaturas y los representantes están correctamente colocados en los repertorios, ir(rendirse) sobre la pantalla <span
+class="pwgScreen">Administración &raquo; Categorías &raquo; Sincronizar</span>.</li>
+
+</ul>
+
+<h3>Miniaturas</h3>
+
+<ul>
+  
+  <li>Así como mencionado anteriormente, cada elemento de tipo llena de imágenes debe ser asociado con una miniatura.</li>
+
+  <li>Las miniaturas son almacenadas en el subdirectorio " thumbnail " de cada repertorio que representa una categoría. Una miniatura es un fichero de tipo llena de imágenes (la misma extensión del nombre del fichero) cuyo nombre de fichero es prefijado por el parámetro de configuración <code>prefix_thumbnail</code>
+(ver <span class="filename">include/config.inc.php</span>).</li>
+
+  <li>Las miniaturas no necesitan tener la misma extensión que les llena de imágenes asociada (una imagen con ".jpg" como extensión puede tener una miniatura .GIF " por ejemplo).</li>
+
+  <li>Es aconsejado utilizar un instrumento(utensilio) externo para la creación de las miniaturas</li>
+
+  <li>Usted también puede utilizar el instrumento(utensilio) de creación de miniatura integrado en Piwigo pero esto es desaconsejado porque la calidad corre peligro de ser decepcionante y esto utiliza inútilmente los recursos del camarero(servidor) (lo que puede ser un problema grave sobre un camarero(servidor) mutualisé).</li>
+
+  <li>Si usted escoge utilizar al servidor web para generar las miniaturas, usted debe dar los derechos en escritura a los repertorios.</li>
+
+</ul>
+
+  </div> <!-- FTP_content -->
+</div> <!-- instructionFTP -->
+
+<div id="instructionPermissions" class="instructionBlock">
+  <div
+    id="permissions_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('permissions_header', 'permissions_content')"
+  ><span>
+    Permisos
+  </span></div>
+  <div
+    id="permissions_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+
+<ul>
+
+  <li>Usted puede prohibir el acceso a las categorías. Pase el tipo de acceso a "intimidad" si usted desea administrar los permisos</li>
+  
+  <li>Usted puede devolver una categoría particular editándolo (<span
+class="pwgScreen">Administración &raquo; Categorías &raquo; Administrar &raquo; Editar</span>) O en gerente las opciones para su árbol completo de las categorías (<span
+class="pwgScreen">Administración &raquo; Categorías &raquo; Propiedades &raquo; Pública / particular</span>).</li>
+
+  <li>
+    <p>En cuanto ciertas categorías son privadas, usted puede administrar los permisos con 3 pantallas:</p>
+    <ul>
+      <li><span class="pwgScreen">Administración &raquo; Identificación &raquo; Utilizadores &raquo; Acciones Permisos</span> (1 lazo por usuario)</li>
+      <li><span class="pwgScreen">Administración &raquo; Identificación &raquo; Grupos &raquo; Acciones Permisos</span> (1 lazo por grupo)</li>
+      <li><span class="pwgScreen">Administración &raquo; Categorías &raquo; Administrar &raquo; Modificar los permisos</span> (1 lazo por categoría)</li>
+    </ul>
+
+  </li>
+</ul>
+
+  </div> <!-- permissions_content --> 
+</div> <!-- instructionPermissions -->
+
+<div id="instructionGroups" class="instructionBlock">
+  <div
+    id="groups_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('groups_header', 'groups_content')"
+  ><span>
+    Grupos de utilizadores
+  </span></div>
+  <div
+    id="groups_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+
+<ul>
+
+  <li>Los grupos de usuarios permiten asignar permisos a una lista de usuarios.</li>
+
+  <li>Usted puede crear grupos y añadir a eso a utilizadores en ello
+<span class="pwgScreen">Administración &raquo; Identificación &raquo; Grupos</span>.</li>
+
+  <li>Un utilizador puede pertenecer a varios grupos. La autorización es más fuerte que la interdicción: si el utilizador "piedra" pertenece a los grupos "familia" y "los amigos", y si sólo el grupo "familia" puede visitar la categoría " Navidad 2003 ", entonces "piedra" puede visitar esta categoría.</li>
+  
+</ul>
+
+  </div> <!-- groups_content --> 
+</div> <!-- instructionGroups -->
+
+<div id="instructionUpload" class="instructionBlock">
+  <div
+    id="upload_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('upload_header', 'upload_content')"
+  ><span>
+    Añadido de ficheros por los utilizadores
+  </span></div>
+  <div
+    id="upload_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+<p>Sus usuarios también pueden añadir sus fotos.</p>
+
+<ol>
+
+  <li>Autorice el añadido de imágenes sobre una o varias categorías (<span
+class="pwgScreen">Administation &raquo; Categorías &raquo; Gestión &raquo; Edicto</span> ou <span
+class="pwgScreen">Administración &raquo; Categorías &raquo; Propiedades &raquo; Añadido de imágenes</span>). Las categorías virtuales no permiten el añadido de imágenes.</li>
+
+  <li>Dar los derechos en escritura (para todos los utilizadores) a los repertorios que corresponden a las categorías que son autorizadas al añadido.</li>
+</ol>
+<p>Las fotos añadidas por los usuarios no son directamente visibles sobre el sitio,
+ Deben ser validados por un administrador.
+ Para eso, un administrador debe ir en <span class="pwgScreen">Administración &raquo; Imágenes &raquo; En espera  &raquo; Imágenes</span> con el fin de aceptar o de rechazar las fotos propuestas.</p>
+
+  </div> <!-- upload_content --> 
+</div> <!-- instructionUpload -->
+
+<div id="instructionCategoryLinks" class="instructionBlock">
+  <div
+    id="categoryLinks_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('categoryLinks_header', 'categoryLinks_content')"
+  ><span>
+    Lazos entre los elementos y las categorías, las categorías virtuales
+  </span></div>
+  <div
+    id="categoryLinks_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+
+<ul>
+
+  <li>Las fotos son fijadas en las categorías que corresponden a los repertorios.</li>
+
+  <li>Usted también puede fijar una foto en varias categorías, sin duplicar el fichero sobre su servidor web. Asocie la foto con cualquier otra categoría desde la pantalla de edición de la foto (al cual accederle desde la página de visualización de la foto lado galería, cuando eres conectado como administrador)</li>
+
+  <li>Las categorías virtuales parten de este principio : no tienen repertorio asociado. Cree categorías virtuales después <span class="pwgScreen">Administración &raquo; Categorías  &raquo; Administrar</span>.</li>
+
+</ul>
+
+  </div> <!-- categoryLinks_content --> 
+</div> <!-- instructionCategoryLinks -->
+
+<div id="instructionMisc" class="instructionBlock">
+  <div
+    id="misc_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('misc_header', 'misc_content')"
+  ><span>
+    Informaciones diversas
+  </span></div>
+  <div
+    id="misc_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+<ul>
+  
+  <li>Una vez creado su galería, configure la fijación por defecto tal como deseado en
+  <span class="pwgScreen">Administración &raquo; Configuración &raquo; Fijación por defecto</span>. En efecto, cada nuevo utilizador heredará de estas propiedades de fijación.</li>
+
+  <li>Totalmente para cuestión, la comunidad Piwigo está en la escucha sobre el <a href="http://piwigo.org/forum">foro</a>.</li>
+
+</ul>
+ 
+  </div> <!-- misc_content --> 
+</div> <!-- instructionMisc -->
+
+</div>
Index: /tags/2.0.2/language/es_ES/help/advanced_feature.html
===================================================================
--- /tags/2.0.2/language/es_ES/help/advanced_feature.html	(revision 3278)
+++ /tags/2.0.2/language/es_ES/help/advanced_feature.html	(revision 3278)
@@ -0,0 +1,16 @@
+<h2>Funciones avanzadas</h2>
+
+<p>Lista carácteres funcionales especiales para los administradores expertos de PWG:</p>
+
+<ul>
+
+  <li>
+    <strong>Elementos no atados :</strong>
+    Fija las imágenes que no son asociadas con una categoría virtual
+  </li>
+  <li>
+    <strong>Ficheros que llevan el mismo nombre en varias categorías físicas :</strong>
+    Fija las imágenes o los ficheros eventuales que podrían estar encontrados en varias categorías.
+  </li>
+
+</ul>
Index: /tags/2.0.2/language/es_ES/help/cat_modify.html
===================================================================
--- /tags/2.0.2/language/es_ES/help/cat_modify.html	(revision 3278)
+++ /tags/2.0.2/language/es_ES/help/cat_modify.html	(revision 3278)
@@ -0,0 +1,117 @@
+<h2>Modificar una categoría</h2>
+
+<h3>Informaciones</h3>
+
+<ul>
+
+  <li><strong>nombre</strong>: renombrar la categoría (virtualmente para una categoría física).</li>
+
+  <li><strong>descripción</strong>: dar una idea del contenido de la categoría, esta indicación figurará bajo la página de las miniaturas.</li>
+
+</ul>
+
+<h3>Desplazar</h3>
+
+<p>Si la categoría es virtual, usted puede desplazarlo. Desplazar una categoría significa cambiar su categoría allegada.</p>
+
+<h3>Opciones</h3>
+
+<ul>
+
+  <li><strong>Tipo de acceso</strong>: gestión de los permisos. Si usted devuelve una categoría particular, todas sus categorías chicas se vuelven particulares. Si usted devuelve una categoría pública, todas sus categorías madres se vuelven públicas.</li>
+
+  <li><strong>Encerrar</strong>: la categoría y todas sus categorías chicas se vuelven temporalmente inaccesibles para mantenimiento.</li>
+
+  <li><strong>Comentarios</strong>: autoriza a los utilizadores a comentar los elementos de esta categoría.</li>
+
+  <li><strong>Autorizar el añadido de imágenes</strong>: autoriza a los utilizadores a cargar ficheros. Esta opción está disponible sólo si la categoría es física (y no virtual).</li>
+
+</ul>
+
+<p>Usted puede también administrar estas opciones por la gestión de las "Propiedades"  
+(pantallas <span class="pwgScreen">Añadido</span>, <span
+class="pwgScreen">Comentarios</span>, <span
+class="pwgScreen">Encerrar</span>, <span
+class="pwgScreen">Pública / particular</span>, <span
+class="pwgScreen">Representante</span> Disponibles a partir de <span
+class="pwgScreen">Administración, Categorías, Propiedades</span>).</p>
+
+<h3>Orden de selección</h3>
+
+<p>Utilizar la orden de selección de las imágenes por defecto.</p>
+
+<p>Indicar si la selección también se aplica las subcategorías.</p>
+
+<p>Seleccionar las columnas de la selección que hay que utilizar para esta categoría.</p>
+<ul>
+<li><strong>Data de creación</strong>: data de grabación</li>
+<li><strong>Data de añadido</strong>: data de la sincronización</li>
+<li><strong>Nota media (*)</strong>: la cual logra por mediación podría ser modificada por el visitador</li>
+<li><strong>Más vistas (*)</strong>: La visita corriente puede cambiar la orden de los más vistos</li>
+<li><strong>Nombre del fichero</strong>: Nombre del fichero dado en los campos de informaciones más arriba</li>
+<li><strong>Id</strong>: Id Interna (las categorías recientes tienen la una "Id" más grande que las precedentes).</li>
+
+</ul>
+<p><strong>(*)</strong>Atención: usted hasta somete a un test estas selecciones que pueden dar los resultados imprevisibles.</p>
+
+
+<h3>Representante</h3>
+
+<p>El representante de una categoría es la miniatura fijada para representar la categoría sobre la página principal (<span
+class="pwgScreen">category.php</span>) Cuando una categoría únicamente contiene subcategorías y ningunos elementos directos (como a la raíz)</p>
+
+<p>Existen 4 medios de escoger al representante de una categoría:</p>
+
+<ul>
+
+  <li><span class="pwgScreen">Página de fijación de las imágenes</span>: En la barra de los botones de acción, uno de ellos permite escoger el elemento fijado como representante de la categoría fijada. Este botón de acción está disponible sólo para los administradores</li>
+
+  <li><span class="pwgScreen">Modificar las informaciones de una imagen</span>
+en la administración. Esta pantalla puede padecer después <span
+class="pwgScreen">picture.php</span> o <span class="pwgScreen">Gestión por lote</span> en él <em>Modo unitario</em>. Ver el ayudante de esta pantalla para los detalles.</li>
+
+  <li><span class="pwgScreen">Administración, Categorías, Propiedades, Representante</span>. Ver el ayudante de esta pantalla para los detalles.</li>
+
+  <li><span class="pwgScreen">Modificar una categoría</span> ( La pantalla presente).</li>
+
+</ul>
+
+<p>La representación depende del parámetro de configuración
+<code>allow_random_representative</code> (ver <span
+class="filename">include/config_default.inc.php</span>).</p>
+
+<p>Por defecto (<code>allow_random_representative</code> à false) cada categoría que contiene por lo menos un elemento es representada por un elemento fijo. Una vez fijado (a la creación de la categoría), el representante únicamente cambia cuando el administrador lo pide. Si el representante no conviene, usted puede pedir a <strong>Encontrar a un nuevo representante al azar</strong>.</p>
+
+<p>Si el parámetro de configuración <code>allow_random_representative</code>
+es a true, una categoría que contiene elementos puede no tener representante fijo. Simplemente utilizar el botón <strong>Suprimir al representante</strong>.</p>
+
+<p>Si la categoría no contiene ningún elemento (sino únicamente subcategorías) puede ser representada a pesar de todo por cualquier elemento gracias a la pantalla <span class="pwgScreen">Modificar las informaciones de una imagen</span>. La sola opción de la pantalla presente es el botón
+<strong>Suprimir al representante</strong>.</p>
+
+<h3>Asociar todos los elementos de la categoría con una nueva categoría</h3>
+
+<ul>
+
+<li><strong>Nombre de la categoría virtual</strong>: Nombre de la nueva categoría que hay que crear, todas las imágenes de la categoría corriente serán atadas a la noticia.</li>
+
+<li><strong>Categoría allegada</strong>: Donde la nueva categoría debe estar, dejar vacío para crearle sobre la página inicial.</li>
+
+</ul>
+
+<h3>Asociar todos los elementos de la categoría con categorías existentes</h3>
+
+<ul>
+
+<li><strong>Categorías</strong>: Escoger la categoría de destino.</li>
+
+</ul>
+
+<h3>Enviarles un mail de informaciones a los miembros de un grupo</h3>
+
+<ul>
+
+<li><strong>Grupo</strong>: Grupo de destinatarios</li>
+
+<li><strong>Contenido del mail</strong>: Texto libre de enviarles.</li>
+
+</ul>  
Index: /tags/2.0.2/language/es_ES/help/cat_move.html
===================================================================
--- /tags/2.0.2/language/es_ES/help/cat_move.html	(revision 3278)
+++ /tags/2.0.2/language/es_ES/help/cat_move.html	(revision 3278)
@@ -0,0 +1,12 @@
+<h2>Desplazamiento de categorías virtuales</h2>
+
+<p>Usted puede cambiar al pariente de una categoría virtual.</p>
+
+<h3>Categorías virtuales que hay que desplazar</h3>
+
+<p>Seleccione una o varias categorías virtual a desplazar. Si la lista está vacía, es porque usted todavía no lo creó.</p>
+
+<h3>Nueva categoría allegada</h3>
+
+<p>Seleccione la nueva categoría allegada (virtual o física). Si usted no selecciona ninguno, las categorías que hay que desplazar habrán subido a la raíz de las categorías.
+Usted no puede desplazar una categoría en él misma o sus niños.</p>
Index: /tags/2.0.2/language/es_ES/help/cat_options.html
===================================================================
--- /tags/2.0.2/language/es_ES/help/cat_options.html	(revision 3278)
+++ /tags/2.0.2/language/es_ES/help/cat_options.html	(revision 3278)
@@ -0,0 +1,30 @@
+<h2>Opciones de las categorías</h2>
+
+<p>Gestión de las opciones para varias categorías a la vez.</p>
+
+<dl>
+
+  <dt>Autorización al añadido</dt>
+
+  <dd>Devolver las categorías autorizadas al añadido por los visitadores. Esta opción no está disponible para las categorías virtuales y distantes.</dd>
+  
+  <dt>Comentarios utilizador</dt>
+
+  <dd>Autorizar a los utilizadores a añadir comentarios en las categorías seleccionada.
+Por herencia, una imagen es commentable si pertenece por lo menos a una categoría commentable.</dd>
+  
+  <dt>Encerrar</dt>
+
+  <dd>Las categorías seleccionadas se vuelven temporalmente inactivas para mantenimiento. Cuando una categoría es encerrada, todas las categorías niño son encerradas. Cuando una categoría es quitada el cierre, todas las categorías allegadas son quitadas el cierre.</dd>
+
+  <dt>Pública / Particular</dt>
+
+  <dd>Gestión del estatuto de las categorías. Los permisos son posibles sólo para las categorías particulares. En cuanto una categoría es privada, usted explícitamente debe autorizar a los utilizadores o los grupos a acceder a eso. Cuando una categoría se vuelve particular, todas las categorías niño se vuelven particulares. Cuando una categoría se vuelve pública, todas las categorías allegadas se vuelven públicas.</dd>
+
+  <dt>Representante</dt>
+
+  <dd>Esta opción únicamente está disponible si el parámetro de configuración <code>allow_random_representative</code> (Ver <span
+class="filename">include/config_default.inc.php</span>) es
+<em>true</em>. Cada categoría posiblemente representada al azar o por una miniatura fija única.</dd>
+
+</dl>
Index: /tags/2.0.2/language/es_ES/help/cat_perm.html
===================================================================
--- /tags/2.0.2/language/es_ES/help/cat_perm.html	(revision 3278)
+++ /tags/2.0.2/language/es_ES/help/cat_perm.html	(revision 3278)
@@ -0,0 +1,11 @@
+<h2>Administrar los permisos para una categoría</h2>
+
+<p>Esta pantalla está disponible sólo para las categorías particulares. Aquí usted podrá seleccionar a los utilizadores y los grupos autorizados para esta categoría.</p>
+
+<h3>Grupos</h3>
+
+<p>Usted puede autorizar o prohibir el acceso a los grupos. Modificando las autorizaciones de los grupos, usted probablemente modificará la lista de los utilizadores autorizados gracias a la pertenencia a los grupos.</p>
+
+<h3>Utilizadores</h3>
+
+<p>Usted puede autorizar o prohibirles el acceso a los utilizadores individualmente.</p>
Index: /tags/2.0.2/language/es_ES/help/configuration.html
===================================================================
--- /tags/2.0.2/language/es_ES/help/configuration.html	(revision 3278)
+++ /tags/2.0.2/language/es_ES/help/configuration.html	(revision 3278)
@@ -0,0 +1,102 @@
+<h2>Configuración</h2>
+
+<p>Esta pantalla permite administrar la configuración básica. En efecto, sólo son mostrados los parámetros de configuración que deben bastar para la mayoría de los administradores. Si usted desea ver la lista de los numerosos (y acercados) parámetros, leer el fichero <span
+class="filename">include/config_default.inc.php</span></p>
+
+<p>Esta pantalla es divisié en varias secciones, reagrupando los parámetros por tema.</p>
+
+<h3>Directora de colegio</h3>
+<ul>
+
+  <li><strong>Título de la galería</strong>: utilizado para el flujo RSS y la notificación por e-mail.</li>
+
+  <li><strong>Bandera de las páginas</strong>: código html fijado en lo alto de las páginas.</li>
+
+  <li><strong>URL de la galería</strong>: utilizado para el flujo RSS.</li>
+
+  <li><strong>Encerrar la galería</strong>: Encerrar el conjunto de la galería para mantenimiento. Sólo los administradores podrán acceder a la galería.</li>
+
+  <li><strong>Notación</strong>: La notación de las fotos es posible.</li>
+
+  <li><strong>Notación por los visitadores</strong>: Hasta los utilizadores no registrados pueden anotar las imágenes.</li>
+
+  <li><strong>Notificar a los administradores en el momento de la inscripción de un utilizador</strong>: Los administradores recibirán un courriel a cada inscripción.</li>
+
+  <li><strong>Permitir el registro de los utilizadores</strong>: La inscripción es libre para ellos todos.</li>
+
+</ul>
+
+<h3>Reseña histórica</h3>
+
+  <p>Las visitas de las páginas <span
+class="pwgScreen">index.php</span> et <span
+class="pwgScreen">picture.php</span> Son registrados en la mesa <code>history</code>.</p>
+
+  <p>Las visitas son fijadas en la pantalla <span class="pwgScreen">Administración, Classes de matemáticas superiores, Reseña histórica</span>.</p>
+
+<ul>
+  <li><strong>Registrar las páginas visitadas por los invitados</strong>: las visitas de las páginas por los invitados son registradas.</li>
+
+  <li><strong>Registrar las páginas visitadas por los utilizadores</strong>: las visitas del pagespar los utilizadores registrados son registrados.</li>
+
+  <li><strong>Registrar las páginas visitadas por los administradores</strong>: Las visitas de las páginas por los administradores son registradas.</li>
+
+</ul>
+
+<h3>Comentarios</h3>
+<ul>
+
+  <li><strong>Comentarios utilizador para ellos todos</strong>: hasta los utilizadores no registrados pueden registrar comentarios.</li>
+
+  <li><strong>Número utilizador de comentarios por página</strong>.</li>
+
+  <li><strong>Validación</strong>: Un administrador debe validar los comentarios utilizadores antes de que puedan volverse visibles en la partida pública. La validación de los comentarios utilizadores se efectua en la pantalla <span class="pwgScreen">Administración, Imágenes, Comentarios</span>.</li>
+
+  <li><strong>Notificar a los administradores cuando un comentario es registrado</strong>:
+Envío un courriel a los administradores cuando un utilizador registra un comentario que es validado.</li>
+
+  <li><strong>Notificar a los administradores cuando un comentario requiere su validación </strong>:
+Envío un courriel a los administradores cuando un tilisateur registra un comentario que pide una validación por parte de los administradores.
+La validación de los comentarios utilizadores se efectua en la pantalla <span class="pwgScreen">Administración, Imágenes, Comentarios</span>.</li>
+
+</ul>
+
+<h3>Descargar</h3>
+<ul>
+  <li><strong>Fijar el lazo de añadido de imagen todo el tiempo</strong>: Si existen unas categorías que permiten el cargamiento, el lazo de añadido de imagen será fijado un poco de sea la categoría.</li>
+  <li><strong>Nivel de acceso usuario para cargar</strong>: Permite restringirles el añadido a ciertos usuarios</li>
+  <li><strong>Notificar a los administradores cuando una imagen es cargada</strong>: Los administradores recibirán un courriel a cada imagen puesto en disposición por un utilizador.</li>
+</ul>
+
+<h3>Fijación por defecto</h3>
+<p>Modificar las opciones de fijación por defecto: para los visitadores no conectados. Una vez conectado, estas opciones son sobrecargadas por las del utilizador, a las que puede modificar en la pantalla <span
+class="pwgScreen">perfila</span>.</p>
+
+<p>Es posible cambiar estas opciones para los utilizadores existentes, pero se trata de una otra pantalla : <span class="pwgScreen">Administración, Identificación, Utilizadores</span>, en el cual usted puede modificar estas opciones para una lista de utilizadores seleccionados.</p>
+
+<ul>
+
+  <li><strong>Lengua</strong>: Concierne sólo a las redacciones de Piwigo. Los nombres de categorías, de imagen y las descripciones no son localizados (ie multilingüe).</li>
+
+  <li><strong>Número de miniaturas por línea</strong></li>
+
+  <li><strong>Número de líneas por página</strong></li>
+
+  <li><strong>Tema de la interfaz</strong></li>
+
+  <li><strong>Período reciente</strong>: En días. El período durante el cual una imagen es considerada cómo noticia. Este período debe ser superior a 1 día.</li>
+
+  <li><strong>Desarrollar todas las categorías</strong>: ¿ Desarrollar todas las categorías en el menú? <em>Attention</em>: Esta opción es susceptible de consumir inútilmente recursos si su árbol de categorías contiene numerosos elementos.</li>
+
+  <li><strong>Mostrar el número de comentarios</strong>: Mostrar número utilizador de comentarios debajo de cada miniatura. Consume recursos.</li>
+
+  <li><strong>Mostrar el número de visualizaciones  </strong>: Fija los "hits" rehechos sobre una imagen bajo su miniatura en la página de miniaturas.
+  Únicamente válido si el parámetro de configuración avanzada es:<br />
+  $conf['show_nb_hits'] = true; <br />
+  N.B.: por defaut es a false.</li>
+
+  <li><strong>Anchura máxima de las imágenes</strong>: A la fijación. Si la imagen es más ancha que este parámetro, entonces será redimensionnée a la fijación. Si usted piensa en neceser de modificar este parametraje (pues para una fijación por defecto), sería pertinente de directamente redimensionner sus imágenes almacenadas.</li>
+
+  <li><strong>Altura máxima de las imágenes</strong>: hasta observa que por la anchura.</li>
+
+</ul>
Index: /tags/2.0.2/language/es_ES/help/extend_for_templates.html
===================================================================
--- /tags/2.0.2/language/es_ES/help/extend_for_templates.html	(revision 3278)
+++ /tags/2.0.2/language/es_ES/help/extend_for_templates.html	(revision 3278)
@@ -0,0 +1,103 @@
+<h2>Configuración para "extender" el templates</h2>
+
+<h3>Objetivo</h3>
+<p>Definir las condiciones de sustitución de cada template (modelo) a partir de template-extensión
+ (template llamado "a reponer" (a sustituto)).</p>
+
+<p>" Templates de origen " proviniendo de . / template / yoga (o de otro expediente que "yoga")
+ son reemplazados por el sustituto si éste es atado(vinculado) a su template de origen 
+ (y de modo facultativo, cuando la dirección (URL) contiene un URL contains un 
+ " Parámetro facultativo del URL ").</p>
+
+<p>Los " Parámetros facultativo del URL " son aquellos a los que usted puede encontrar después del nombre del módulo en la dirección (URL).</p>
+
+<p>Así un " Parámetro facultativo del URL " puede ser un "permalink" (lazo permanente) activo 
+(ver el permalinks en nuestra documentación para más información).</p>
+
+<p>Leer las `<a href="#warnings">impuestas en guardia</a>` sobre las condiciones de utilización.</p>
+
+<h3>¿ Qué las extensiones de los modelos?</h3>
+
+<p>Este instrumento de configuración es a la vez poderoso para los principiantes y para los usuarios avanzados.
+Por FTP, en el expediente template-extensión, Webmaster podrá duplicar una buena parte(partida) de los ficheros 
+.tpl distribuidos (" Templates de origen ") 
+con un nombre diferente ("reponer" (a sustituto)).
+ 
+ "Templates de origen ", actualmente los modelos sostenidos de origen son:</p>
+<ul>
+  <li><span class="filename">index.tpl</span></li>
+  <li><span class="filename">mainpage_categories.tpl</span> and/or <span class="filename">thumbnails.tpl</span></li>
+  <li><span class="filename">menubar.tpl</span></li>
+  <li><span class="filename">header.tpl</span> and/or <span class="filename">footer.tpl</span></li>
+  <li><span class="filename">picture_content.tpl</span> and/or <span class="filename">picture.tpl</span></li>
+  <!-- <li><span class="filename">slideshow.tpl</span></li> -->
+  <li><span class="filename">profile.tpl</span> and/or <span class="filename">profile_content.tpl</span></li>
+  <li><span class="filename">tags.tpl</span></li>
+  <li><span class="filename">upload.tpl</span></li>
+  <li><span class="filename">about.tpl</span></li>
+  <li><span class="filename">popuphelp.tpl</span></li>
+  <li><span class="filename">search.tpl</span> and/or <span class="filename">search_rules.tpl</span></li>
+  <li><span class="filename">nbm.tpl</span> and/or <span class="filename">notification.tpl</span></li>
+  <li><span class="filename">identification.tpl</span> and/or <span class="filename">register.tpl</span></li>
+  <li><span class="filename">redirect.tpl</span></li>
+</ul>
+
+<h3>¿ Dónde puedo encontrar a " Templates de origen "?</h3>
+
+<p>Los modelos distribuidos de origen son en template / yoga / 
+(directamente no modificarlos en este lugar por razones de evolución).
+ Así a partir de " templates de origen ", todo webmaster podrá crear su " replacers 
+ (modelos personalisés) ".</p>
+
+<h3>¿ Dónde debo registrar a los "sustitutos"?</h3>
+
+<p>Los <strong>sustitutos (templates modificados)</strong> pueden estar colocados en 
+el expediente template-extensión (o sus subexpedientes).
+Los sustitutos pueden tener cualquier nombre de fichero con la extensión .tpl. Por ejemplo: <span
+class="filename">template-extension/my-extension/video.tpl</span>.</p>
+
+
+<h3>¿ Cómo puedo acelerar a mis "sustitutos"?</h3>
+<p>Uno <strong>Template de origen </strong> debería ser asociado con cada <strong>
+ reponer (modelo modificado) </strong> a fin de acelerar las sustituciones correspondientes.
+ Acelerar a los sustitutos es la función de " Extender el templates " en los menús de
+ Configuración de la Administración. </p>
+
+<p>Si usted selecciona un <strong> Define parámetros facultativo del URL </strong>
+ entonces las sustituciones serán realizados sólo sobre las páginas que utilizarán 
+ esta palabra clave. Por ejemplo: <span
+  class="pwgScreen">index.php?/<strong>most_visited</strong></span></p>
+  
+<p>Los usuarios avanzados utilizarán el permalinks (permaliens, lazos permanentes) como strong> parámetro facultativo del URL </strong>. </p>
+
+<!-- TODO -->
+<p>If you select a <strong>Bound template</strong> then replacements will be operate only on this template.</p>
+
+<h3>¿ Cómo puedo desactivar mi "sustitutos"?</h3>
+<ul>
+<li>Deselectionner " template de origen ".</li>
+<li>Por FTP suprimir "sustitutos".</li>
+</ul>
+<a name="warnings"></a>
+<h3>Advertidas</h3>
+<ul>
+
+  <li>¡ El <strong> template de origen </strong> debe ser el verdadero 
+  template " de origen " de otro modo usted podría tener los resultados imprevisibles!</li>
+
+  <li>Si vario <strong> sustituto templates modofiés </strong> tienen lo mismo <strong>
+  template de origen </strong> y lo mismo <strong> parámetro facultativo del URL </strong> entonces solamente el último sustituto será activo.</li>
+
+  <li>No seleccionar de <strong> parámetro facultativo del URL </strong> acelerará el template de sustitución a cada utilización del template.
+  Así como mencionada más arriba, la orden puede inhibir por los sustitutos precedentes.</li>
+
+  <li>Subexpedientes :
+  Los subexpedientes son ignorados pero son útiles para modificar la orden de los sustitutos. <br />
+  distributed-samples: ¡ para sus pruebas son distributés! 
+<strong>No modificarlos :</strong>¡ Cree vuestros!
+</li>
+
+  <li>A la supresión del sustituto el <strong> template de origen </strong> inmediatamente será
+  reactivado.</li>
+
+</ul>
Index: /tags/2.0.2/language/es_ES/help/group_list.html
===================================================================
--- /tags/2.0.2/language/es_ES/help/group_list.html	(revision 3278)
+++ /tags/2.0.2/language/es_ES/help/group_list.html	(revision 3278)
@@ -0,0 +1,21 @@
+<h2>Lista grupos</h2>
+
+<p> Manipulación de las propiedades de los grupos definidos.</p>
+
+<h3>Añadir un grupo</h3>
+
+<p>El administrador puede añadir grupos.</p>
+
+<h3>Lista grupos</h3>
+
+<p>La lista permite para cada grupo:</p>
+
+<ul>
+  <li>de acceder a la lista de los miembros</li>
+  <li>de acceder a los permisos</li>
+  <li>de suprimir el grupo (necesita una confirmación)</li>
+  <li>de invertir el estatuto " por defecto " (necesita una confirmación)</li>
+</ul>
+
+<h3>Grupos por defecto</h3>
+<p>Los grupos por defecto son los grupos asociados automáticamente con cada nuevo utilizador.</p>
Index: /tags/2.0.2/language/es_ES/help/history.html
===================================================================
--- /tags/2.0.2/language/es_ES/help/history.html	(revision 3278)
+++ /tags/2.0.2/language/es_ES/help/history.html	(revision 3278)
@@ -0,0 +1,51 @@
+<h2>Histórico</h2>
+
+<p>Estas pantallas permiten seguir el histórico de navegación en Piwigo
+ en función de las opciones que ha determinado en 
+Administración - Ensayo general - señal Reseña histórica.</p>
+	
+<h3>Estadísticas</h3>
+<ul>
+  <p>Si quiere que las visitas de las páginas <span
+class="pwgScreen">index.php</span> y <span
+class="pwgScreen">picture.php</span> sean 
+registradas en el cuadro <code>history</code>,
+esta señal permite seguir el número de páginas visitadas</p>
+	
+	<li><strong>Estadísticas totales</strong> : ve las estadísticas por año.</li>
+	
+	<li><strong>Estadísticas de un año</strong> : ve las estadísticas de los
+	meses del año seleccionado.</li>
+	
+	<li><strong>Estadísticas de un mes</strong> : ve las estadísticas
+	de los días del mes seleccionado.</li>
+	
+	<li><strong>Estadísticas de un día</strong> : ve las estadísticas
+	de las horas del día seleccionado.</li>
+	
+</ul>
+
+<h3>Buscar</h3>
+<ul>
+  <p>Si quiere que las visitas de las páginas <span
+class="pwgScreen">index.php</span> y <span
+class="pwgScreen">picture.php</span> sean 
+registradas en el cuadro <code>history</code>, esta señal permite 
+seguir más detalladamente las páginas exploradas en su sitio con ayuda 
+de distintos filtros..</p>
+ 
+	<li><strong>Filtrar por fecha</strong> : seleccionar la zona de observación cuya 
+	actividad quiere observar.</li>
+	
+	<li><strong>Filtrar por tipo de elemento</strong> : seleccionar el tipo de 
+	elemento cuya actividad	quiere observar .</li>
+	
+	<li><strong>Filtrar por usuario</strong> : seleccionar el usuario cuya actividad
+	quiere observar.</li>
+	
+	<li><strong>Filtrar por nombre del fichero</strong> : seleccionar el nombre del 
+	fichero cuya actividad quiere observar.</li>
+	
+	<li><strong>Filtrar por identificador de la imagen</strong> : seleccionar el 
+	identificador de la imagen cuya actividad quiere observar.</li>
+</ul>
Index: /tags/2.0.2/language/es_ES/help/index.php
===================================================================
--- /tags/2.0.2/language/es_ES/help/index.php	(revision 3278)
+++ /tags/2.0.2/language/es_ES/help/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/language/es_ES/help/maintenance.html
===================================================================
--- /tags/2.0.2/language/es_ES/help/maintenance.html	(revision 3278)
+++ /tags/2.0.2/language/es_ES/help/maintenance.html	(revision 3278)
@@ -0,0 +1,27 @@
+<h2>Mantenimiento</h2>
+
+<p>Para optimizar el tiempo de generación de las páginas, Piwigo utiliza informaciones en viñeta. Por ejemplo, en lugar de contar el número de elementos contenidos en cada categoría a cada nueva carga de página, esta información es almacenada en la base de datos. Teóricamente, esta información debe siempre ser correcta, pero a veces un error puede sobrevenir y la información en viñeta se vuelve falsa.</p>
+
+<p>Informaciones se vuelven inútiles con tiempo. Suprimirlos de la base de datos libera del espacio disco.</p>
+
+<ul>
+
+  <li><strong>Poner al día las informaciones de las categorías:</strong> Para cada categoría, las informaciones a controller y\o poner al día son las siguientes: lista de las categorías madres, número de elementos, fecha del último elemento, la posición entre las categorías hermana, posición en el árbol completo de las categorías. Esta acción también verifica la coherencia de los representantes.</li>
+
+  <li><strong>Poner al día las informaciones de las imágenes:</strong> Para cada imagen, las informaciones que hay que poner al día son: camino completo hacia el fichero, la nota media. <em>Atención</em>: No confundir con los méta-datos que son sincronizados sobre la pantalla <span
+class="pwgScreen">Administración, Categorías, Sincronizar</span> O sobre la pantalla <span class="pwgScreen">Modificar las informaciones de una imagen</span>
+(accesible desde la página de visualización de una imagen <span
+class="pwgScreen">picture.php</span>).</li>
+
+  <li><strong>Purgar la reseña histórica:</strong> Suprime todas las líneas de la mesa <code>history</code>. La pantalla <span
+class="pwgScreen">Administración, Classes de matemáticas superiores, Reseña histórica</span> no muestres entonces ninguna información sobre el pasado. <em>Atención</em>: todos los datos estarán perdidos y no existe ningún medio de recuperarlas.</li>
+
+  <li><strong>Purgar las sesiones:</strong> Suprimir las sesiones espiradas..</li>
+
+  <li><strong>Purgar los flujos jamás utilizados de notificación</strong></li>
+
+  <li><strong>Reparar y optimizar la base de datos:</strong>
+Para cada mesas de la base de datos PhpWegGallery, las operaciones de ré-planificación, de reparación y de optimización son efectuadas.
+  </li>
+
+</ul>
Index: /tags/2.0.2/language/es_ES/help/notification_by_mail.html
===================================================================
--- /tags/2.0.2/language/es_ES/help/notification_by_mail.html	(revision 3278)
+++ /tags/2.0.2/language/es_ES/help/notification_by_mail.html	(revision 3278)
@@ -0,0 +1,15 @@
+<h2>Notificación por mail</h2>
+
+<p>Esta pantalla permite configurar, administrarles la notificación a los utilizadores de cambios por el envío de un mail.</p>
+
+<p>Esta pantalla es constada por 3 ingletes:</p>
+
+<h3>Paramètrage</h3>
+<p>Accésible únicamente en el webmestres, este inglete permite situar los parámetros de la notificación por mail.</p>
+
+<h3>Inscripción</h3>
+<p>Accésible únicamente en el webmestres, este inglete permite administrar las inscripciones / désinscriptions a la notificación por mail.</p>
+
+<h3>Envío</h3>
+<p>Accésible en el webmestres y a los administradores, este inglete permite efectuar los envíos del mails para notificar los cambios.</p>
+
Index: /tags/2.0.2/language/es_ES/help/permalinks.html
===================================================================
--- /tags/2.0.2/language/es_ES/help/permalinks.html	(revision 3278)
+++ /tags/2.0.2/language/es_ES/help/permalinks.html	(revision 3278)
@@ -0,0 +1,7 @@
+<h2>Lazos permanentes</h2>
+
+<p>Los lazos permanentes son utilizados para devolver el urls más hermoso de las categorías. Cuando una categoría tiene un lazo permanente asociada, identificándolo de la categoría no es necesario más en el url.</p>
+
+<p>Cuando un lazo permanente es borrado, usted puede salvaguardarlo en la reseña histórica de los lazos permanentes, de modo que los lazos externos tienen PWG todavía funcionan. En la reseña histórica de los lazos permanentes usted puede ver la fecha de borradura del lazo, así como fecha de la última utilización y el número de utilizaciones de este lazo.</p>
+
+<p>Por favor, anote que los lazos permanentes deben ser únicos. Deben también ser únicos en la reseña histórica de los lazos permanentes.</p>
Index: /tags/2.0.2/language/es_ES/help/search.html
===================================================================
--- /tags/2.0.2/language/es_ES/help/search.html	(revision 3278)
+++ /tags/2.0.2/language/es_ES/help/search.html	(revision 3278)
@@ -0,0 +1,23 @@
+<h2>Búsqueda</h2>
+
+<p>Búsqueda de imágenes a través del conjunto de la galería.</p>
+
+<dl>
+
+  <dt>Buscar una palabra</dt>
+
+  <dd>Búsqueda una o varias palabras en todos los atributos atados a las imágenes. Utilizar * como mono para las búsquedas parciales.</dd>
+  
+  <dt>Búsqueda de un autor</dt>
+
+  <dd>Utilizar * como mono para las búsquedas parciales.</dd>
+
+  <dt>Búsqueda por fecha</dt>
+
+  <dd>Seleccionar una fecha y/o una fecha de fin. Dejar la fecha vacía si desearle hacer una búsqueda "delantera". El año debe haber entrado en el último campo en forma de 4 cifras (2005 por ejemplo).</dd>
+
+  <dt>Búsqueda en las categorías</dt>
+
+  <dd>Seleccionar las categorías sobre las cuales restringir la búsqueda.</dd>
+
+</dl>
Index: /tags/2.0.2/language/es_ES/help/site_manager.html
===================================================================
--- /tags/2.0.2/language/es_ES/help/site_manager.html	(revision 3278)
+++ /tags/2.0.2/language/es_ES/help/site_manager.html	(revision 3278)
@@ -0,0 +1,42 @@
+<h2>Sitios distante</h2>
+
+<p>Piwigo ofrece la posibilidad de utilizar varias sitios para almacenar los ficheros que compondrán su galería. Esto puede ser útil si su galería está instalada sobre un espacio de almacenamiento limitado y si usted tiene numerosos ficheros que hay que mostrar.</p>
+
+
+<ol>
+
+  <li>editar el fichero <span
+class="filename">tools/create_listing_file.php</span> modificando la sección de los parámetros como <code>$conf['prefix_thumbnail']</code> or
+<code>$conf['use_exif']</code>.</li>
+
+  <li>colocar el fichero <span
+class="filename">tools/create_listing_file.php</span> modificado sobre su sitio distante, en el mismo repertorio que los repertorios que representan sus categorías (como el repertorio <span class="filename">galleries</span> de
+ce site) para FTP. Por ejemplo, digamos que usted puede acceder a  <span
+class="filename">http://exemple.com/galleries/create_listing_file.php</span>.</li>
+
+  <li>Ir sobre <span class="pwgScreen">Administración, Categorías, Gerente de las sitios</span>. Pedir crear una nueva sitio, por ejemplo <span
+class="filename">http://exemple.com/galleries</span>.</li>
+
+  <li>
+
+    <p>Una nueva sitio distante es registrada. 4 acciones posibles :</p>
+
+    <ol>
+
+      <li><strong>generar la lista</strong> : lanza una demanda distante para generar el fichero de listado distante</li>
+
+      <li><strong>sincronizar</strong> : lee el fichero distante <span
+class="filename">listing.xml</span> y sincroniza con la base de datos local</li>
+
+      <li><strong>limpiar</strong> : Suprime el fichero distante de listado</li>
+
+      <li><strong>destruir</strong> : suprime la sitio (y todos los elementos que son asociados con eso) en la base de datos</li>
+
+    </ol>
+
+  </li>
+
+</ol>
+
+<!--<p>Usted también puede efectuar estas operaciones manualmente editando el fichero <span class = filename "> listing.xml </span> en la mano y desplazándolo hacia su repertorio raíz. Hacerse sobre <span class = pwgScreen "> Administración, Categorías, Ubicaciones(Sitios) distante </span>:
+Piwigo detecta el fichero y propone servirse de eso.</p>-->
Index: /tags/2.0.2/language/es_ES/help/synchronize.html
===================================================================
--- /tags/2.0.2/language/es_ES/help/synchronize.html	(revision 3278)
+++ /tags/2.0.2/language/es_ES/help/synchronize.html	(revision 3278)
@@ -0,0 +1,12 @@
+<h2>Sincronizar</h2>
+
+<ul>
+
+  <li>Existen 2 tipos de sincronizaciones: estructura y meta-datos. Sincronizar la estructura vuelve a sincronizar su árbol de los repertorios y los ficheros con la representación de la estructura en la base de datos. Sincronizar los méta-datos permite poner al día las informaciones como el peso del fichero, las dimensiones, los datos EXIF o IPTC.</li>
+
+  <li>La première synchronisation à effectuer doit être celle sur la
+structure.</li>
+
+  <li>El proceso de sincronización puede llevar tiempo (con arreglo a la carga del servidor y de la cantidad de ficheros administrando), pues es posible avanzar paso a paso: categoría por categoría.</li>
+
+</ul>
Index: /tags/2.0.2/language/es_ES/help/thumbnail.html
===================================================================
--- /tags/2.0.2/language/es_ES/help/thumbnail.html	(revision 3278)
+++ /tags/2.0.2/language/es_ES/help/thumbnail.html	(revision 3278)
@@ -0,0 +1,25 @@
+<h2>Creación de las miniaturas</h2>
+
+<p>Creación de las miniaturas faltantes. La utilización de este carácter funcional no es aconsejada si su galería es albergada sobre un servidor mutualisé (resources máquina compartidas).</p>
+
+<dl>
+
+  <dt>Versión de GD</dt>
+
+  <dd>GD es una librería gráfica de manipulación de imágenes para PHP. Escoja la versión instalada sobre su servidor. Si usted escoge al mal, mensajes de errores aparecerán, vuelva sobre la página precedente y escoja la otra versión. Si ninguna versión marcha, esto significa que GD no está disponible.</dd>
+
+  <dt>Anchura y altura</dt>
+
+  <dd>Dimensiones máximo que las miniaturas pueden tomar. El ratio anchura / altura original es conservado. Los valores por defecto son modificables gracias a los parámetros de configuración <code>tn_width</code> y
+<code>tn_height</code> (ver el fichero <span
+class="filename">include/config_default.inc.php</span>).</dd>
+  
+  <dt>Número de miniaturas que hay que crear</dt>
+
+  <dd>No hésayez de miniaturizar un número demasiado grande de imágenes a la vez. En efecto, la miniaturización requiere una utilización relativamente gruesa procesador.</dd>
+
+  <dt>Tamaño de fichero</dt>
+
+  <dd>Las miniaturas son creadas al tamaño JPEG. Sólo el tamaño PNG y JPEG pueden ser miniaturizados.</dd>
+
+</dl>
Index: /tags/2.0.2/language/es_ES/help/user_list.html
===================================================================
--- /tags/2.0.2/language/es_ES/help/user_list.html	(revision 3278)
+++ /tags/2.0.2/language/es_ES/help/user_list.html	(revision 3278)
@@ -0,0 +1,33 @@
+<h2>Lista utilizadores</h2>
+
+<p>Manipulación de las propiedades de los utilizadores registrados. Las únicas los permisos son administrados en una pantalla diferente.</p>
+
+<h3>Añadir a un utilizador</h3>
+
+<p>El administrador puede añadir manualmente a utilizadores.</p>
+
+<h3>Lista utilizadores</h3>
+
+<p>La lista puede ser filtrada con nombre de utilizador (* = mono), con grupo o todavía el estatuto. La lista puede ser ordenada según la fecha de registro o el nombre de utilizador, por orden ascendente al desminuir.</p>
+
+<p>Esta pantalla funciona por modificación de varios utilizadores simultáneamente:</p>
+
+<ul>
+  <li>suprimir a utilizadores (necesita una confirmación)</li>
+  <li>cambiar el estatuto</li>
+  <li>asociar o disociar grupos</li>
+  <li>modificar las propiedades de fijación</li>
+  <li>modificar las propiedades anexos</li>
+</ul>
+
+<p>El blanco es la lista de los utilizadores seleccionados (por defecto) o bien todos los utilizadores de la lista filtrada.</p>
+
+<h3>Consejero</h3>
+<p>Definición de un utilizador aconsejar:</p>
+<ul>
+  <li>permite acceder a todas las pantallas permitidas por su estatuto</li>
+  <li>acceso únicamente en consulta o en simulación</li>
+</ul>
+
+<p>Es posible permitir el asignación del modo aconsejar con la variable $conf['allow_adviser'].</p>
+<p>Si esta variable está a 'true', será posible definir al utilizador como un consejero</p>
Index: /tags/2.0.2/language/es_ES/index.php
===================================================================
--- /tags/2.0.2/language/es_ES/index.php	(revision 3278)
+++ /tags/2.0.2/language/es_ES/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/language/es_ES/install.lang.php
===================================================================
--- /tags/2.0.2/language/es_ES/install.lang.php	(revision 3278)
+++ /tags/2.0.2/language/es_ES/install.lang.php	(revision 3278)
@@ -0,0 +1,74 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+$lang['Installation'] = 'Instalación';
+$lang['Initial_config'] = 'Configuración de Base';
+$lang['Default_lang'] = 'Lengua por defecto de la galería';
+$lang['step1_title'] = 'Configuración de la Base de datos';
+$lang['step2_title'] = 'Configuración de la cuenta Administrador';
+$lang['Start_Install'] = 'Empezar la instalación';
+$lang['reg_err_mail_address'] = 'La dirección mail debe ser la forma xxx@yyy.eee (ejemplo: jack@altern.org)';
+
+$lang['install_webmaster'] = 'Administrador';
+$lang['install_webmaster_info'] = 'Este identificado aparecerá en todos sus visitadores. Le sirve para administrar la sitio';
+
+$lang['step1_confirmation'] = 'Los parámetros entrados son correctos';
+$lang['step1_err_db'] = 'La conexión al camarero(servidor) es O.K., pero imposible conectarse a esta base de datos';
+$lang['step1_err_server'] = 'Imposible conectarse al servidor';
+
+$lang['step1_host'] = 'Huésped MySQL';
+$lang['step1_host_info'] = 'localhost, sql.multimania.com, toto.freesurf.fr';
+$lang['step1_user'] = 'Utilizador';
+$lang['step1_user_info'] = 'Nombre de utilizador para su hébergeur';
+$lang['step1_pass'] = 'Palabra de paso';
+$lang['step1_pass_info'] = 'El abastecido por su hébergeur';
+$lang['step1_database'] = 'Nombre de la base';
+$lang['step1_database_info'] = 'El abastecido por su hébergeur';
+$lang['step1_prefix'] = 'Prefijo nombres de mesa';
+$lang['step1_prefix_info'] = 'El nombre de las mesas aparecerá con este prefijo (permite administrar mejor su base de datos)';
+$lang['step2_err_login1'] = 'Por favor, recoja un pseudo para el webmaster';
+$lang['step2_err_login3'] = 'El pseudo del webmaster no debe contener carácter " y \'';
+$lang['step2_err_pass'] = 'Por favor, arregle su palabra de paso';
+$lang['install_end_title'] = 'Instalación acabada';
+$lang['step2_pwd'] = 'Palabra de paso';
+$lang['step2_pwd_info'] = 'Debe quedar confidencial, permite acceder al tabla de administración.';
+$lang['step2_pwd_conf'] = 'Palabra de paso [Confirmar]';
+$lang['step2_pwd_conf_info'] = 'Comprobación';
+$lang['step1_err_copy'] = 'Copie el texto en rosa entre las rayas y pegúelo en el fichero mysql.inc.php que se encuentra en el repertorio " include " a la base del lugar donde usted instaló a Piwigo (el fichero mysql.inc.php debe contener SÓLO lo que está en rosa entre las rayas, ninguna vuelta a la línea o espacio es autorizado)';
+$lang['install_help'] = '¿ Necesidad de ayudante? Plantee su cuestión sobre él <a href="%s">foro de Piwigo</a>.';
+$lang['install_end_message'] = 'La configuración de la aplicación correctamente se celebró, coloca en la etapa próxima<br /><br />
+* Vaya sobre la página de identificación y conéctese con pseudo dado para el webmaster<br />
+* Éste le permite acceder a la parte administración y a las instrucciones para colocar las imágenes en los repertorios.';
+$lang['conf_mail_webmaster'] = 'Dirige e-mail del Administrador';
+$lang['conf_mail_webmaster_info'] = 'Los visitadores podrán ponerse en contacto con usted por este mail';
+
+$lang['PHP 5 is required'] = 'PHP 5 es requerido';
+$lang['It appears your webhost is currently running PHP %s.'] = 'Aparentemente, la versión PHP de su hébergeur es PHP %s.';
+$lang['Piwigo may try to switch your configuration to PHP 5 by creating or modifying a .htaccess file.'] = 'Piwigo va a tratar de pasar en PHP 5 creando o modificando el fichero .htaccess.';
+$lang['Note you can change your configuration by yourself and restart Piwigo after that.'] = 'Anote que usted mismo puede cambiar la configuración PHP y volver a lanzar a Piwigo después.';
+$lang['Try to configure PHP 5'] = 'Tratar de configurar PHP 5';
+$lang['Sorry!'] = 'Desolado!';
+$lang['Piwigo was not able to configure PHP 5.'] = 'Piwigo no pudo configurar PHP 5.';
+$lang["You may referer to your hosting provider's support and see how you could switch to PHP 5 by yourself."] = 'Usted debe ponerse en contacto con su hébergeur con el fin de saber cómo configurar PHP 5';
+$lang['Hope to see you back soon.'] = 'Esperando verle de revisarle muy pronto...';
+?>
Index: /tags/2.0.2/language/es_ES/iso.txt
===================================================================
--- /tags/2.0.2/language/es_ES/iso.txt	(revision 3278)
+++ /tags/2.0.2/language/es_ES/iso.txt	(revision 3278)
@@ -0,0 +1,1 @@
+Español [ES]
Index: /tags/2.0.2/language/es_ES/upgrade.lang.php
===================================================================
--- /tags/2.0.2/language/es_ES/upgrade.lang.php	(revision 3278)
+++ /tags/2.0.2/language/es_ES/upgrade.lang.php	(revision 3278)
@@ -0,0 +1,44 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+$lang['Upgrade'] = 'Puesta al día';
+$lang['introduction message'] = 'Esta página le propone poner al día la base de dato correspondiente a su antigua versión de piwigo hacia la nueva versión.
+El asistente de postura al día piensa en la versión actual es un <strong> versión %s </strong> (o equivalente). ';
+$lang['Upgrade from %s to %s'] = 'Puesta al día por la versión %s a %s';
+$lang['Statistics'] = 'Estadísticas';
+$lang['total upgrade time'] = 'tiempo total de la puesta al día';
+$lang['total SQL time'] = 'tiempo total de la demanda SQL';
+$lang['SQL queries'] = 'número de demanda SQL';
+$lang['Upgrade informations'] = 'Informaciones sobre la puesta al día';
+$lang['perform a maintenance check'] = 'Por favor, efectúes un mantenimiento en [Administración>Especiales>Mantenimiento] si usted encuentra problemas.';
+$lang['deactivated plugins'] = 'Por precaución, el plugins siguiente han sido desactivados. Verifique si existen unas posturas al día antes de reactivarlas:';
+$lang['upgrade login message'] = 'Sólo un administrador puede lanzar la puesta al día: por favor, identifiqúese más abajo.';
+$lang['You do not have access rights to run upgrade'] = 'Usted no tiene los derechos necessaires para lanzar la puesta al día.';
+/* TODO */$lang['in include/mysql.inc.php, before ?>, insert:'] = 'In <i>include/mysql.inc.php</i>, before <b>?></b>, insert:';
+
+// Upgrade informations from upgrade_1.3.1.php
+$lang['all sub-categories of private categories become private'] = 'Todas las subcategorías de categorías privadas se vuelven privadas';
+$lang['user permissions and group permissions have been erased'] = 'Los autorizaciones de los usuarios y de los grupos han sido borrados';
+$lang['only thumbnails prefix and webmaster mail saved'] = 'Sólo el prefijo de las miniaturas y el email electrónico del webmestre han sido salvaguardados por la configuración precedente';
+
+?>
Index: /tags/2.0.2/language/fr_FR/about.html
===================================================================
--- /tags/2.0.2/language/fr_FR/about.html	(revision 3278)
+++ /tags/2.0.2/language/fr_FR/about.html	(revision 3278)
@@ -0,0 +1,8 @@
+  <li>Piwigo est une application web permettant de créer facilement
+une galerie d'images en ligne.</li>
+
+  <li>Techniquement, Piwigo est développée en PHP avec une base de
+données MySQL.</li>
+
+  <li>Si vous avez des suggestions ou des commentaires, visitez le <a
+  href="http://fr.piwigo.org">site officiel</a> et <a href="http://fr.piwigo.org/forum">son forum</a>.</li>
Index: /tags/2.0.2/language/fr_FR/admin.lang.php
===================================================================
--- /tags/2.0.2/language/fr_FR/admin.lang.php	(revision 3278)
+++ /tags/2.0.2/language/fr_FR/admin.lang.php	(revision 3278)
@@ -0,0 +1,649 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+$lang['%d association'] = '%d association';
+$lang['%d associations'] = '%d associations';
+$lang['cat_inclu_part1_S'] = '%d catégorie dont ';
+$lang['cat_inclu_part1_P'] = '%d catégories dont ';
+$lang['cat_inclu_part2_S'] = '%d physique';
+$lang['cat_inclu_part2_P'] = '%d physiques';
+$lang['cat_inclu_part3_S'] = ' et %d virtuelle';
+$lang['cat_inclu_part3_P'] = ' et %d virtuelles';
+$lang['%d category moved'] = '%d catégorie déplacée';
+$lang['%d categories moved'] = '%d catégories déplacées';
+$lang['%d group'] = '%d groupe';
+$lang['%d groups'] = '%d groupes';
+$lang['%d member'] = '%d membre';
+$lang['%d members'] = '%d membres';
+$lang['%d tag'] = '%d tag';
+$lang['%d tags'] = '%d tags';
+$lang['%d user comment rejected'] = '%d commentaire d\'utilisateur rejeté';
+$lang['%d user comments rejected'] = '%d commentaires d\'utilisateurs rejetés';
+$lang['%d user comment validated'] = '%d commentaire d\'utilisateur validé';
+$lang['%d user comments validated'] = '%d commentaires d\'utilisateurs validés';
+$lang['%d user deleted'] = '%d utilisateur supprimé';
+$lang['%d users deleted'] = '%d utilisateurs supprimés';
+$lang['%d user'] = '%d utilisateur';
+$lang['%d users'] = '%d utilisateurs';
+$lang['%d waiting for validation'] = '%d en attente de validation';
+$lang['%d waiting pictures rejected'] = '%d images en attente rejetées';
+$lang['%d waiting pictures validated'] = '%d images en attente validées';
+$lang['Actions'] = 'Actions';
+$lang['Activate'] = 'Activer';
+$lang['Add/delete a permalink'] = 'Ajouter/effacer un lien permanent';
+$lang['Add a tag'] = 'Ajouter un tag';
+$lang['Add a user'] = 'Ajouter un utilisateur';
+$lang['Add group'] = 'Ajouter un groupe';
+$lang['Add selected elements to caddie'] = 'Ajouter les éléments sélectionnés au panier';
+$lang['Add'] = 'Ajouter';
+$lang['Allow user registration'] = 'Permettre l\'enregistrement des utilisateurs';
+$lang['Apply to subcategories'] = 'Appliquer aux sous-catégories';
+$lang['Are you sure?'] = 'Etes-vous sur?';
+$lang['Associated'] = 'Associée à';
+$lang['Association to categories'] = 'Association aux catégories';
+$lang['Batch management'] = 'Gestion par lot';
+$lang['Caddie management'] = 'Gestion du panier';
+$lang['Caddie'] = 'Panier';
+$lang['Categories authorized thanks to group associations'] = 'Catégories accessibles grâce à l\'appartenance aux groupes';
+$lang['Categories manual order was saved'] = 'L\'ordre manuel des catégories a été sauvegardé';
+$lang['Categories ordered alphanumerically'] = 'Catégories ordonnées alphabético-numériquement';
+$lang['Category elements associated to the following categories: %s'] = 'Les éléments de la catégorie ont été associés aux catégories suivantes : %s';
+$lang['Check for upgrade failed for unknown reasons.'] = 'La vérification de la dernière version sur le serveur a échouée pour une raison inconnue.';
+$lang['Check for upgrade'] = 'Dernière version ?';
+$lang['Comments for all'] = 'Commentaires pour tous';
+$lang['Controversy'] = 'Controverse';
+$lang['Current name'] = 'Nom courant';
+$lang['Database'] = 'Base de données';
+$lang['Deactivate'] = 'Désactiver';
+$lang['Delete Representant'] = 'Supprimer le représentant';
+$lang['Delete selected tags'] = 'Supprimer les tags sélectionnés';
+$lang['Delete selected users'] = 'Supprimer les utilisateurs sélectionnés';
+$lang['Deletions'] = 'Suppressions';
+$lang['Deny selected groups'] = 'Interdire l\'accès aux groupes sélectionnés';
+$lang['Deny selected users'] = 'Interdire l\'accès aux utilisateurs sélectionnés';
+$lang['Description'] = 'Description';
+$lang['Display options'] = 'Options d\'affichage';
+$lang['Dissociated'] = 'Dissociée de';
+$lang['Does not represent'] = 'Ne représente pas';
+$lang['Edit all picture informations'] = 'Modifier toutes les informations liées à cette image';
+$lang['Edit selected tags'] = 'Editer les tags sélectionnés';
+$lang['Edit tags'] = 'Editer les tags';
+$lang['Elements'] = 'Éléments';
+$lang['Email administrators when a new user registers'] = 'Notifier les administrateurs lors de l\'inscription d\'un utilisateur';
+$lang['Email administrators when a valid comment is entered'] = 'Notifier les administrateurs quand un commentaire est enregistré';
+$lang['Email administrators when a comment requires validation'] = 'Notifier les administrateurs quand un commentaire requiert sa validation';
+$lang['Email administrators when a picture is uploaded'] = 'Notifier les administrateurs quand une image est téléchargée';
+$lang['Empty caddie'] = 'Vider le panier';
+$lang['Environment'] = 'Environnement';
+$lang['Form'] = 'Formulaire';
+$lang['Gallery URL'] = 'URL de la galerie';
+$lang['Gallery description'] = 'Description de la galerie';
+$lang['Gallery title'] = 'Titre de la galerie';
+$lang['Grant selected groups'] = 'Donner l\'accès aux groupes sélectionnés';
+$lang['Grant selected users'] = 'Donner l\'accès aux utilisateurs sélectionnés';
+$lang['Group name'] = 'Nom du groupe';
+$lang['Groups'] = 'Groupes';
+$lang['Guests'] = 'Invités';
+$lang['History'] = 'Historique';
+$lang['Informations'] = 'Informations';
+$lang['Install'] = 'Installer';
+$lang['Link all category elements to a new category'] = 'Associer tous les éléments de la catégorie à une nouvelle catégorie';
+$lang['Link all category elements to some existing categories'] = 'Associer tous les éléments de la catégorie à des catégories existantes';
+$lang['Linked categories'] = 'Catégories associées';
+$lang['Lock gallery'] = 'Verrouiller la galerie';
+$lang['Maintenance'] = 'Maintenance';
+$lang['Manage permissions for a category'] = 'Gérer les permissions pour une catégorie';
+$lang['Manage permissions for group "%s"'] = 'Gérer les permissions pour le groupe "%s"';
+$lang['Manage permissions for user "%s"'] = 'Gérer les permissions pour l\'utilisateur "%s"';
+$lang['Manage tags'] = 'Gérer les tags';
+$lang['Members'] = 'Membres';
+$lang['Metadata synchronized from file'] = 'Meta-données synchronisées à partir du fichier';
+$lang['Move categories'] = 'Déplacer les catégories';
+$lang['Move'] = 'Déplacer';
+$lang['Name'] = 'Nom';
+$lang['New name'] = 'Nouveau nom';
+$lang['New parent category'] = 'Nouvelle catégorie parente';
+$lang['New tag'] = 'Nouveau tag';
+$lang['No tag defined. Use Administration>Pictures>Tags'] = 'Aucun tag défini. Utiliser l\'écran Adminstration>Images>Tags';
+$lang['Number of comments per page'] = 'Nombre de commentaires par page';
+$lang['Number of rates'] = 'Nombre de notes';
+$lang['Number of thumbnails to create'] = 'Nombre de miniatures à créer';
+$lang['Only private categories are listed'] = 'Seules les catégories privées sont listées';
+$lang['Operating system'] = 'System d\'exploitation';
+$lang['Options'] = 'Options';
+$lang['Order alphanumerically'] = 'Ordonner alphabético-numériquement';
+$lang['Other private categories'] = 'Autres catégories privées';
+$lang['Page banner'] = 'Bannière des pages';
+$lang['Parent category'] = 'Catégorie parente';
+$lang['Path'] = 'Chemin';
+$lang['Permalink'] = 'Lien permanent';
+$lang['Permalink_%s_histo_used_by_%s'] = 'Le lien permanent %s a été utilisé précédemment par la catégorie %s. Veuillez l\'effacer de l\'historique des liens permanents';
+$lang['Permalink_name_rule'] = 'Le lien permanent ne doit contenir des caractères que parmi "a-zA-Z0-9", "-", "_" ou "/". Il ne doit pas être numérique ou commencer par un nombre suivi par "-"';
+$lang['Permalink %s is already used by category %s'] = 'Le lien permanent %s est dèja utilisé par la catégorie %s';
+$lang['Permalink history'] = 'Historique des liens permanents';
+$lang['Permalinks'] = 'Liens permanents';
+$lang['Permission denied'] = 'Accès interdit';
+$lang['Permission granted thanks to a group'] = 'Accès autorisé grâce à l\'appartenance aux groupes';
+$lang['Permission granted'] = 'Accès autorisé';
+$lang['Picture informations updated'] = 'Informations de l\'image mises à jour';
+$lang['Plugins'] = 'Plugins';
+$lang['Position'] = 'Position';
+$lang['Preferences'] = 'Préférences';
+$lang['Properties'] = 'Propriétés';
+$lang['Random picture'] = 'Au hasard';
+$lang['Rate date'] = 'Date de notation';
+$lang['Rating by guests'] = 'Notation par les invités';
+$lang['Rating'] = 'Notation';
+$lang['Reject All'] = 'Tout rejeter';
+$lang['Reject'] = 'Rejeter';
+$lang['Representant'] = 'Représentant';
+$lang['Representation of categories'] = 'Représentation des catégories';
+$lang['Representative'] = 'Représentant';
+$lang['Represents'] = 'Représente';
+$lang['Save order'] = 'Sauvegarder l\'ordre';
+$lang['Save to permalink history'] = 'Sauvegarder dans l\'historique des liens permanents';
+$lang['Select at least one category'] = 'Sélectionner au moins une catégorie';
+$lang['Select at least one picture'] = 'Sélectionner au moins une image';
+$lang['Select at least one user'] = 'Sélectionner au moins un utilisateur';
+$lang['Show info'] = 'Montrer les informations';
+$lang['Site manager'] = 'Gestionnaire des sites';
+$lang['Status'] = 'Statut';
+$lang['Statistics'] = 'Statistiques';
+$lang['Storage category'] = 'Catégorie de stockage';
+$lang['Sum of rates'] = 'Somme des notes';
+$lang['Tag "%s" already exists'] = 'Le tag "%s" existe déjà';
+$lang['Tag "%s" was added'] = 'Le tag "%s" a été ajouté';
+$lang['Tag selection'] = 'Sélection de tags';
+$lang['Take selected elements out of caddie'] = 'Sortir les éléments sélectionnés du panier';
+$lang['The %d following tag were deleted'] = 'Le tag suivant a été supprimé';
+$lang['The %d following tags were deleted'] = 'Les %d tags suivants ont été supprimés';
+$lang['Unable to check for upgrade.'] = 'Impossible de connaître la dernière version.';
+$lang['Uninstall'] = 'Désinstaller';
+$lang['Use default sort order']='Utiliser l\'ordre de tri des images par défaut (défini dans le fichier de configuration)';
+$lang['User comments validation'] = 'Validation des commentaires d\'utilisateurs';
+$lang['Users'] = 'Utilisateurs';
+$lang['Validate All'] = 'Tout valider';
+$lang['Validate'] = 'Valider';
+$lang['Validation'] = 'Validation';
+$lang['Version'] = 'Version';
+$lang['Virtual categories movement'] = 'Déplacement de catégories virtuelles';
+$lang['Virtual categories to move'] = 'Catégories virtuelles à déplacer';
+$lang['Virtual category name'] = 'Nom de la catégorie virtuelle';
+$lang['Webmaster cannot be deleted'] = 'Le webmestre ne peut pas être supprimé';
+$lang['You are running on development sources, no check possible.'] = 'Vous travaillez avec les sources de développement, impossible de vérifier la dernière version.';
+$lang['You cannot delete your account'] = "Vous ne pouvez pas supprimer votre compte";
+$lang['You cannot move a category in its own sub category'] = 'Vous ne pouvez pas déplacer une catégorie dans sa propre sous-catégorie';
+$lang['You need to confirm deletion'] = 'Vous devez confirmer la suppression';
+$lang['add tags'] = 'ajouter les tags';
+$lang['adviser'] = 'Conseiller';
+$lang['associate to category'] = 'associer à la catégorie';
+$lang['associate to group'] = 'associer au groupe';
+$lang['authorized'] = 'Autorisés';
+$lang['cat_add'] = 'Ajouter une catégorie virtuelle';
+$lang['cat_comments_title'] = 'Autoriser les utilisateurs à ajouter des commentaires dans les catégories sélectionnées';
+$lang['cat_error_name'] = 'Le nom de la catégorie ne doit pas être vide';
+$lang['cat_lock_title'] = 'Verrouiller les catégories';
+$lang['cat_private'] = 'Catégorie privée';
+$lang['cat_public'] = 'Catégorie publique';
+$lang['cat_representant'] = 'Trouver un nouveau représentant au hasard';
+$lang['cat_security'] = 'Publique / Privée';
+$lang['cat_status_title'] = 'Gérer le type d\'accès pour les catégories sélectionnées';
+$lang['cat_upload_title'] = 'Sélectionner les catégories autorisées à l\'ajout';
+$lang['cat_virtual_added'] = 'Catégorie virtuelle ajoutée';
+$lang['cat_virtual_deleted'] = 'Catégorie virtuelle supprimée';
+$lang['category'] = 'Catégorie';
+$lang['conf_access'] = 'Type d\'accès';
+$lang['conf_comments_title'] = 'Commentaires';
+$lang['conf_confirmation'] = 'Informations enregistrées dans la base de données';
+$lang['conf_display'] = 'Affichage par défaut';
+$lang['conf_history_title'] = 'Historique';
+$lang['conf_gallery_url_error'] = 'L\'adresse de la galerie n\'est pas valide.';
+$lang['conf_main_title'] = 'Principale';
+$lang['conf_nb_comment_page_error'] = 'Le nombre de commentaires d\'utilisateurs par page doit être compris entre 5 et 50.';
+$lang['config'] = 'Configuration';
+$lang['confirm'] = 'confirmer';
+$lang['Date'] = 'Date';
+$lang['delete category'] = 'supprimer la catégorie';
+$lang['dissociate from category'] = 'dissocier de la catégorie';
+$lang['dissociate from group'] = 'dissocier du groupe';
+$lang['edit category permissions'] = 'Modifier les permissions de la catégorie';
+$lang['editcat_confirm'] = 'Les informations de la catégorie ont été mises à jour avec succès.';
+$lang['editcat_uploadable'] = 'Autoriser l\'ajout d\'images';
+$lang['elements per page'] = 'éléments par page';
+$lang['elements'] = 'éléments';
+$lang['enabled_high'] = 'Haute définition actif';
+$lang['file'] = 'Fichier';
+$lang['filesize'] = 'Poids';
+$lang['first element added on %s'] = 'premier élément ajouté le %s';
+$lang['forbidden'] = 'Interdit';
+$lang['conf_general'] = 'Générale';
+$lang['global mode'] = 'mode global';
+$lang['group "%s" added'] = 'groupe "%s" ajouté';
+$lang['group "%s" deleted'] = 'groupe "%s" supprimé';
+$lang['group "%s" updated'] = 'groupe "%s" mis à jour';
+$lang['group'] = 'groupe';
+$lang['group_add_error1'] = 'Le nom du groupe ne doit pas contenir " or \' et ne doit pas être vide.';
+$lang['group_add_error2'] = 'Ce nom est déjà utilisé par un autre groupe.';
+$lang['groups'] = 'Groupes';
+$lang['instructions'] = 'Instructions';
+$lang['is_high_disabled'] = '';
+$lang['is_high_enabled'] = 'Haute définition';
+$lang['jump to category'] = 'se rendre dans la catégorie';
+$lang['jump to image'] = 'se rendre à l\'image';
+$lang['leave'] = 'laisser';
+$lang['lock'] = 'Verrouiller';
+$lang['locked'] = 'Verrouillé';
+$lang['manage category elements'] = 'gérer les éléments de la catégorie';
+$lang['manage sub-categories'] = 'gérer les sous-catégories';
+$lang['manage'] = 'Gérer';
+$lang['maximum height'] = 'hauteur maximum';
+$lang['maximum width'] = 'largeur maximum';
+$lang['nbm_background_treatment_redirect_second'] = 'Le temps d\'exécution étant dépassé, le traitement doit continuer [Temps estimé: %d second].';
+$lang['nbm_background_treatment_redirect_seconds'] = 'Le temps d\'exécution étant dépassé, le traitement doit continuer [Temps estimé: %d secondes].';
+$lang['nbm_break_timeout_list_user'] = 'Le temps de préparation de la liste des utilisateurs pour l\'envoi est limité. Les autres utilisateurs ne sont pas listés.';
+$lang['nbm_break_timeout_send_mail'] = 'Le temps d\'envoi des mails est limité. Les autres envois de mail ont été ignorés.';
+$lang['nbm_col_check_user_send_mail'] = 'A envoyer ?';
+$lang['nbm_col_last_send'] = 'Dernier envoi';
+$lang['nbm_col_mail'] = 'email';
+$lang['nbm_col_user'] = 'Utilisateur';
+$lang['nbm_complementary_mail_content'] = 'Contenu complémentaire au mail';
+$lang['nbm_content_byebye'] = 'A bientôt,';
+$lang['nbm_content_goto_1'] = 'Rendez-vous sur ';
+$lang['nbm_content_goto_2'] = '.';
+$lang['nbm_content_hello_1'] = 'Bonjour ';
+$lang['nbm_content_hello_2'] = ',';
+$lang['nbm_content_new_elements'] = 'De nouveaux éléments ont été ajoutés ';
+$lang['nbm_content_new_elements_single'] = ' le ';
+$lang['nbm_content_new_elements_between_1'] = 'entre le ';
+$lang['nbm_content_new_elements_between_2'] = ' et le ';
+$lang['nbm_content_subscribe_by_admin'] = 'Vous venez d\'être inscrit par le webmestre du site pour recevoir la notification par mail.';
+$lang['nbm_content_subscribe_by_himself'] = 'Vous venez de vous inscrire pour recevoir la notification par mail.';
+$lang['nbm_content_subscribe_link'] = 'Pour vous inscrire';
+$lang['nbm_content_problem_contact'] = 'En cas de problèmes ou de questions, envoyer un mail à ';
+$lang['nbm_content_pb_contact_object'] = '[NBM] Problèmes ou de questions';
+$lang['nbm_content_unsubscribe_by_admin'] = 'Vous venez d\'être désinscrit par le webmestre du site pour ne plus recevoir la notification par mail.';
+$lang['nbm_content_unsubscribe_by_himself'] = 'Vous venez de vous désinscrire pour ne plus recevoir la notification par mail.';
+$lang['nbm_content_click_on'] = ', cliquez sur ';
+$lang['nbm_content_unsubscribe_link'] = 'Pour vous désinscrire';
+$lang['nbm_info_send_mail_as'] = 'Sans valeur, le titre de la galerie sera utilisé';
+$lang['nbm_item_notification'] = 'Notification';
+$lang['nbm_msg_error_sending_email_to'] = 'Erreur lors de l\'envoi du mail à %s [%s].';
+$lang['nbm_msg_mail_sent_to'] = 'Mail envoyé à %s [%s].';
+$lang['nbm_msg_n_mail_sent'] = '%s mail a été envoyé.';
+$lang['nbm_msg_n_mails_sent'] = '%s mails ont été envoyés.';
+$lang['nbm_msg_n_mail_not_send'] = '%s mail n\'a pas été envoyé.';
+$lang['nbm_msg_n_mails_not_send'] = '%s mails n\'ont pas été envoyés.';
+$lang['nbm_no_mail_to_send'] = 'Pas de mail à envoyer.';
+$lang['nbm_no_user_available_to_send_L1'] = 'Il n\'y a pas d\'utilisateur à notifier par mail.';
+$lang['nbm_no_user_available_to_send_L2'] = 'Un utilisateur est à notifier si de nouveaux éléments sont disponibles pour cet utilisateur.';
+$lang['nbm_no_user_available_to_send_L3'] = 'Il se peut aussi qu\'il n\'y ait aucun utilisateur inscrit (seul le webmaster a accès à cet onglet).';
+$lang['nbm_no_user_to send_notifications_by_mail'] = 'Pas d\'utilisateur pour envoyer des notifications par mails.';
+$lang['nbm_object_news'] = 'Nouveaux éléments ajoutés';
+$lang['nbm_object_subscribe'] = 'Inscription à la notification par mail';
+$lang['nbm_object_unsubscribe'] = 'Désinscription à la notification par mail';
+$lang['nbm_param_mode'] = 'Paramétrage';
+$lang['nbm_redirect_msg'] = 'Traitement en cours.'."\n".'Veuillez patienter...';
+$lang['nbm_repost_submit'] = 'Continuer le traitement en cours...';
+$lang['nbm_send_complementary_mail_content'] = 'Contenu complémentaire du mail';
+$lang['nbm_send_detailed_content'] = 'Ajout d\'un contenu détaillé';
+$lang['nbm_send_mail_as'] = 'Envoyer le mail en tant que';
+$lang['nbm_send_mail_to_users'] = 'Envoi de mail aux utilisateurs';
+$lang['nbm_send_mode'] = 'Envoi';
+$lang['nbm_send_options'] = 'Options';
+$lang['nbm_send_submit'] = 'Envoyer';
+$lang['nbm_subscribe_col'] = 'Inscrits';
+$lang['nbm_subscribe_mode'] = 'Inscription';
+$lang['nbm_title_param'] = 'Paramètres';
+$lang['nbm_title_send'] = 'Sélection des envois';
+$lang['nbm_title_subscribe'] = 'Inscrire/désinscrire les utilisateurs';
+$lang['nbm_unsubscribe_col'] = 'Non Inscrits';
+$lang['nbm_updated_param_count'] = '%d paramètre a été mis à jour.';
+$lang['nbm_updated_params_count'] = '%d paramètres ont été mis à jour.';
+$lang['nbm_user_change_enabled_error_on_updated_data_count'] = '%d utilisateur n\'a pas été mis à jour.';
+$lang['nbm_users_change_enabled_error_on_updated_data_count'] = '%d utilisateurs n\'ont pas été mis à jour.';
+$lang['nbm_user_change_enabled_false'] = 'L\'utilisateur %s [%s] a été supprimé de la liste des inscrits.';
+$lang['nbm_user_change_enabled_true'] = 'L\'utilisateur %s [%s] a été ajouté à la liste des inscrits.';
+$lang['nbm_user_change_enabled_updated_data_count'] = '%d utilisateur a été mis à jour.';
+$lang['nbm_users_change_enabled_updated_data_count'] = '%d utilisateurs ont été mis à jour.';
+$lang['nbm_user_not_change_enabled_false'] = 'L\'utilisateur %s [%s] n\'a pas été supprimé de la liste des inscrits.';
+$lang['nbm_user_not_change_enabled_true'] = 'L\'utilisateur %s [%s] n\'a pas été ajouté à la liste des inscrits.';
+$lang['nbm_user_x_added'] = 'Utilisateur %s [%s] ajouté.';
+$lang['nbm_warning_subscribe_unsubscribe'] = 'Attention, l\'inscription ou la désincription entraine l\'envoi de mails aux utilisateurs concernés';
+$lang['nbm_send_html_mail'] = 'Envoyer le mail au format HTML';
+$lang['nbm_send_recent_post_dates'] = 'Inclure l\'affichage des dernières images groupées par dates';
+$lang['nbm_info_send_recent_post_dates'] = 'Disponible uniquement avec le format HTML';
+$lang['no_write_access'] = 'pas d\'accès en écriture';
+$lang['path'] = 'chemin';
+$lang['permissions'] = 'Permissions';
+$lang['private'] = 'privé';
+$lang['properties'] = 'Propriétés';
+$lang['public'] = 'public';
+$lang['purge never used notification feeds'] = 'Purger les flux de notification jamais utilisés';
+$lang['purge sessions'] = 'Purger les sessions';
+$lang['randomly represented'] = 'représentant au hasard';
+$lang['registration_date'] = 'date d\'enregistrement';
+$lang['remote_site'] = 'Site distant';
+$lang['remote_site_clean'] = 'nettoyer';
+$lang['remote_site_clean_hint'] = 'supprimer le fichier listing.xml distant';
+$lang['remote_site_generate'] = 'générer le listing';
+$lang['remote_site_generate_hint'] = 'générer le fichier listing.xml sur le site distant';
+$lang['remote_site_local_create'] = 'Créer ce site';
+$lang['remote_site_local_found'] = 'Un fichier listing.xml local a été trouvé pour ';
+$lang['remote_site_local_update'] = 'lire le listing.xml local et mettre à jour';
+$lang['remote_site_test'] = 'tester';
+$lang['remote_site_test_hint'] = 'tester ce site distant';
+$lang['remote_site_uncorrect_url'] = 'L\'URL d\'un site distant doit commencer par "http" ou "https" et ne doit contenir des caractères que parmi "/", "a-zA-Z0-9", "-" ou "_"';
+$lang['remove tags'] = 'supprimer les tags';
+$lang['repair and optimize database'] = 'Réparer et optimiser la base de données';
+$lang['selection'] = 'sélection';
+$lang['set to'] = 'changer en';
+$lang['singly represented'] = 'représentant fixe';
+$lang['site_already_exists'] = 'Ce site existe déjà';
+$lang['site_create'] = 'Créer un nouveau site distant : (donner son URL vers create_listing_file.php)';
+$lang['site_created'] = 'créé';
+$lang['site_delete'] = 'supprimer';
+$lang['site_delete_hint'] = 'supprimer ce site et toutes les informations associées';
+$lang['site_deleted'] = 'supprimé';
+$lang['site_err'] = 'une erreur est survenue';
+$lang['site_err_remote_file_not_found'] = 'le fichier create_listing_file.php est introuvable sur le site distant';
+$lang['site_local'] = 'Local';
+$lang['site_remote'] = 'Distant';
+$lang['site_synchronize'] = 'synchroniser';
+$lang['site_synchronize_hint'] = 'met à jour la base de données à partir des fichiers';
+$lang['status'] = 'statut';
+$lang['storage'] = 'Répertoire';
+$lang['sub-categories'] = 'sous-catégories';
+$lang['synchronize metadata'] = 'synchroniser les méta-données';
+$lang['synchronize'] = 'synchroniser';
+$lang['target'] = 'cible';
+$lang['thumbnail'] = 'Miniature';
+$lang['title'] = 'titre';
+$lang['title_categories'] = 'Gestion des catégories';
+$lang['title_configuration'] = 'Configuration de Piwigo';
+$lang['title_default'] = 'Administration de Piwigo';
+$lang['title_edit_cat'] = 'Modifier une catégorie';
+$lang['title_groups'] = 'Gestion des groupes';
+$lang['title_liste_users'] = 'Liste des utilisateurs';
+$lang['title_picmod'] = 'Modifier les informations d\'une image';
+$lang['title_thumbnails'] = 'Création des miniatures';
+$lang['title_update'] = 'Synchronisation de la base à partir des fichiers de';
+$lang['title_upload'] = 'Images en attente de validation';
+$lang['tn_all'] = 'tout';
+$lang['tn_alone_title'] = 'image sans miniature (jpeg et png uniquement)';
+$lang['tn_err_height'] = 'la hauteur doit un entier supérieur à';
+$lang['tn_err_width'] = 'la largeur doit être un entier supérieur à';
+$lang['tn_format'] = 'pour le format de fichier';
+$lang['tn_no_missing'] = 'Aucune miniature ne manque';
+$lang['tn_no_support'] = 'Image inaccessible ou non supportée';
+$lang['tn_params_GD'] = 'version de GD';
+$lang['tn_params_title'] = 'Paramètre de miniaturisation';
+$lang['tn_results_gen_time'] = 'générée en';
+$lang['tn_results_title'] = 'Résultats de la miniaturisation';
+$lang['tn_stats'] = 'Statistiques générales';
+$lang['tn_stats_max'] = 'temps maximal';
+$lang['tn_stats_mean'] = 'temps moyen';
+$lang['tn_stats_min'] = 'temps minimal';
+$lang['tn_stats_nb'] = 'nombre de miniatures créées';
+$lang['tn_stats_total'] = 'temps total';
+$lang['tn_thisformat'] = 'pour ce format de fichier';
+$lang['unit mode'] = 'mode unitaire';
+$lang['unlocked'] = 'déverrouillée';
+$lang['unset'] = 'vider';
+$lang['up'] = 'Déplacer vers le haut';
+$lang['update categories informations'] = 'Mettre à jour les informations des catégories';
+$lang['update images informations'] = 'Mettre à jour les informations des images';
+$lang['update'] = 'Synchroniser';
+$lang['update_cats_subset'] = 'traiter uniquement une catégorie';
+$lang['update_default_title'] = 'Choisir une option';
+$lang['update_display_info'] = 'afficher un maximum d\'informations (catégories ajoutées, éléments ajoutés, catégories et éléments supprimés)';
+$lang['update_err_pwg_version_differs'] = 'La version Piwigo sur le site distant est differente';
+$lang['update_err_pwg_version_differs_info'] = 'La version de create_listing_file.php sur le site distant et Piwigo doit être la même';
+$lang['update_err_remote_listing_not_found'] = 'le fichier listing.xml est introuvable';
+$lang['update_err_remote_listing_not_found_info'] = 'le fichier listing.xml est introuvable sur le site distant. Ce fichier est generé en choisissant la commande "générer le listing" dans le gestionnaire de sites';
+$lang['update_error_list_title'] = 'Liste des erreurs';
+$lang['update_errors_caption'] = 'Légende des erreurs';
+$lang['update_infos_title'] = 'Informations détaillées';
+$lang['update_missing_file_or_dir'] = 'Erreur d\'ouverture fichier/répertoire';
+$lang['update_missing_file_or_dir_info'] = 'Le fichier ou répertoire ne peut pas être accessible (soit il n\'existe pas, soit l\'accès est refusé)';
+$lang['update_missing_tn_info'] = 'Chaque fichier image requiert une miniature. La miniature doit être présente dans le sous-répertoire "thumbnail" du répertoire de la catégorie. Le nom du fichier de la miniature doit commencer avec le paramètre de configuration "prefix_thumbnail" et l\'extension du nom du fichier doit être parmi la liste suivante :';
+$lang['update_missing_tn_short'] = 'miniature manquante';
+$lang['update_nb_del_categories'] = 'catégories supprimées de la base de données';
+$lang['update_nb_del_elements'] = 'éléments supprimés de la base de données';
+$lang['update_nb_elements_metadata_available'] = 'images candidates à la synchronisation avec les méta-données';
+$lang['update_nb_elements_metadata_sync'] = 'informations des images synchronisées avec les méta-données';
+$lang['update_nb_errors'] = 'erreurs survenues durant la synchronisation';
+$lang['update_nb_new_categories'] = 'catégories ajoutées dans la base de données';
+$lang['update_nb_new_elements'] = 'éléments ajoutés dans la base de données';
+$lang['update_nb_upd_elements'] = 'éléments mis à jour dans la base de données';
+$lang['update_part_research'] = 'Chercher les nouvelles images dans les répertoires';
+$lang['update_research_added'] = 'ajouté';
+$lang['update_research_deleted'] = 'supprimé';
+$lang['update_result_metadata'] = 'Résultat de la synchronisation des méta-données';
+$lang['update_simulate'] = 'Simuler uniquement (aucun changement dans la base de données ne sera effectué)';
+$lang['update_simulation_title'] = '[Simulation]';
+$lang['update_sync_all'] = 'répertoires + fichiers';
+$lang['update_sync_dirs'] = 'répertoires uniquement';
+$lang['update_sync_files'] = 'synchroniser la structure des fichiers avec la base de données';
+$lang['update_sync_metadata'] = 'synchroniser les informations des éléments dans la base de données à partir des méta-données des fichiers';
+$lang['update_sync_metadata_all'] = 'même les éléments déjà synchronisés';
+$lang['update_used_metadata'] = 'Méta-données employées';
+$lang['update_wrong_dirname_info'] = 'Le nom des répertoires et des fichiers ne doit être constitué que de lettres, de chiffres, de "-", "_" et "."';
+$lang['update_wrong_dirname_short'] = 'nom de fichier erroné';
+$lang['upload'] = 'Ajout';
+$lang['user "%s" added'] = 'utilisateur "%s" ajouté';
+$lang['user_status'] = 'Statut de l\'utilisateur';
+$lang['user_status_admin'] = 'Administrateur';
+$lang['user_status_generic'] = 'Générique';
+$lang['user_status_guest'] = 'Invité';
+$lang['user_status_normal'] = 'Visiteur';
+$lang['user_status_webmaster'] = 'Webmestre';
+$lang['username'] = 'nom utilisateur';
+$lang['users'] = 'Utilisateurs';
+$lang['virtual_category'] = 'Catégorie virtuelle';
+$lang['waiting'] = 'En attente';
+$lang['is_default_group'] = 'par défaut';
+$lang['toggle_is_default_group'] = 'Inverser la propriété \'groupe par défaut\'';
+$lang['Advanced_features'] = 'Fonctions avancées';
+$lang['Elements_not_linked'] = 'Eléments non liés';
+$lang['special_admin_menu'] = 'Spéciales';
+$lang['Duplicates'] = 'Fichiers portant le même nom dans plusieurs catégories physiques';
+
+$lang['Overall'] = 'Vue globale';
+$lang['Year'] = 'Année';
+$lang['Month'] = 'Mois';
+$lang['Day'] = 'Jour';
+$lang['Pages seen'] = 'Pages vues';
+$lang['Pictures'] = 'Images';
+$lang['time'] = 'Heure';
+$lang['user'] = 'Utilisateur';
+$lang['IP'] = 'IP';
+$lang['image'] = 'Element';
+$lang['section'] = 'Section';
+$lang['tags'] = 'Tags';
+$lang['conf_history_guest'] = 'Enregistrer les pages visitées par les invités';
+$lang['conf_history_user'] = 'Enregistrer les pages visitées par les utilisateurs';
+$lang['conf_history_admin'] = 'Enregistrer les pages visitées par les administrateurs';
+$lang['cat_options_title'] = 'Propriétés';
+$lang['An information email was sent to group "%s"'] = 'Un mail d\'informations a été envoyé aux membres du groupe';
+$lang['Send an information email to group members'] = 'Envoyer un mail d\'informations aux membres d\'un groupe';
+$lang['Group'] = 'Groupe';
+$lang['[%s] Come to visit the category %s'] = '[%s] Venez visiter la catégorie %s';
+$lang['Hello,'] = 'Bonjour,';
+$lang['See you soon.'] = 'A bientôt.';
+$lang['Come to discover the category:'] = 'Venez découvrir la catégorie:';
+$lang['mail_content'] = 'Contenu du mail';
+$lang['none'] = 'aucun';
+$lang['high'] = 'high';
+$lang['other'] = 'autre';
+$lang['Element type'] = "Type d'élément";
+$lang['User'] = 'Utilisateur';
+$lang['Image id'] = 'Identifiant image';
+$lang['Summary'] = 'Résumé';
+$lang['%d line filtered'] = '%d ligne filtrée';
+$lang['%d lines filtered'] = '%d lignes filtrées';
+$lang['%d guest'] = '%d invité';
+$lang['%d guests'] = '%d invités';
+$lang['Hour'] = 'Heure';
+$lang['is_the_guest'] = 'invité';
+$lang['is_the_default'] = 'valeurs par défaut';
+$lang['High filesize'] = 'Taille du fichier HR';
+// --------- Starting below: New or revised $lang ---- from version 1.7.1
+$lang['Guest cannot be deleted'] = 'L\'invité ne peut pas être supprimé';
+$lang['Default user cannot be deleted'] = 'L\'utilisateur par défaut ne peut pas être supprimé';
+$lang['purge history detail'] = 'Purger le detail de l\'historique';
+$lang['purge history summary'] = 'Purger le sommaire de l\'historique';
+$lang['c13y_title'] = 'Contrôle d\'intégrité';
+$lang['c13y_Anomaly'] = 'Anomalie';
+$lang['c13y_Correction'] = 'Correction';
+$lang['c13y_Automatic_correction'] = 'Correction automatique';
+$lang['c13y_Impossible_automatic_correction'] = 'Correction automatique impossible';
+$lang['c13y_Correction_applied_success'] = 'Correction appliquée avec succés';
+$lang['c13y_Correction_applied_error'] = 'Correction appliquée avec erreur';
+$lang['c13y_anomaly_count'] = '%d anomalie a été détectée.';
+$lang['c13y_anomalies_count'] = '%d anomalies ont été détectées.';
+$lang['c13y_anomaly_corrected_count'] = '%d anomalie a été corrigée.';
+$lang['c13y_anomalies_corrected_count'] = '%d anomalies ont été corrigées.';
+$lang['c13y_anomaly_not_corrected_count'] = '%d anomalie n\'a pas pu être corrigée.';
+$lang['c13y_anomalies_not_corrected_count'] = '%d anomalies n\'ont pu être corrigées.';
+$lang['c13y_more_info'] = 'Allez sur %s ou %s pour plus d\'informations';
+$lang['c13y_more_info_forum'] = 'le forum';
+$lang['c13y_more_info_wiki'] = 'le wiki';
+$lang['c13y_exif_anomaly'] = 'La valeur de %s n\'est pas correcte parce que l\'exif n\'est pas supporté';
+$lang['c13y_exif_correction'] = '%s doit être mis à "false" dans votre fichier config_local.inc.php';
+$lang['c13y_guest_non_existent'] = 'L\'utilisateur "invité" principal n\'existe plus';
+$lang['c13y_bad_guest_status'] = 'Le statut de l\'utilisateur "invité" principal est incorrect';
+$lang['c13y_default_non_existent'] = 'L\'utilisateur par défaut n\'existe plus';
+$lang['c13y_webmaster_non_existent'] = 'L\'utilisateur "webmestre" principal n\'existe plus';
+$lang['c13y_bad_webmaster_status'] = 'Le statut de l\'utilisateur "webmestre" principal est incorrect';
+$lang['c13y_user_created'] = 'Utilisateur "%s" créé avec comme mot de passe "%s"';
+$lang['c13y_user_status_updated'] = 'Statut de l\'utilisateur "%s" mis à jour';
+$lang['add new elements to caddie'] = 'ajouter les nouveaux éléments au panier';
+// --------- Starting below: New or revised $lang ---- from Butterfly
+$lang['no_display_thumbnail'] = 'Pas d\'affichage';
+$lang['display_thumbnail_classic'] = 'Affichage classique';
+$lang['display_thumbnail_hoverbox'] = 'Affichage lors du survol';
+$lang['Thumbnails'] = 'Miniatures';
+$lang['obligatory_user_mail_address'] = 'L\'adresse mail est obligatoire pour tous les utilisateurs';
+$lang['Minimum privacy level'] = 'Niveau minimal de confidentialité';
+$lang['Privacy level'] = 'Niveau de confidentialité';
+$lang['Level 0'] = '---';
+$lang['Level 1'] = 'Contacts';
+$lang['Level 2'] = 'Amis';
+$lang['Level 4'] = 'Famille';
+$lang['Level 8'] = 'Admins';
+$lang['c13y_maintenance'] = 'Réinitialiser les contrôles d\'intégrité';
+$lang['Check all'] = 'Tout cocher';
+$lang['Uncheck all'] = 'Tout décocher';
+$lang['c13y_check_auto'] = 'Cocher les corrections automatiques';
+$lang['c13y_submit_correction'] = 'Appliquer les corrections sélectionnées';
+$lang['c13y_submit_ignore'] = 'Ignorer les anomalies sélectionnées';
+$lang['c13y_submit_refresh'] = 'Rafraîchir';
+$lang['c13y_ignore_msg1'] = 'L\'anomalie sera ignorée jusqu\'à la prochaine version de l\'application';
+$lang['c13y_ignore_msg2'] = 'La correction de l\'anomalie annulera le fait qu\'elle soit ignorée';
+$lang['c13y_anomaly_ignored_count'] = '%d anomalie a été ignorée.';
+$lang['c13y_anomalies_ignored_count'] = '%d anomalies ont été ignorées.';
+$lang['plugins_need_update'] = 'Plugins necessitant une mise à jour';
+$lang['plugins_dontneed_update'] = 'Plugins à jour';
+$lang['plugins_cant_check'] = 'Impossible de vérifier les plugins suivants';
+$lang['plugins_actual_version'] = 'Version<br>actuelle';
+$lang['plugins_new_version'] = 'Version<br>disponible';
+$lang['plugins_auto_update'] = 'Mise à jour automatique';
+$lang['plugins_auto_install'] = 'Installation automatique';
+$lang['plugins_download'] = 'Télécharger le fichier';
+$lang['plugins_tab_list'] = 'Liste des plugins';
+$lang['plugins_tab_update'] = 'Vérifier les mises à jour';
+$lang['plugins_tab_new'] = 'Autres plugins disponibles';
+$lang['plugins_revisions'] = 'Dernières révisions';
+$lang['plugins_delete'] = 'Supprimer';
+$lang['plugins_confirm_install'] = 'Etes-vous sûr de vouloir installer ce plugin?';
+$lang['plugins_confirm_delete'] = 'Etes-vous sûr de vouloir supprimer ce plugin?';
+$lang['plugins_confirm_upgrade'] = 'Etes-vous sur de vouloir installer cette mise à jour? Vous devez vérifiez que cette mise à jour ne nécessite pas de désinstallation.';
+$lang['plugins_upgrade_ok'] = '%s a été mis à jour avec succès.';
+$lang['plugins_install_ok'] = 'Le plugin a été copié avec succès.';
+$lang['plugins_install_need_activate'] = 'Rendez-vous dans la liste des plugins pour l\'installer et l\'activer.';
+$lang['plugins_temp_path_error'] = 'Impossible de créer un fichier temporaire.';
+$lang['plugins_dl_archive_error'] = 'Impossible de récupérer l\'archive.';
+$lang['plugins_archive_error'] = 'Impossible de lire ou d\'extraire l\'archive.';
+$lang['plugins_extract_error'] = 'Une erreur est survenue pendant l\'extraction des fichiers (%s).';
+$lang['plugins_check_chmod'] = 'Vérifiez les permissions du dossier "plugins" et de ses sous-dossiers (CHMOD).';
+$lang['plugins_server_error'] = 'Impossible de se connecter au serveur.';
+$lang['Purge compiled templates'] = 'Purger les templates compilés';
+$lang['Caddie is currently empty'] = 'Le panier est actuellement vide.';
+$lang['DEMO'] = 'Démo';
+$lang['HOME'] = 'Accueil Piwigo';
+$lang['FORUM'] = 'Support';
+$lang['BUGS'] = 'Bogues';
+$lang['EXTENSIONS'] = 'Extensions';
+$lang['WIKI / DOC'] = 'Documentation';
+$lang['conf_upload_title'] = 'Téléchargement';
+$lang['Show upload link every time'] = 'Afficher le lien d\'ajout d\'image tout le temps';
+$lang['User access level to upload'] = 'Niveau d\'accès utilisateur pour télécharger';
+$lang['ACCESS_0'] = 'Accès libre';
+$lang['ACCESS_1'] = 'Accès à tous';
+$lang['ACCESS_2'] = 'Accès aux inscrits';
+$lang['ACCESS_3'] = 'Accès aux administrateurs';
+$lang['ACCESS_4'] = 'Accès aux webmestres';
+$lang['ACCESS_5'] = 'Pas d\'accès';
+$lang['A new version of Piwigo is available.'] = 'Une nouvelle version de Piwigo est disponible.';
+$lang['Piwigo Administration'] = 'Administration de Piwigo';
+$lang['Piwigo version'] = 'Version de Piwigo';
+$lang['You are running the latest version of Piwigo.'] = 'Vous utilisez la dernière version de Piwigo.';
+$lang['c13y_version_anomaly'] = 'La version de %s [%s] installée n\'est pas compatible avec la version requise [%s]';
+$lang['c13y_version_correction'] = 'Vous devez mettre à jour votre système pour profiter pleinement de l\'application sinon l\'application ne fonctionnera pas correctement, voire pas du tout';
+$lang['Deleted on'] = 'Effacé le';
+$lang['Last hit'] =  'Dernier accès';
+$lang['Hits'] = 'Utilisations';
+$lang['GD library is missing'] = 'la bibliothèque GD est manquante';
+$lang['conf_extents'] = 'Templates (modèles)';
+$lang['extend_for_templates'] = 'Etendre les templates';
+$lang['Replacement of original templates'] = 'Remplacement des templates d\'origine par vos templates adaptés du dossier template-extension';
+$lang['Replacers'] = 'Remplaçants (templates modifiés)';
+$lang['Original templates'] = 'Templates d\'origine';
+$lang['Optional URL keyword'] = 'Paramètre facultatif de l\'URL';
+$lang['Templates recorded.'] = 'La configuration des templates a été enregistrée.';
+$lang['Optimizations completed'] = 'Toutes les optimisations ont été réalisées avec succès.';
+$lang['Optimizations errors'] = 'Certaines optimisations se sont terminées avec des erreurs.';
+$lang['delete this comment'] = 'supprimer ce commentaire';
+$lang['link_info_image'] = 'Modifier les informations';
+$lang['edit category informations'] = 'éditer les informations de cette catégorie';
+$lang['nothing'] = 'rien';
+$lang['overrides existing values with empty ones'] = 'écraser les données existantes avec des données vides';
+$lang['manage image ranks'] = 'gérer l\'ordre des images';
+$lang['Manage image ranks'] = 'Gérer l\'ordre des images';
+$lang['Edit ranks'] = 'Modifier l\'ordre';
+$lang['No element in this category'] = 'Aucun élément dans cette catégorie';
+$lang['Images manual order was saved'] = 'L\'ordre manuel des images a été sauvé';
+$lang['ranks'] = 'rangs';
+$lang['Drag to re-order'] = 'Cliquer-glisser pour ré-organiser';
+$lang['Unable to retrieve server informations since allow_url_fopen is disabled.'] = 'Impossible de se connecter au server car la fonction allow_url_fopen est désactivée.';
+$lang['Quick Local Synchronization'] = 'Synchronisation Rapide';
+$lang['No photo can be deleted'] = 'Aucune photo ne peut être supprimée';
+$lang['Note: Only deletes photos added with pLoader'] = 'Note: seules les photos ajoutées via pLoader peuvent être supprimées';
+$lang['Delete selected photos'] = 'Supprimer les photos';
+$lang['%d photo was deleted'] = '%d photo a été supprimée';
+$lang['%d photos were deleted'] = '%d photos ont été supprimées';
+$lang['Bound template'] = 'Template rattaché';
+$lang['Downloads'] = 'Téléchargements';
+$lang['Released on'] = 'Ajouté le';
+$lang['Number of downloads'] = 'Nombre de téléchargements';
+?>
Index: /tags/2.0.2/language/fr_FR/common.lang.php
===================================================================
--- /tags/2.0.2/language/fr_FR/common.lang.php	(revision 3278)
+++ /tags/2.0.2/language/fr_FR/common.lang.php	(revision 3278)
@@ -0,0 +1,368 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Langage informations
+$lang_info['language_name'] = 'Français';
+$lang_info['country'] = 'France';
+$lang_info['direction'] = 'ltr';
+$lang_info['code'] = 'fr';
+$lang_info['zero_plural'] = false;
+
+$lang['%.2f (rated %d times, standard deviation = %.2f)'] = '%.2f (noté %d fois, écart type = %.2f)';
+$lang['%d Kb'] = '%d Ko';
+$lang['%d category updated'] = '%d catégorie mise à jour';
+$lang['%d categories updated'] = '%d catégories mises à jour';
+$lang['%d comment to validate'] = '%d commentaire utilisateur à valider';
+$lang['%d comments to validate'] = '%d commentaires utilisateur à valider';
+$lang['%d new comment'] = '%d nouveau commentaire utilisateur';
+$lang['%d new comments'] = '%d nouveaux commentaires utilisateur';
+$lang['%d comment'] = '%d commentaire';
+$lang['%d comments'] = '%d commentaires';
+$lang['%d hit'] = 'vue %d fois';
+$lang['%d hits'] = 'vue %d fois';
+$lang['%d new element'] = '%d nouvelle image';
+$lang['%d new elements'] = '%d nouvelles images';
+$lang['%d new user'] = '%d nouvel utilisateur';
+$lang['%d new users'] = '%d nouveaux utilisateurs';
+$lang['%d waiting element'] = '%d élément en attente';
+$lang['%d waiting elements'] = '%d éléments en attente';
+$lang['About'] = 'À propos';
+$lang['All tags must match'] = 'Tous les tags doivent correspondre';
+$lang['All tags'] = 'Tous les tags';
+$lang['Any tag'] = 'N\'importe quel tag';
+$lang['At least one listed rule must be satisfied.'] = 'Au moins un des critères doit être satisfait.';
+$lang['At least one tag must match'] = 'Au moins un tag doit correspondre';
+$lang['Author'] = 'Auteur';
+$lang['Average rate'] = 'Note moyenne';
+$lang['Categories'] = 'Catégories';
+$lang['Category'] = 'Catégorie';
+$lang['Close this window'] = 'Fermer cette fenêtre';
+$lang['Complete RSS feed'] = 'Flux RSS complet (images, commentaires)';
+$lang['Confirm Password'] = 'Confirmer le mot de passe';
+$lang['Connection settings'] = 'Paramètres de connexion';
+$lang['Connection'] = 'Connexion';
+$lang['Contact webmaster'] = 'Contacter le webmestre';
+$lang['Create a new account'] = 'Créer un nouveau compte';
+$lang['Created on'] = 'Créée le';
+$lang['Creation date'] = 'Date de création';
+$lang['Current password is wrong'] = 'Erreur sur le mot de passe actuel';
+$lang['Dimensions'] = 'Dimensions';
+$lang['Display'] = 'Affichage';
+$lang['Each listed rule must be satisfied.'] = 'Chaque critère doit être satisfait';
+$lang['Email address is missing'] = 'L\'adresse e-mail manque';
+$lang['Email address'] = 'Adresse e-mail';
+$lang['Enter your personnal informations'] = 'Entrer vos informations personnelles';
+$lang['Error sending email'] = 'Erreur à l\'envoi du mail';
+$lang['File name'] = 'Nom du fichier';
+$lang['File'] = 'Fichier';
+$lang['Filesize'] = 'Poids';
+$lang['Filter and display'] = 'Filtrer et afficher';
+$lang['Filter'] = 'Filtre';
+$lang['Forgot your password?'] = 'Mot de passe oublié ?';
+$lang['Go through the gallery as a visitor'] = 'Parcourir la galerie en tant que visiteur';
+$lang['Help'] = 'Aide';
+$lang['Identification'] = 'Identification';
+$lang['Image only RSS feed'] = 'Flux RSS des images';
+$lang['Keyword'] = 'Mot-clef';
+$lang['Links'] = 'Liens';
+$lang['Mail address'] = $lang['Email address'];
+$lang['N/A'] = 'non disponible';
+$lang['New on %s'] = 'Nouveau le %s';
+$lang['New password confirmation does not correspond'] = 'Erreur de confirmation de mot de passe';
+$lang['New password sent by email'] = 'Nouveau mot de passe envoyé par e-mail';
+$lang['No email address'] = 'Pas d\'adresse e-mail';
+$lang['No user matches this email address'] = 'Cette adresse e-mail ne correspond à aucun utilisateur classique';
+$lang['Notification'] = 'Notification';
+$lang['Number of items'] = 'Nombre d\'élément';
+$lang['Original dimensions'] = 'Dimensions d\'origine';
+$lang['Password forgotten'] = 'Mot de passe oublié';
+$lang['Password'] = 'Mot de passe';
+$lang['Post date'] = 'Date d\'ajout';
+$lang['Posted on'] = 'Ajoutée le';
+$lang['Profile'] = 'Profil';
+$lang['Quick connect'] = 'Connexion rapide';
+$lang['RSS feed'] = 'flux RSS';
+$lang['Rate'] = 'Note';
+$lang['Register'] = 'S\'enregistrer';
+$lang['Registration'] = 'Enregistrement';
+$lang['Related tags'] = 'Tags liés';
+$lang['Reset'] = 'Annuler';
+$lang['Retrieve password'] = 'Récupérer un mot de passe';
+$lang['Search rules'] = 'Critères de recherche';
+$lang['Search tags'] = 'Rechercher les tags';
+$lang['Search'] = 'Rechercher';
+$lang['See available tags'] = 'Voir les tags disponibles';
+$lang['Send new password'] = 'Envoyer le nouveau mot de passe';
+$lang['Since'] = 'Depuis';
+$lang['Sort by'] = 'Trier selon';
+$lang['Sort order'] = 'Ordre de tri';
+$lang['Tag'] = 'Tag';
+$lang['Tags'] = 'Tags';
+$lang['The RSS notification feed provides notification on news from this website : new pictures, updated categories, new comments. Use a RSS feed reader.'] = 'Le flux RSS notifie les événements de la galerie : nouvelles images, catégories mises à jour, nouveaux commentaires utilisateur. À utiliser avec un lecteur de flux RSS.';
+$lang['Unknown feed identifier'] = 'Identifiant de flux inconnu';
+$lang['User comments'] = 'Commentaires utilisateur';
+$lang['Username'] = 'Nom d\'utilisateur';
+$lang['Visits'] = 'Visites';
+$lang['Webmaster'] = 'Webmestre';
+$lang['Week %d'] = 'Semaine %d';
+$lang['about_page_title'] = 'À propos de Piwigo';
+$lang['access_forbiden'] = 'Vous n\'êtes pas autorisé sur la page demandée';
+$lang['add to caddie'] = 'ajouter au panier';
+$lang['add_favorites_hint'] = 'ajouter cette image à vos favoris';
+$lang['admin'] = 'Administration';
+$lang['adviser_mode_enabled'] = 'Mode conseiller actif';
+$lang['all'] = 'tout';
+$lang['ascending'] = 'croissant';
+$lang['author(s) : %s'] = 'auteur(s) : %s';
+$lang['auto_expand'] = 'Développer toutes les catégories';
+$lang['became available after %s (%s)'] = 'mis à disposition après le %s (%s)';
+$lang['became available before %s (%s)'] = 'mis à disposition avant le %s (%s)';
+$lang['became available between %s (%s) and %s (%s)'] = 'mis à disposition entre le %s (%s) et le %s (%s)';
+$lang['became available on %s'] = 'mis à disposition le %s';
+$lang['best_rated_cat'] = 'Mieux notées';
+$lang['best_rated_cat_hint'] = 'afficher les images les mieux notées';
+$lang['caddie'] = 'Panier';
+$lang['calendar'] = 'Calendrier';
+$lang['calendar_any'] = 'Tout';
+$lang['calendar_hint'] = 'affichage année par année, mois par mois, jour par jour';
+$lang['calendar_picture_hint'] = 'afficher les images du ';
+$lang['calendar_view'] = 'Vue';
+$lang['chronology_monthly_calendar'] = 'Calendrier mensuel';
+$lang['chronology_monthly_list'] = 'Liste mensuelle';
+$lang['chronology_weekly_list'] = 'Liste hebdomadaire';
+$lang['click_to_redirect'] = 'Cliquez ici si votre navigateur ne vous redirige pas.';
+$lang['comment date'] = 'date du commentaire';
+$lang['comment'] = 'Commentaire';
+$lang['comment_added'] = 'Votre commentaire a été enregistré';
+$lang['comment_anti-flood'] = 'Système anti-abus : merci de patienter avant d\'ajouter un nouveau commentaire';
+$lang['comment_not_added'] = 'Votre commentaire n\'a pas été enregistré parce qu\'il ne vérifie pas les règles de validation';
+$lang['comment_to_validate'] = 'Un administrateur doit valider votre commentaire afin qu\'il soit visible.';
+$lang['comment_user_exists'] = 'Ce nom d\'utilisateur est déjà pris';
+$lang['comments'] = 'Commentaires';
+$lang['comments_add'] = 'Ajouter un commentaire';
+$lang['created after %s (%s)'] = 'créée après le %s (%s)';
+$lang['created before %s (%s)'] = 'créée avant le %s (%s)';
+$lang['created between %s (%s) and %s (%s)'] = 'créée entre le %s (%s) et le %s (%s)';
+$lang['created on %s'] = 'créée le %s';
+$lang['customize'] = 'Personnaliser';
+$lang['customize_page_title'] = 'Personnalisation de votre affichage ';
+$lang['day'][0] = 'Dimanche';
+$lang['day'][1] = 'Lundi';
+$lang['day'][2] = 'Mardi';
+$lang['day'][3] = 'Mercredi';
+$lang['day'][4] = 'Jeudi';
+$lang['day'][5] = 'Vendredi';
+$lang['day'][6] = 'Samedi';
+$lang['default_sort'] = 'Par défaut';
+$lang['del_favorites_hint'] = 'supprimer cette image de vos favoris';
+$lang['delete'] = 'Supprimer';
+$lang['descending'] = 'décroissant';
+$lang['download'] = 'télécharger';
+$lang['download_hint'] = 'télécharger ce fichier';
+$lang['edit'] = 'éditer';
+$lang['err_date'] = 'date erronée';
+$lang['excluded'] = 'exclus';
+$lang['favorite_cat'] = 'Mes favorites';
+$lang['favorite_cat_hint'] = 'afficher mes images favorites';
+$lang['favorites'] = 'Favoris';
+$lang['first_page'] = 'Première';
+$lang['gallery_locked_message'] = 'La galerie est verrouillée pour cause de maintenance. Revenir plus tard.';
+$lang['generation_time'] = 'Page fabriquée en';
+$lang['guest'] = 'visiteur';
+$lang['hello'] = 'Bonjour';
+$lang['hint_admin'] = 'disponible uniquement pour les administrateurs';
+$lang['hint_category'] = 'montre les images à la racine de cette catégorie';
+$lang['hint_comments'] = 'Voir les derniers commentaires utilisateur';
+$lang['hint_customize'] = 'personnaliser l\'apparence de la galerie';
+$lang['hint_search'] = 'recherche';
+$lang['home'] = 'Accueil';
+$lang['identification'] = 'Identification';
+$lang['images_available_cpl'] = 'dans cette catégorie';
+$lang['images_available_cat'] = 'dans %d sous-catégorie';
+$lang['images_available_cats'] = 'dans %d sous-catégories';
+$lang['included'] = 'inclus';
+$lang['invalid_pwd'] = 'Mot de passe invalide !';
+$lang['language'] = 'Langue';
+$lang['last %d days'] = '%d derniers jours';
+$lang['last_page'] = 'Dernière';
+$lang['logout'] = 'Déconnexion';
+$lang['mail_address'] = $lang['Email address'];
+$lang['mandatory'] = 'obligatoire';
+$lang['maxheight'] = 'Hauteur maximum des images';
+$lang['maxheight_error'] = 'La hauteur maximum des images doit être supérieure à 50';
+$lang['maxwidth'] = 'Largeur maximum des images';
+$lang['maxwidth_error'] = 'La largeur des images doit être supérieure à 50';
+$lang['mode_created_hint'] = 'afficher un calendrier par date de création';
+$lang['mode_flat_hint'] = 'afficher à plat les éléments des catégories et des sous-catégories';
+$lang['mode_normal_hint'] = 'retourner à la vue normale';
+$lang['mode_posted_hint'] = 'afficher un calendrier par date d\'ajout';
+$lang['month'][10] = 'Octobre';
+$lang['month'][11] = 'Novembre';
+$lang['month'][12] = 'Décembre';
+$lang['month'][1] = 'Janvier';
+$lang['month'][2] = 'Février';
+$lang['month'][3] = 'Mars';
+$lang['month'][4] = 'Avril';
+$lang['month'][5] = 'Mai';
+$lang['month'][6] = 'Juin';
+$lang['month'][7] = 'Juillet';
+$lang['month'][8] = 'Août';
+$lang['month'][9] = 'Septembre';
+$lang['most_visited_cat'] = 'Plus vues';
+$lang['most_visited_cat_hint'] = 'afficher les images les plus vues';
+$lang['nb_image_line_error'] = 'Le nombre d\'images par ligne doit être un entier non nul';
+$lang['nb_image_per_row'] = 'Nombre de miniatures par ligne';
+$lang['nb_line_page_error'] = 'Le nombre de lignes par page doit être un entier non nul';
+$lang['nb_row_per_page'] = 'Nombre de lignes par page';
+$lang['nbm_unknown_identifier'] = 'Identifiants inconnus';
+$lang['new_password'] = 'Nouveau mot de passe';
+$lang['new_rate'] = 'Votez pour cette image';
+$lang['next_page'] = 'Suivante';
+$lang['no_category'] = 'Accueil';
+$lang['no_rate'] = 'pas de note';
+$lang['note_filter_day'] = 'L\'ensemble des éléments est filtré pour n\'afficher que les éléments récents de moins de %d jour.';
+$lang['note_filter_days'] = 'L\'ensemble des éléments est filtré pour n\'afficher que les éléments récents de moins de %d jours.';
+$lang['password updated'] = 'mot de passe mis à jour';
+$lang['periods_error'] = 'La période de nouveauté doit être un entier positif';
+$lang['picture'] = 'image';
+$lang['picture_high'] = 'Cliquer sur l\'image pour la visualiser en haute définition';
+$lang['picture_show_metadata'] = 'Montrer les méta-données du fichier';
+$lang['powered_by'] = 'Propulsé par';
+$lang['preferences'] = 'Préférences';
+$lang['previous_page'] = 'Précédente';
+$lang['random_cat'] = 'Images au hasard';
+$lang['random_cat_hint'] = 'afficher un ensemble aléatoire d\'images';
+$lang['recent_cats_cat'] = 'Catégories récentes';
+$lang['recent_cats_cat_hint'] = 'afficher les catégories récemment mises à jour ou créées';
+$lang['recent_period'] = 'Période récente';
+$lang['recent_pics_cat'] = 'Images récentes';
+$lang['recent_pics_cat_hint'] = 'afficher les images les plus récentes';
+$lang['redirect_msg'] = 'Redirection...';
+$lang['reg_err_login1'] = 'S\'il vous plaît, entrer un nom utilisateur';
+$lang['reg_err_login2'] = 'le nom utilisateur ne doit pas se terminer par un espace';
+$lang['reg_err_login3'] = 'le nom utilisateur ne doit pas commencer par un espace';
+$lang['reg_err_login5'] = 'ce nom utilisateur est déjà pris';
+$lang['reg_err_mail_address'] = 'l\'adresse e-mail doit être de la forme xxx@yyy.eee (exemple : jack@altern.org)';
+$lang['reg_err_pass'] = 'S\'il vous plaît, entrez à nouveau votre mot de passe';
+$lang['remember_me'] = 'Connexion auto';
+$lang['remove this tag'] = 'enlever ce tag de la liste';
+$lang['representative'] = 'Représentante';
+$lang['return to homepage'] = 'retour à la page d\'accueil';
+$lang['search_author'] = 'Rechercher un auteur';
+$lang['search_categories'] = 'Rechercher dans les catégories';
+$lang['search_date'] = 'Recherche par date';
+$lang['search_date_from'] = 'Date';
+$lang['search_date_to'] = 'Date de fin';
+$lang['search_date_type'] = 'Type de date';
+$lang['search_keywords'] = 'Recherche de mot';
+$lang['search_mode_and'] = 'Rechercher tous les mots';
+$lang['search_mode_or'] = 'Rechercher un des mots';
+$lang['search_one_clause_at_least'] = 'Requête vide. Aucun critère fourni.';
+$lang['search_options'] = 'Options de recherche';
+$lang['search_result'] = 'Résultats de recherche';
+$lang['search_subcats_included'] = 'Rechercher dans les sous-catégories';
+$lang['search_title'] = 'Recherche';
+$lang['searched words : %s'] = 'mots recherchés : %s';
+$lang['send_mail'] = 'Contacter';
+$lang['set as category representative'] = 'Choisir comme représentante de cette catégorie';
+$lang['show_nb_comments'] = 'Montrer le nombre de commentaires';
+$lang['show_nb_hits'] = 'Montrer le nombre de visualisations';
+$lang['slideshow'] = 'Diaporama';
+$lang['slideshow_stop'] = 'arrêter le diaporama';
+$lang['special_categories'] = 'Spéciales';
+$lang['sql_queries_in'] = 'requêtes SQL en';
+$lang['start_filter_hint'] = 'n\'afficher que les éléments récents';
+$lang['stop_filter_hint'] = 'retourner à l\'affichage de tous les éléments';
+$lang['the beginning'] = 'le début';
+$lang['theme'] = 'Thème de l\'interface';
+$lang['thumbnails'] = 'Miniatures';
+$lang['title_menu'] = 'Menu';
+$lang['title_send_mail'] = 'Un commentaire sur le site';
+$lang['today'] = 'aujourd\'hui';
+$lang['update_rate'] = 'Mettre à jour votre note';
+$lang['update_wrong_dirname'] = 'mauvais nom de répertoire';
+$lang['upload_advise_filesize'] = 'le poids de l\'image ne doit dépasser : ';
+$lang['upload_advise_filetype'] = 'le format de l\'image doit être jpg, png ou gif';
+$lang['upload_advise_height'] = 'la hauteur de l\'image ne doit pas dépasser : ';
+$lang['upload_advise_thumbnail'] = 'Optionnel, mais recommandé : choisir une miniature à associer ';
+$lang['upload_advise_width'] = 'la largeur de l\'image ne doit pas dépasser : ';
+$lang['upload_author'] = 'Auteur';
+$lang['upload_cannot_upload'] = 'impossible de transférer le fichier sur le serveur';
+$lang['upload_err_username'] = 'nom d\'utilisateur manquant';
+$lang['upload_file_exists'] = 'ce fichier existe déjà';
+$lang['upload_filenotfound'] = 'le format du fichier n\'est pas un format d\'image';
+$lang['upload_forbidden'] = 'impossible d\'ajouter une image dans cette catégorie';
+$lang['upload_name'] = 'Nom de l\'image';
+$lang['upload_picture'] = 'Ajouter une image';
+$lang['upload_successful'] = 'Image ajoutée avec succès, un administrateur doit valider l\'ajout pour le rendre visible';
+$lang['upload_title'] = 'Ajouter une image';
+$lang['useful when password forgotten'] = 'utile en cas d\'oubli de mot de passe';
+$lang['qsearch'] = 'Recherche rapide';
+$lang['Connected user: %s'] = 'Utilisateur connecté: %s';
+$lang['IP: %s'] = 'IP: %s';
+$lang['Browser: %s'] = 'Navigateur: %s';
+$lang['Author: %s'] = 'Auteur: %s';
+$lang['Comment: %s'] = 'Commentaire: %s';
+$lang['Delete: %s'] = 'Suppression: %s';
+$lang['Validate: %s'] = 'Validation: %s';
+$lang['Comment by %s'] = 'Commentaire par %s';
+$lang['User: %s'] = 'Utilisateur: %s';
+$lang['Email: %s'] = 'Email: %s';
+$lang['Admin: %s'] = 'Administration: %s';
+$lang['Registration of %s'] = 'Enregistrement de %s';
+$lang['Category: %s'] = 'Catégorie: %s';
+$lang['Picture name: %s'] = 'Nom de l\'image: %s';
+$lang['Creation date: %s'] = 'Date de création: %d';
+$lang['Waiting page: %s'] = 'Page en attente: %s';
+$lang['Picture uploaded by %s'] = 'Image téléchargée par %s';
+// --------- Starting below: New or revised $lang ---- from version 1.7.1
+$lang['guest_must_be_guest'] = 'Statut de l\'utilisateur "guest" non conforme, utilisation du statut par défaut. Veuillez prévenir le webmestre.';
+// --------- Starting below: New or revised $lang ---- from Butterfly (2.0)
+$lang['Administrator, webmaster and special user cannot use this method'] = 'Administrateur, webmestre et utilisateur spécial ne peuvent pas utiliser cette méthode';
+$lang['reg_err_mail_address_dbl'] = 'un utilisateur utilise déjà cette adresse e-mail';
+$lang['Category results for'] = 'Résultats des catégories pour';
+$lang['Tag results for'] = 'Résultats des tags pour';
+$lang['from %s to %s'] = 'du %s au %s';
+$lang['start_play'] = 'Lecture du diaporama';
+$lang['stop_play'] = 'Pause du diaporama';
+$lang['start_repeat'] = 'Répeter le diaporama';
+$lang['stop_repeat'] = 'Ne pas répeter le diaporama';
+$lang['inc_period'] = 'Ralentir la vitesse du diaporama';
+$lang['dec_period'] = 'Accélerer la vitesse du diaporama';
+$lang['Submit'] = 'Valider';
+$lang['Yes'] = 'Oui';
+$lang['No'] = 'Non';
+$lang['%d element']='%d image';
+$lang['%d elements']='%d images';
+$lang['%d element are also linked to current tags'] = '%d image est également liée aux tags courants';
+$lang['%d elements are also linked to current tags'] = '%d images sont également liées aux tags courants';
+$lang['See elements linked to this tag only'] = 'Voir les images liées uniquement à ce tag';
+$lang['elements posted during the last %d days'] = 'images ajoutées au cours de %d derniers jours';
+$lang['Choose an image'] = 'Choisir une image à ajouter';
+$lang['Piwigo Help'] = 'Aide de Piwigo';
+$lang['Rank'] = 'Rang';
+$lang['group by letters'] = 'regrouper par lettres';
+$lang['letters'] = 'lettres';
+$lang['show tag cloud'] = 'montrer le nuage de tags';
+$lang['cloud'] = 'nuage';
+?>
Index: /tags/2.0.2/language/fr_FR/help.html
===================================================================
--- /tags/2.0.2/language/fr_FR/help.html	(revision 3278)
+++ /tags/2.0.2/language/fr_FR/help.html	(revision 3278)
@@ -0,0 +1,330 @@
+<div class="instructions">
+<h2>Aide</h2>
+
+<div id="instructionPLoader" class="instructionBlock">
+  <div
+    id="pLoader_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('pLoader_header', 'pLoader_content')"
+  ><span>
+    Ajouter des photos avec pLoader
+  </span></div>
+  <div
+    id="pLoader_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+    <p><a href="http://fr.piwigo.org/ext/extension_view.php?eid=270">pLoader pour Windows</a> ou <a href="http://fr.piwigo.org/ext/extension_view.php?eid=269">pLoader pour Linux</a> : description, téléchargement et détails des nouvelles versions.</p>
+    <ol>
+      <li>Créez un répertoire "upload" à côté du répertoire "galleries" sur votre installation de Piwigo, avec un accès en écriture.</li>
+      <li>Installez pLoader sur votre ordinateur, démarrez le et remplissez les paramètres de connection : l'URL de votre galerie, votre nom d'utilisateur et votre mot de passe.</li>
+      <li>Ajoutez des photos dans la sélection par glisser/déposer depuis votre navigateur de fichiers.</li>
+      <li>Créez une catégorie et sélectionnez la.</li>
+      <li>Sélectionnez des photos.</li>
+      <li>Cliquez sur la flêche verte pour charger les photos dans votre galerie.</li>
+    </ol>
+    <p>Bravo ! Vous avez créé avec succès la première catégorie de votre galerie.</p>
+  </div> <!-- pLoader_content -->
+</div> <!-- instructionPLoader -->
+
+<div id="instructionFTP" class="instructionBlock">
+  <div
+    id="FTP_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('FTP_header', 'FTP_content')"
+  ><span>
+    Ajouter des photos par FTP
+  </span></div>
+  <div
+    id="FTP_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+
+<h3>Démarrage rapide</h3>
+
+<ol>
+  <li>Créez un répertoire sur votre ordinateur.</li>
+
+  <li>Copiez des photos à l'intérieur de ce répertoire, puis redimensionnez les pour un affichage sur le web. <em>Attention</em> : le nom des répertoires et des fichiers ne doit contenir que des lettres, des chiffres et les caractères  "-", "_" or ".". Pas d'espace ou de caractères accentués.</li>
+
+  <li>Avec un client FTP, copiez le répertoire dans le répertoire "galleries" de votre installation de Piwigo.</li>
+
+  <li>Connectez vous à votre installation de Piwigo et rendez vous sur <span class="pwgScreen">Administration &raquo; Images &raquo; Miniatures</span> pour créer les miniatures manquantes.</li>
+
+  <li>Rendez vous sur <span class="pwgScreen">Administration</span> et cliquez sur le gros bouton de synchronisation.</li>
+</ol>
+
+<p>Bravo ! Vous avez créé avec succès la première catégorie de votre galerie.</p>
+
+<h3>Organisation des répertoires et des fichiers</h3>
+
+<ul>
+
+  <li>
+
+    <p>Les répertoires représentant les catégories sont dans le répertoire
+"galleries". Ci-dessous l'arbre des répertoires d'une très petite galerie
+(mais utilisant de nombreuses fonctionnalités) : </p>
+  
+<pre>
+.
+|-- admin
+|-- doc
+|-- galleries
+|   |-- categorie-1
+|   |   |-- categorie-1.1
+|   |   |   |-- categorie-1.1.1
+|   |   |   |   |-- categorie-1.1.1.1
+|   |   |   |   |   |-- pwg_high
+|   |   |   |   |   |   +-- mariage.jpg
+|   |   |   |   |   |-- thumbnail
+|   |   |   |   |   |   +-- TN-mariage.jpg
+|   |   |   |   |   +-- mariage.jpg
+|   |   |   |   +-- categorie-1.1.1.2
+|   |   |   +-- categorie-1.1.2
+|   |   |-- categorie-1.2
+|   |   |   |-- pookie.jpg
+|   |   |   +-- thumbnail
+|   |   |       +-- TN-pookie.jpg
+|   |   +-- categorie-1.3
+|   +-- categorie-2
+|       |-- porcinet.gif
+|       |-- pwg_representative
+|       |   +-- video.jpg
+|       |-- thumbnail
+|       |   +-- TN-porcinet.jpg
+|       +-- video.avi
+|-- include
+|-- install
+|-- language
+|-- template
++-- tool</pre>
+
+  </li>
+  
+  <li>Fondamentalement, une catégorie est représentée par un répertoire à
+n'importe quel niveau sous le répertoire "galleries" de votre installation
+de Piwigo. Chaque catégorie peut contenir autant de sous-niveaux que
+désiré. Dans l'exemple ci-dessus, categorie-1.1.1.1 est à un niveau 4 de
+profondeur.</li>
+
+  <li>Fondamentalement, un élément est représenté par un fichier. Un fichier
+peut être un élément pour Piwigo si l'extension du nom du fichier est
+parmi la liste du paramètre de configuration <code>file_ext</code> (voir
+fichier <span class="filename">include/config.inc.php</span>). Un fichier
+peut être une image si son extension est parmi le paramètre de configuration
+<code>picture_ext</code>.</li>
+
+  <li>Les éléments de type image doivent avoir une miniature associée (voir la
+section suivante à propos des miniatures).</li>
+
+  <li>Les éléments de type image peuvent avoir un image en grand format
+associé.  Comme pour le fichier <span class="filename">mariage.jpg</span>
+dans l'exemple ci-dessus. Aucun préfixe n'est nécessaire sur le nom du
+fichier.</li>
+
+  <li>Les éléments non image (vidéos, sons, fichiers texte, tout ce que vous
+voulez...) sont par défaut représentés par un icône correspondant à
+l'extension du nom du fichier. Optionnellement, une miniature et un
+représentant peuvent être associés (voir le fichier <span
+class="filename">video.avi</span> dans l'exemple).</li>
+
+  <li><em>Attention</em> : le nom d'un répertoire ou d'un fichier ne doit
+être composé que de lettres, de chiffres, de "-", "_" ou ".". Pas d'espace
+ou de caractères accentués.</li>
+
+  <li><em>Conseil</em> : une catégorie peut contenir des éléments et des
+sous-catégories à la fois. Néanmoins, il est fortement conseillé pour chaque
+catégorie de choisir entre contenir des éléments <strong>ou bien</strong>
+des sous-catégories.</li>
+
+  <li>Une fois que les fichiers, les miniatures et les représentants sont
+correctement placés dans les répertoires, se rendre sur l'écran <span
+class="pwgScreen">Administration &raquo; Catégories &raquo; Synchroniser</span>.</li>
+
+</ul>
+
+<h3>Miniatures</h3>
+
+<ul>
+  
+  <li>Comme mentionné précédemment, chaque élément de type image doit être
+associé à une miniature.</li>
+
+  <li>Les miniatures sont stockées dans le sous-répertoire "thumbnail" de
+chaque répertoire représentant une catégorie. Une miniature est un fichier
+de type image (même extension du nom du fichier) dont le nom de fichier est
+préfixé par le paramètre de configuration <code>prefix_thumbnail</code>
+(voir <span class="filename">include/config.inc.php</span>).</li>
+
+  <li>Les miniatures n'ont pas besoin d'avoir la même extension que leur
+image associée (une image avec ".jpg" comme extension peut avoir une
+miniature en ".GIF" par exemple).</li>
+
+  <li>Il est conseillé d'utiliser un outil externe pour la création des
+miniatures.</li>
+
+  <li>Vous pouvez également utiliser l'outil de création de miniature
+intégré à Piwigo mais cela est déconseillé car la qualité risque
+d'être décevante et cela utilise inutilement les ressources du serveur (ce
+qui peut être un grave problème sur un serveur mutualisé).</li>
+
+  <li>Si vous choisissez d'utiliser le serveur web pour générer les
+miniatures, vous devez donner les droits en écriture sur les
+répertoires.</li>
+
+</ul>
+  </div> <!-- FTP_content -->
+</div> <!-- instructionFTP -->
+
+<div id="instructionPermissions" class="instructionBlock">
+  <div
+    id="permissions_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('permissions_header', 'permissions_content')"
+  ><span>
+    Permissions
+  </span></div>
+  <div
+    id="permissions_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+
+<ul>
+
+  <li>Vous pouvez interdire l'accès aux catégories. Passez le type d'accès à "privé" si vous souhaitez gérer les permissions.</li>
+  
+  <li>Vous pouvez rendre une catégorie privée en l'éditant (<span
+class="pwgScreen">Administration &raquo; Catégories &raquo; Gérer &raquo; Editer</span>) ou en
+gérant les options pour votre arbre complet des catégories (<span
+class="pwgScreen">Administration &raquo; Catégories &raquo; Propriétés &raquo; Publique/Privée</span>).</li>
+
+  <li>
+    <p>Une fois que certaines catégories sont privées, vous pouvez gérer les
+permissions avec 3 écrans :</p>
+    <ul>
+      <li><span class="pwgScreen">Administration &raquo; Identification &raquo; Utilisateurs &raquo; action Permissions</span> (1 lien par utilisateur)</li>
+      <li><span class="pwgScreen">Administration &raquo; Identification &raquo; Groupes &raquo; action Permissions</span> (1 lien par groupe)</li>
+      <li><span class="pwgScreen">Administration &raquo; Catégories &raquo; Gérer &raquo; Modifier les permissions</span> (1 lien par catégorie)</li>
+    </ul>
+
+  </li>
+
+</ul>
+  </div> <!-- permissions_content --> 
+</div> <!-- instructionPermissions -->
+
+<div id="instructionGroups" class="instructionBlock">
+  <div
+    id="groups_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('groups_header', 'groups_content')"
+  ><span>
+    Groupes d'utilisateurs
+  </span></div>
+  <div
+    id="groups_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+<ul>
+
+  <li>Les groupes d'utilisateurs permettent d'assigner des permissions à une liste d'utilisateurs.</li>
+
+  <li>Vous pouvez créer des groupes et y ajouter des utilisateurs dans la
+<span class="pwgScreen">Administration &raquo; Identification &raquo; Groupes</span>.</li>
+
+  <li>Un utilisateur peut appartenir à plusieurs groupes. L'autorisation est
+plus forte que l'interdiction : si l'utilisateur "pierre" appartient aux
+groupes "famille" et "amis", et que seul le groupe "famille" peut visiter la
+catégorie "Noël 2003", alors "pierre" peut visiter cette catégorie.</li>
+  
+</ul>
+  </div> <!-- groups_content --> 
+</div> <!-- instructionGroups -->
+
+<div id="instructionUpload" class="instructionBlock">
+  <div
+    id="upload_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('upload_header', 'upload_content')"
+  ><span>
+    Ajout de fichiers par les utilisateurs
+  </span></div>
+  <div
+    id="upload_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+<p>Vos utilisateurs peuvent également ajouter leurs photos.</p>
+
+<ol>
+
+  <li>Autorisez l'ajout d'images sur une ou plusieurs catégories (<span
+class="pwgScreen">Administation &raquo; Catégories &raquo; Gestion &raquo; Edit</span> ou <span
+class="pwgScreen">Administration &raquo; Catégories &raquo; Propriétés &raquo; Ajout d'images</span>). Les catégories virtuelles ne permettent pas l'ajout d'images.</li>
+
+  <li>donner les droits en écriture (pour tous les utilisateurs) sur les
+répertoires correspondant aux catégories qui sont autorisées à l'ajout.</li>
+</ol>
+
+  <p>Les photos ajoutées par les utilisateurs ne sont pas directement
+visibles sur le site, ils doivent être validés par un administrateur. Pour
+cela, un administrateur doit se rendre dans <span class="pwgScreen">Administration &raquo; Images &raquo; En attente  &raquo; Images</span> afin d'accepter ou de rejeter les photos proposées.</p>
+
+  </div> <!-- upload_content --> 
+</div> <!-- instructionUpload -->
+
+<div id="instructionCategoryLinks" class="instructionBlock">
+  <div
+    id="categoryLinks_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('categoryLinks_header', 'categoryLinks_content')"
+  ><span>
+    Liens entre les photos et les catégories, catégories virtuelles
+  </span></div>
+  <div
+    id="categoryLinks_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+<ul>
+
+  <li>Les photos sont affichées dans les catégories correspondant aux répertoires.</li>
+
+  <li>Vous pouvez également afficher une photo dans plusieurs catégories, sans dupliquer le fichier sur votre serveur web. Associez la photo à n'importe quelle autre catégorie depuis l'écran d'édition de la photo (auquel vous accéder depuis la page de visualisation de la photo côté galerie, lorsque vous êtes connecté en tant qu'administrateur)</li>
+
+  <li>Les catégories virtuelles partent de ce principe : elles n'ont pas de répertoire associé. Créez des catégories virtuelles depuis <span class="pwgScreen">Administration &raquo; Catégories &raquo; Gérer</span>.</li>
+
+</ul>
+  </div> <!-- categoryLinks_content --> 
+</div> <!-- instructionCategoryLinks -->
+
+<div id="instructionMisc" class="instructionBlock">
+  <div
+    id="misc_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('misc_header', 'misc_content')"
+  ><span>
+    Informations diverses
+  </span></div>
+  <div
+    id="misc_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+<ul>
+  
+  <li>Une fois votre galerie créée, configurez l'affichage par
+défaut tel que désiré dans <span class="pwgScreen">Administation &raquo; Configuration &raquo; Affichage par défaut</span>. En effet, chaque nouvel
+utilisateur héritera de ces propriétés d'affichage.</li>
+
+  <li>Pour tout question, la communauté francophone Piwigo est à l'écoute sur le <a href="http://fr.piwigo.org/forum">forum</a>.</li>
+
+</ul>
+  </div> <!-- misc_content --> 
+</div> <!-- instructionMisc -->
+
+</div>
Index: /tags/2.0.2/language/fr_FR/help/advanced_feature.html
===================================================================
--- /tags/2.0.2/language/fr_FR/help/advanced_feature.html	(revision 3278)
+++ /tags/2.0.2/language/fr_FR/help/advanced_feature.html	(revision 3278)
@@ -0,0 +1,16 @@
+<h2>Fonctions avancées</h2>
+
+<p>Liste des fonctionnalités spéciales pour les administrateurs experts de PWG:</p>
+
+<ul>
+
+  <li>
+    <strong>Eléments non liés:</strong>
+    Affiche les images qui ne sont pas associées à une catégorie virtuelle
+  </li>
+  <li>
+    <strong>Fichiers portant le même nom dans plusieurs catégories physiques:</strong>
+    Affiche les images ou les éventuels fichiers qui pourraient être trouvés dans plusieurs catégories.
+  </li>
+
+</ul>
Index: /tags/2.0.2/language/fr_FR/help/cat_modify.html
===================================================================
--- /tags/2.0.2/language/fr_FR/help/cat_modify.html	(revision 3278)
+++ /tags/2.0.2/language/fr_FR/help/cat_modify.html	(revision 3278)
@@ -0,0 +1,149 @@
+<h2>Modifier une catégorie</h2>
+
+<h3>Informations</h3>
+
+<ul>
+
+  <li><strong>nom</strong>: renommer la catégorie (virtuellement pour 
+  une catégorie physique).</li>
+
+  <li><strong>description</strong>: donner une idée du contenu de la catégorie,
+  cette indication figurera sous la page des miniatures.</li>
+
+</ul>
+
+<h3>Déplacer</h3>
+
+<p>Si la catégorie est virtuelle, vous pouvez la déplacer. Déplacer une
+catégorie signifie changer sa catégorie parente.</p>
+
+<h3>Options</h3>
+
+<ul>
+
+  <li><strong>Type d'accès</strong>: gestion des permissions. Si vous rendez
+une catégorie privée, toutes ses catégories filles deviennent privées. Si
+vous rendez une catégorie publique, toutes ses catégories mères deviennent
+publiques.</li>
+
+  <li><strong>Verrouiller</strong>: la catégorie et toutes ses catégories
+filles deviennent temporairement inaccessibles pour maintenance.</li>
+
+  <li><strong>Commentaires</strong>: autorise les utilisateurs à commenter
+les éléments de cette catégorie.</li>
+
+  <li><strong>Autoriser l'ajout d'images</strong>: autorise les utilisateurs
+à télécharger des fichiers. Cette option n'est disponible que si la
+catégorie est physique (et non virtuelle).</li>
+
+</ul>
+
+<p>Vous pouvez aussi gérer ces options par la gestion des "Propriétés" 
+(écrans <span class="pwgScreen">Ajout</span>, <span
+class="pwgScreen">Commentaires</span>, <span
+class="pwgScreen">Verrouiller</span>, <span
+class="pwgScreen">Publique/Privée</span>, <span
+class="pwgScreen">Représentant</span> disponibles à partir d' <span
+class="pwgScreen">Administration, Catégories, Propriétés</span>).</p>
+
+<h3>Ordre de tri</h3>
+
+<p>Utiliser l'ordre de tri des images par défaut.</p>
+
+<p>Indiquer si le tri s'applique également aux sous-catégories.</p>
+
+<p>Sélectionner les colonnes du tri à utiliser pour cette catégorie.</p>
+<ul>
+<li><strong>Date de création</strong>: Date de prise de vue</li>
+<li><strong>Date d'ajout</strong>: Date de la synchronisation</li>
+<li><strong>Note moyenne (*)</strong>: laquelle moyenne pourrait être modifiée par le visiteur</li>
+<li><strong>Plus vues (*)</strong>: La visite en cours peut changer l'ordre des plus vues</li>
+<li><strong>Nom du fichier</strong>: Nom du fichier donné dans les champs d'informations ci-dessus</li>
+<li><strong>Id</strong>: Id interne (les catégories récentes ont un "Id" plus grand que les précédentes).</li>
+
+</ul>
+<p><strong>(*)</strong>Attention: testez-vous même ces tris qui peuvent donner des résultats imprévisibles.</p>
+
+
+<h3>Représentant</h3>
+
+<p>Le représentant d'une catégorie est la miniature affichée pour
+représenter la catégorie sur la page principale (<span
+class="pwgScreen">category.php</span>) lorsqu'une catégorie contient
+uniquement des sous-catégories et pas d'éléments directs (comme à la
+racine)</p>
+
+<p>Il existe 4 moyens de choisir le représentant d'une catégorie:</p>
+
+<ul>
+
+  <li><span class="pwgScreen">Page d'affichage des images</span>: dans la barre des boutons
+d'action, l'un d'eux permet de choisir l'élément affiché comme représentant
+de la catégorie affichée. Ce bouton d'action n'est disponible que pour les
+administrateurs.</li>
+
+  <li><span class="pwgScreen">Modifier les informations d'une image</span>
+dans l'administration. Cet écran peut être atteint depuis <span
+class="pwgScreen">picture.php</span> ou <span class="pwgScreen">Gestion par
+lot</span> dans le <em>mode unitaire</em>. Voir l'aide de cet écran pour les
+détails.</li>
+
+  <li><span class="pwgScreen">Administration, Catégories, Propriétés,
+Représentant</span>. Voir l'aide de cet écran pour les détails.</li>
+
+  <li><span class="pwgScreen">Modifier une catégorie</span> (le présent
+écran).</li>
+
+</ul>
+
+<p>La représentation dépend du paramètre de configuration
+<code>allow_random_representative</code> (voir <span
+class="filename">include/config_default.inc.php</span>).</p>
+
+<p>Par défaut (<code>allow_random_representative</code> à false) chaque
+catégorie contenant au moins un élément est représenté par un élément
+fixe. Une fois fixé (à la création de la catégorie), le représentant change
+uniquement lorsque l'administrateur le demande. Si le représentant ne
+convient pas, vous pouvez demander à <strong>Trouver un nouveau représentant
+au hasard</strong>.</p>
+
+<p>Si le paramètre de configuration <code>allow_random_representative</code>
+est à true, une catégorie contenant des éléments peut ne pas avoir de
+représentant fixe. Utiliser simplement le bouton <strong>Supprimer le
+représentant</strong>.</p>
+
+<p>Si la catégorie ne contient aucun élément (mais uniquement des 
+sous-catégories) elle peut quand même être représentée par n'importe quel 
+élément grâce à l'écran <span class="pwgScreen">Modifier les informations 
+d'une image</span>. La seule option du présent écran est le bouton
+<strong>Supprimer le représentant</strong>.</p>
+
+<h3>Associer tous les éléments de la catégorie à une nouvelle catégorie</h3>
+
+<ul>
+
+<li><strong>Nom de la catégorie virtuelle</strong>: Nom de la nouvelle catégorie à créer, 
+toutes les images de la catégorie en cours seront liées à la nouvelle.</li>
+
+<li><strong>Catégorie parente</strong>: Où la nouvelle catégorie doit être, 
+laisser vide pour la créer sur la page d'accueil.</li>
+
+</ul>
+
+<h3>Associer tous les éléments de la catégorie à des catégories existantes</h3>
+
+<ul>
+
+<li><strong>Catégories</strong>: Choisir la catégorie de destination.</li>
+
+</ul>
+
+<h3>Envoyer un mail d'informations aux membres d'un groupe</h3>
+
+<ul>
+
+<li><strong>Groupe</strong>: Groupe de destinataires</li>
+
+<li><strong>Contenu du mail</strong>: Texte libre à leur envoyer.</li>
+
+</ul>  
Index: /tags/2.0.2/language/fr_FR/help/cat_move.html
===================================================================
--- /tags/2.0.2/language/fr_FR/help/cat_move.html	(revision 3278)
+++ /tags/2.0.2/language/fr_FR/help/cat_move.html	(revision 3278)
@@ -0,0 +1,15 @@
+<h2>Déplacement de catégories virtuelles</h2>
+
+<p>Vous pouvez changer le parent d'une catégorie virtuelle.</p>
+
+<h3>Catégories virtuelles à déplacer</h3>
+
+<p>Sélectionnez une ou plusieurs catégories virtuelle à déplacer. 
+Si la liste est vide, c'est que vous n'en avez pas encore créé.</p>
+
+<h3>Nouvelle catégorie parente</h3>
+
+<p>Sélectionnez la nouvelle catégorie parente (virtuelle ou physique). 
+Si vous n'en sélectionnez aucune, 
+les catégories à déplacer seront remontée à la racine des catégories.
+Vous ne pouvez déplacer une catégorie dans elle-même ou ses enfants.</p>
Index: /tags/2.0.2/language/fr_FR/help/cat_options.html
===================================================================
--- /tags/2.0.2/language/fr_FR/help/cat_options.html	(revision 3278)
+++ /tags/2.0.2/language/fr_FR/help/cat_options.html	(revision 3278)
@@ -0,0 +1,42 @@
+<h2>Options des catégories</h2>
+
+<p>Gestion des options pour plusieurs catégories à la fois.</p>
+
+<dl>
+
+  <dt>Autorisation à l'ajout</dt>
+
+  <dd>Rendre les catégories autorisées à l'ajout par les visiteurs. Cette
+option n'est pas disponible pour les catégories virtuelles et
+distantes.</dd>
+  
+  <dt>Commentaires utilisateur</dt>
+
+  <dd>Autoriser les utilisateurs à ajouter des commentaires dans les catégories sélectionnée.
+Par héritage, une image est commentable si elle appartient à au moins une catégorie commentable.</dd>
+  
+  <dt>Verrouiller</dt>
+
+  <dd>Les catégories sélectionnées deviennent temporairement inactives pour
+maintenance. Lorsqu'une catégorie est verrouillée, toutes les catégories
+enfant sont verrouillées. Lorsqu'une catégorie est déverrouillée, toutes les
+catégories parentes sont déverrouillées.</dd>
+
+  <dt>Publique / Privée</dt>
+
+  <dd>Gestion du statut des catégories. Les permissions ne sont possibles
+que pour les catégories privées. Une fois qu'une catégorie est privée, vous
+devez explicitement autoriser les utilisateurs ou les groupes à y
+accéder. Lorsqu'une catégorie devient privée, toutes les catégories enfant
+deviennent privées. Lorsqu'une catégorie devient publique, toutes les
+catégories parentes deviennent publiques.</dd>
+
+  <dt>Représentant</dt>
+
+  <dd>Cette option est disponible uniquement si le paramètre de
+configuration <code>allow_random_representative</code> (voir <span
+class="filename">include/config_default.inc.php</span>) est
+<em>true</em>. Chaque catégorie peut-être représentée au hasard ou par une
+miniature fixe unique.</dd>
+
+</dl>
Index: /tags/2.0.2/language/fr_FR/help/cat_perm.html
===================================================================
--- /tags/2.0.2/language/fr_FR/help/cat_perm.html	(revision 3278)
+++ /tags/2.0.2/language/fr_FR/help/cat_perm.html	(revision 3278)
@@ -0,0 +1,16 @@
+<h2>Gérer les permissions pour une catégorie</h2>
+
+<p>Cet écran n'est disponible que pour les catégories privées. Ici vous
+pourrez sélectionner les utilisateurs et les groupes autorisés pour cette
+catégorie.</p>
+
+<h3>Groupes</h3>
+
+<p>Vous pouvez autoriser ou interdire l'accès aux groupes. En modifiant les
+autorisations des groupes, vous modifierez probablement la liste des
+utilisateurs autorisés grâce à l'appartenance aux groupes.</p>
+
+<h3>Utilisateurs</h3>
+
+<p>Vous pouvez autoriser ou interdire l'accès aux utilisateurs
+individuellement.</p>
Index: /tags/2.0.2/language/fr_FR/help/configuration.html
===================================================================
--- /tags/2.0.2/language/fr_FR/help/configuration.html	(revision 3278)
+++ /tags/2.0.2/language/fr_FR/help/configuration.html	(revision 3278)
@@ -0,0 +1,138 @@
+<h2>Configuration</h2>
+
+<p>Cet écran permet de gérer la configuration basique. En effet, seuls sont
+montrés les paramètres de configuration qui doivent suffire à la majorité
+des administrateurs. Si vous souhaitez voir la liste des nombreux (et
+avancés) paramètres, lire le fichier <span
+class="filename">include/config_default.inc.php</span></p>
+
+<p>Cet écran est divisié en plusieurs sections, regroupant les paramètres
+par thème.</p>
+
+<h3>Principale</h3>
+<ul>
+
+  <li><strong>Titre de la galerie</strong>: utilisé pour le flux RSS et
+la notification par email.</li>
+
+  <li><strong>Bannière des pages</strong>: code html affiché en haut des
+pages.</li>
+
+  <li><strong>URL de la galerie</strong>: utilisé pour le flux RSS.</li>
+
+  <li><strong>Verrouiller la galerie</strong>: Verrouiller l'ensemble de la
+galerie pour maintenance. Seul les administrateurs pourront accéder à la
+galerie.</li>
+
+  <li><strong>Notation</strong>: La notation des photos est possible.</li>
+
+  <li><strong>Notation par les visiteurs</strong>: Même les utilisateurs non enregistrés peuvent noter les images.</li>
+
+  <li><strong>Permettre l'enregistrement des utilisateurs</strong>: L'inscription est libre pour tous.</li>
+
+  <li><strong>L'adresse mail est obligatoire pour tous les utilisateurs</strong>: L'adresse mail sera vérifié lors des inscriptions ou de la mise à jour des profils sauf si l'action est effectuée dans la partie administration.</li>
+
+  <li><strong>Notifier les administrateurs lors de l'inscription d'un utilisateur</strong>: Les administrateurs recevront un courriel à chaque inscription.</li>
+
+</ul>
+
+<h3>Historique</h3>
+
+  <p>les visites des pages <span
+class="pwgScreen">index.php</span> et <span
+class="pwgScreen">picture.php</span> sont
+enregistrées dans la table <code>history</code>.</p>
+
+  <p>Les visites sont affichées dans l'écran <span class="pwgScreen">Administration, Spéciales, Historique</span>.</p>
+
+<ul>
+  <li><strong>Enregistrer les pages visitées par les invités</strong>: les visites des pages par les invités sont enregistrées.</li>
+
+  <li><strong>Enregistrer les pages visitées par les utilisateurs</strong>: les visites des pagespar les utilisateurs enregistrés sont enregistrées.</li>
+
+  <li><strong>Enregistrer les pages visitées par les administrateurs</strong>: les visites des pages par les administrateurs sont enregistrées.</li>
+
+</ul>
+
+<h3>Commentaires</h3>
+<ul>
+
+  <li><strong>Commentaires utilisateur pour tous</strong>: même les
+utilisateurs non enregistrés peuvent enregistrer des commentaires.</li>
+
+  <li><strong>Nombre de commentaires utilisateur par page</strong>.</li>
+
+  <li><strong>Validation</strong>: un administrateur doit valider les
+commentaires utilisateurs avant qu'ils puissent devenir visibles dans la
+partie publique. La validation des commentaires utilisateurs a lieu dans
+l'écran <span class="pwgScreen">Administration, Images,
+Commentaires</span>.</li>
+
+  <li><strong>Notifier les administrateurs quand un commentaire est enregistré</strong>:
+Envoi un courriel aux administrateurs lorsqu'un utilisateur enregistre un commentaire qui est validé.</li>
+
+  <li><strong>Notifier les administrateurs quand un commentaire requiert sa validation </strong>:
+Envoi un courriel aux administrateurs lorsqu'un utilisateur enregistre un commentaire qui demande une validation de la part des administrateurs.
+La validation des commentaires utilisateurs a lieu dans l'écran <span class="pwgScreen">Administration, Images, Commentaires</span>.</li>
+
+</ul>
+
+<h3>Téléchargement</h3>
+<ul>
+  <li><strong>Afficher le lien d'ajout d'image tout le temps</strong>: S'il existe des catégories permettant le téléchargement, le lien d'ajout d'image sera affiché quelque soit la catégorie.</li>
+  <li><strong>Niveau d'accès utilisateur pour télécharger</strong>: Permet de restreindre l'ajout à certains utilisateurs</li>
+  <li><strong>Notifier les administrateurs quand une image est téléchargée</strong>: Les administrateurs recevront un courriel à chaque image mis à disposition par un utilisateur.</li>
+</ul>
+
+<h3>Affichage par défaut</h3>
+<p>Modifier les options d'affichage par défaut: pour les visiteurs non
+connectés. Une fois connecté, ces options sont surchargées par celles de
+l'utilisateur, qu'il peut modifier dans l'écran <span
+class="pwgScreen">profile</span>.</p>
+
+<p>Il est possible de changer ces options pour les utilisateurs existants,
+mais il s'agit d'un autre écran : <span class="pwgScreen">Administration,
+Identification, Utilisateurs</span>, dans lequel vous pouvez modifier ces
+options pour une liste d'utilisateurs sélectionnés.</p>
+
+<ul>
+
+  <li><strong>Langue</strong>: ne concerne que les libellés de
+Piwigo. Les noms de catégories, d'image et les descriptions ne sont
+pas localisés (ie multilingue).</li>
+
+  <li><strong>Nombre de miniatures par ligne</strong></li>
+
+  <li><strong>Nombre de lignes par page</strong></li>
+
+  <li><strong>Thème de l'interface</strong></li>
+
+  <li><strong>Période récente</strong>: en jours. Période pendant laquelle
+une image est considérée comment nouvelle. Cette période doit être
+supérieure à 1 jour.</li>
+
+  <li><strong>Développer toutes les catégories</strong>: développer toutes
+les catégories dans le menu? <em>Attention</em>: cette option est
+susceptible de consommer inutilement des ressources si votre arbre de
+catégories contient de nombreux éléments.</li>
+
+  <li><strong>Montrer le nombre de commentaires</strong>: montrer les nombre
+de commentaires utilisateur en dessous de chaque miniature. Consomme des
+ressources.</li>
+
+  <li><strong>Montrer le nombre de visualisations  </strong>: affiche les 
+  « hits » relevés sur une image sous sa miniature dans la page de miniatures.
+  Uniquement valable si le paramètre de configuration avancée est :<br />
+  $conf['show_nb_hits'] = true; <br />
+  N.B.: par defaut il est à false.</li>
+
+  <li><strong>Largeur maximum des images</strong>: à l'affichage. Si l'image
+est plus large que ce paramètre, alors elle sera redimensionnée à
+l'affichage. Si vous pensez nécessaire de modifier ce paramétrage (donc pour
+un affichage par défaut), il serait pertinent de redimensionner directement
+vos images stockées.</li>
+
+  <li><strong>Hauteur maximum des images</strong>: même remarque que pour la
+largeur.</li>
+
+</ul>
Index: /tags/2.0.2/language/fr_FR/help/extend_for_templates.html
===================================================================
--- /tags/2.0.2/language/fr_FR/help/extend_for_templates.html	(revision 3278)
+++ /tags/2.0.2/language/fr_FR/help/extend_for_templates.html	(revision 3278)
@@ -0,0 +1,101 @@
+<h2>Configuration pour "étendre" les templates</h2>
+
+<h3>Objectif</h3>
+<p>Définir les conditions de remplacement de chaque template (modèle) à partir de template-extension
+(template appelé "replacer" (remplaçant)).</p>
+
+<p>Les "Templates d'origine" provenant de ./template/yoga (ou de tout autre dossier que "yoga")
+ sont remplacés par un remplaçant si celui-ci est lié à son template d'origine
+ (et de façon facultative, quand l'adresse (URL) demandée contient un URL contains un "Paramètre facultatif de l'URL").</p>
+
+<p>Les "Paramètres facultatif de l'URL" sont ceux que vous pouvez trouver après le nom du module dans l'adresse (URL).</p>
+
+<p>Ainsi un "Paramètre facultatif de l'URL" peut être un "permalink" (lien permanent) actif
+(voir les permalinks dans notre documentation pour plus d'information).</p>
+
+<p>Lire les `<a href="#warnings">mises en garde</a>` sur les conditions d'utilisation.</p>
+
+<h3>Qu'est-ce que les extensions des modèles?</h3>
+
+<p>Cet outil de configuration est à la fois puissant pour les débutants et pour les utilisateurs avancés.
+Par FTP, dans le dossier template-extension, le Webmaster pourra dupliquer une bonne partie des fichiers
+ .tpl distribués ("Templates d'origine") avec un nom différent  
+ ("replacer" (remplaçant)).
+ 
+ "Templates d'origine", actuellement les modèles d'origine supportés sont:</p>
+<ul>
+  <li><span class="filename">index.tpl</span></li>
+  <li><span class="filename">mainpage_categories.tpl</span> and/or <span class="filename">thumbnails.tpl</span></li>
+  <li><span class="filename">menubar.tpl</span></li>
+  <li><span class="filename">header.tpl</span> and/or <span class="filename">footer.tpl</span></li>
+  <li><span class="filename">picture_content.tpl</span> and/or <span class="filename">picture.tpl</span></li>
+  <!-- <li><span class="filename">slideshow.tpl</span></li> -->
+  <li><span class="filename">profile.tpl</span> and/or <span class="filename">profile_content.tpl</span></li>
+  <li><span class="filename">tags.tpl</span></li>
+  <li><span class="filename">upload.tpl</span></li>
+  <li><span class="filename">about.tpl</span></li>
+  <li><span class="filename">popuphelp.tpl</span></li>
+  <li><span class="filename">search.tpl</span> and/or <span class="filename">search_rules.tpl</span></li>
+  <li><span class="filename">nbm.tpl</span> and/or <span class="filename">notification.tpl</span></li>
+  <li><span class="filename">identification.tpl</span> and/or <span class="filename">register.tpl</span></li>
+  <li><span class="filename">redirect.tpl</span></li>
+</ul>
+
+<h3>Où puis-je trouver les "Templates d'origine"?</h3>
+
+<p>Les modèles distribués d'origine sont dans template/yoga/ 
+(ne pas les modifier directement à cet endroit pour des raisons d'évolution). Ainsi à partir des "templates d'origine", 
+tout webmaster pourra créer ses "replacers (modèles personalisés)".</p>
+
+<h3>Où dois-je enregistrer les "remplaçants"?</h3>
+
+<p>Les <strong>Replacers (templates modifiés)</strong> peuvent être placés dans le dossier 
+template-extension (ou ses sous-dossiers).
+Les remplaçants peuvent avoir n'importe quel nom de fichier avec l'extension .tpl. Par exemple: <span
+class="filename">template-extension/my-extension/video.tpl</span>.</p>
+
+
+<h3>Comment puis-je activer mes "remplaçants"?</h3>
+<p>Un <strong>template d'origine</strong> devrait être associé à chaque
+ <strong>replacer (modèle modifié)</strong> à fin d'activer les remplacements correspondants.
+ Activer les remplaçants est la fonction de "Etendre les templates" dans les menus de Configuration de l'Administration.</p>
+
+<p>Si vous sélectionnez un <strong>Paramètre facultatif de l'URL</strong> alors les remplacements 
+ne seront réalisés que sur les pages utilisant ce mot clé. Par exemple: <span
+  class="pwgScreen">index.php?/<strong>most_visited</strong></span></p>
+  
+<p>Les utilisateurs avancés utiliseront les permalinks (permaliens, liens permanents) en tant que 
+<strong>paramètre facultatif de l'URL</strong>. </p>
+
+<p>Si vous sélectionnez un <strong>Template rattaché</strong> alors les remplacements ne seront réalisés que sur ce template.</p>
+
+<h3>Comment puis-je désactiver mes "replacers"?</h3>
+<ul>
+<li>Déselectionner le "template d'origine".</li>
+<li>Par FTP supprimer le "remplaçant".</li>
+</ul>
+<a name="warnings"></a>
+<h3>Mises en garde</h3>
+<ul>
+
+  <li>Le <strong>template d'origine</strong> doit être le véritable template "d'origine"
+  autrement vous pourriez avoir des résultats imprévisibles!</li>
+
+  <li>Si plusieurs <strong>remplaçants (templates modofiés)</strong> ont le même
+  <strong>template d'origine</strong> et le même <strong>paramètre facultatif
+  de l'URL</strong> alors seulement le dernier remplaçant sera actif.</li>
+
+  <li>Ne pas sélectionner de <strong>paramètre facultatif de l'URL</strong> 
+  activera le template de remplacement à chaque utilisation du template.
+  Comme mentionné ci-dessus, l'ordre peut inhiber les remplaçants précédents.</li>
+
+  <li>Sous-dossiers:
+  Les sous-dossiers sont ignorés mais ils sont utiles pour modifier l'ordre des remplaçants.<br />
+distributed-samples: pour vos tests sont distributés! 
+<strong>Ne pas les modifier</strong>, créez les votres!
+</li>
+
+  <li>A la suppression d'un remplaçant le <strong>template d'origine</strong> sera 
+  immédiatement réactivé.</li>
+
+</ul>
Index: /tags/2.0.2/language/fr_FR/help/group_list.html
===================================================================
--- /tags/2.0.2/language/fr_FR/help/group_list.html	(revision 3278)
+++ /tags/2.0.2/language/fr_FR/help/group_list.html	(revision 3278)
@@ -0,0 +1,21 @@
+<h2>Liste des groupes</h2>
+
+<p>Manipulation des propriétés des groupes définis.</p>
+
+<h3>Ajouter un groupe</h3>
+
+<p>L'administrateur peut ajouter des groupes.</p>
+
+<h3>Liste des groupes</h3>
+
+<p>La liste permet pour chaque groupe:</p>
+
+<ul>
+  <li>d'accéder à la liste des membres</li>
+  <li>d'accéder aux permissions</li>
+  <li>de supprimer le groupe (nécessite une confirmation)</li>
+  <li>d'inverser le statut "par défaut" (nécessite une confirmation)</li>
+</ul>
+
+<h3>Groupes par défaut</h3>
+<p>Les groupes par défaut sont les groupes associés automatiquement à chaque nouvel utilisateur.</p>
Index: /tags/2.0.2/language/fr_FR/help/history.html
===================================================================
--- /tags/2.0.2/language/fr_FR/help/history.html	(revision 3278)
+++ /tags/2.0.2/language/fr_FR/help/history.html	(revision 3278)
@@ -0,0 +1,52 @@
+<h2>Historique</h2>
+
+<p>Ces écrans permettent de suivre l'historique de navigation dans Piwigo
+ suivant les options que vous avez déterminées dans - Administration - Générale 
+ - Onglet "Historique".</p>
+	
+<h3>Statistiques</h3>
+<ul>
+  <p>Si vous avez choisi que les visites des pages <span
+class="pwgScreen">index.php</span> et <span
+class="pwgScreen">picture.php</span> soient
+enregistrées dans la table <code>history</code>,
+cet onglet permet de suivre le nombre de pages visitées</p>
+	
+	<li><strong>Statistiques totales</strong> : vous visualisez les statistiques
+	par année</li>
+	
+	<li><strong>Statistiques d'une année</strong> : vous visualisez les statistiques
+	des mois de l’année sélectionnée.</li>
+	
+	<li><strong>Statistiques d'un mois</strong> : vous visualisez les statistiques
+	des jours du mois sélectionné.</li>
+	
+	<li><strong>Statistiques d'une journée</strong> : vous visualisez les statistiques
+	des heures de la journée sélectionnée.</li>
+	
+</ul>
+
+<h3>Rechercher</h3>
+<ul>
+  <p>Si vous avez choisi que les visites des pages <span
+class="pwgScreen">index.php</span> et <span
+class="pwgScreen">picture.php</span> soient
+enregistrées dans la table <code>history</code>.
+ Cet onglet permet de suivre plus en détail les pages explorées
+ sur votre site avec l'aide de différents filtres.</p>
+ 
+	<li><strong>Filtrer par date</strong> : sélectionner la plage
+ d'observation dont vous souhaitez observer l’activité.</li>
+	
+	<li><strong>Filtrer par type d'élément</strong> : sélectionner le
+type d'élément dont vous souhaitez observer l’activité.</li>
+	
+	<li><strong>Filtrer par utilisateur</strong> : sélectionner l'utilisateur dont vous
+ souhaitez observer l’activité.</li>
+	
+	<li><strong>Filtrer par nom du fichier</strong> : sélectionner le nom du fichier dont vous
+ souhaitez observer l’activité.</li>
+	
+	<li><strong>Filtrer par identifiant image</strong> : sélectionner l'identifiant image dont vous
+ souhaitez observer l’activité.</li>
+</ul>
Index: /tags/2.0.2/language/fr_FR/help/index.php
===================================================================
--- /tags/2.0.2/language/fr_FR/help/index.php	(revision 3278)
+++ /tags/2.0.2/language/fr_FR/help/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/language/fr_FR/help/maintenance.html
===================================================================
--- /tags/2.0.2/language/fr_FR/help/maintenance.html	(revision 3278)
+++ /tags/2.0.2/language/fr_FR/help/maintenance.html	(revision 3278)
@@ -0,0 +1,51 @@
+<h2>Maintenance</h2>
+
+<p>Pour optimiser le temps de génération des pages, Piwigo utilise
+des informations en cache. Par exemple, au lieu de compter le nombre
+d'éléments contenus dans chaque catégorie à chaque rechargement de page,
+cette information est stockée dans la base de données. En théorie, cette
+information doit toujours être correcte, mais parfois une erreur peut
+survenir et l'information en cache devient fausse.</p>
+
+<p>Des informations deviennent inutiles avec le temps. Les supprimer de la
+base de données libère de l'espace disque.</p>
+
+<ul>
+
+  <li><strong>Mettre à jour les informations des catégories:</strong> Pour
+chaque catégorie, les informations à controller et/ou mettre à jour sont les
+suivantes: liste des catégories mères, nombre d'éléments, date du dernier
+élément, position parmi les catégories soeur, position dans l'arbre complet
+des catégories. Cette action vérifie également la cohérence des
+représentants.</li>
+
+  <li><strong>Mettre à jour les informations des images:</strong> Pour
+chaque image, les informations à mettre à jour sont: chemin complet vers le
+fichier, note moyenne. <em>Attention</em>: ne pas confondre avec les
+méta-données qui sont synchronisées sur l'écran <span
+class="pwgScreen">Administration, Catégories, Synchroniser</span> ou sur
+l'écran <span class="pwgScreen">Modifier les informations d'une image</span>
+(accessible depuis la page de visualisation d'une image <span
+class="pwgScreen">picture.php</span>).</li>
+
+  <li><strong>Réparer et optimiser la base de données:</strong>
+Pour chaque tables de la base de données PhpWegGallery, les opérations de ré-ordonnancement, de réparation et d'optimisation sont effectuées.
+  </li>
+
+</ul>
+
+<ul>
+  <li><strong>Purger le detail de l'historique:</strong> Supprime toutes les lignes de
+la table <code>history</code>. L'écran <span
+class="pwgScreen">Administration, Spéciales, Historique</span> ne montre alors
+plus aucune information sur le passé. <em>Attention</em>: toutes les données
+seront perdues et il n'existe aucun moyen de les récupérer.</li>
+
+  <li><strong>Purger le sommaire de l'historique:</strong> Supprime toutes les informations sommaires (obtenues à partir de detail de l'historique) .</li>
+
+  <li><strong>Purger les sessions:</strong> Supprimer les sessions
+expirées..</li>
+
+  <li><strong>Purger les flux de notification jamais utilisés</strong></li>
+
+</ul>
Index: /tags/2.0.2/language/fr_FR/help/notification_by_mail.html
===================================================================
--- /tags/2.0.2/language/fr_FR/help/notification_by_mail.html	(revision 3278)
+++ /tags/2.0.2/language/fr_FR/help/notification_by_mail.html	(revision 3278)
@@ -0,0 +1,14 @@
+<h2>Notification par mail</h2>
+
+<p>Cet écran permet de configurer, de gérer la notification aux utilisateurs de changements par l'envoi d'un mail.</p>
+
+<p>Cet écran est composé de 3 onglets:</p>
+
+<h3>Paramétrage</h3>
+<p>Accessible uniquement aux webmestres, cet onglet permet de positionner les paramètres de la notification par mail.</p>
+
+<h3>Inscription</h3>
+<p>Accessible uniquement aux webmestres, cet onglet permet de gérer les inscriptions/désinscriptions à la notification par mail.</p>
+
+<h3>Envoi</h3>
+<p>Accessible aux webmestres et aux administrateurs, cet onglet permet d'effectuer les envois des mails pour notifier les changements.</p>
Index: /tags/2.0.2/language/fr_FR/help/permalinks.html
===================================================================
--- /tags/2.0.2/language/fr_FR/help/permalinks.html	(revision 3278)
+++ /tags/2.0.2/language/fr_FR/help/permalinks.html	(revision 3278)
@@ -0,0 +1,7 @@
+<h2>Liens permanents</h2>
+
+<p>Les liens permanents sont utilisés pour rendre les urls des catégories plus jolis. Quand une catégorie a un lien permanent associée, l'identifiant de la catégorie n'est plus nécessaire dans l'url.</p>
+
+<p>Quand un lien permanent est effacé, vous pouvez le sauvegarder dans l'historique des liens permanents, de sorte que les liens externes a PWG fonctionnent encore. Dans l'historique des liens permanents vous pouvez voir la date d'effacement du lien, ainsi que la date de la dernière utilisation et le nombre d'utilisations de ce lien.</p>
+
+<p>Veuillez noter que les liens permanents doivent être uniques. Ils doivent aussi être uniques dans l'historique des liens permanents.</p>
Index: /tags/2.0.2/language/fr_FR/help/search.html
===================================================================
--- /tags/2.0.2/language/fr_FR/help/search.html	(revision 3278)
+++ /tags/2.0.2/language/fr_FR/help/search.html	(revision 3278)
@@ -0,0 +1,27 @@
+<h2>Recherche</h2>
+
+<p>Recherche d'images à travers l'ensemble de la galerie.</p>
+
+<dl>
+
+  <dt>Rechercher un mot</dt>
+
+  <dd>Recherche un ou plusieurs mots dans tous les attributs liés aux
+images. Utiliser * comme joker pour les recherches partielles.</dd>
+  
+  <dt>Recherche d'un auteur</dt>
+
+  <dd>Utiliser * comme joker pour les recherches partielles.</dd>
+
+  <dt>Recherche par date</dt>
+
+  <dd>Sélectionner une date et/ou une date de fin. Laisser la date vide si
+vous souhaiter faire une recherche "avant". L'année doit être entrée dans le
+dernier champ sous forme de 4 chiffres (2005 par exemple).</dd>
+
+  <dt>Recherche dans les catégories</dt>
+
+  <dd>Sélectionner les catégories sur lesquelles restreindre la
+recherche.</dd>
+
+</dl>
Index: /tags/2.0.2/language/fr_FR/help/site_manager.html
===================================================================
--- /tags/2.0.2/language/fr_FR/help/site_manager.html	(revision 3278)
+++ /tags/2.0.2/language/fr_FR/help/site_manager.html	(revision 3278)
@@ -0,0 +1,56 @@
+<h2>Sites distant</h2>
+
+<p>Piwigo offre la possibilité d'utiliser plusieurs sites pour
+stocker les fichiers qui composeront votre galerie. Cela peut être utile si
+votre galerie est installée sur un espace de stockage limité et que vous
+avez de nombreux fichiers à montrer.</p>
+
+
+<ol>
+
+  <li>éditer le fichier <span
+class="filename">tools/create_listing_file.php</span> en modifiant la
+section des paramètres comme <code>$conf['prefix_thumbnail']</code> ou
+<code>$conf['use_exif']</code>.</li>
+
+  <li>placer le fichier <span
+class="filename">tools/create_listing_file.php</span> modifié sur votre site
+distant, dans le même répertoire que les répertoires représentant vos
+catégories (comme le répertoire <span class="filename">galleries</span> de
+ce site) par FTP. Par exemple, disons que vous pouvez accéder à <span
+class="filename">http://exemple.com/galleries/create_listing_file.php</span>.</li>
+
+  <li>Se rendre sur <span class="pwgScreen">Administration, Catégories,
+Gestionnaire des sites</span>. Demander à créer un nouveau site, par exemple <span
+class="filename">http://exemple.com/galleries</span>.</li>
+
+  <li>
+
+    <p>un nouveau site distant est enregistré. 4 actions possibles :</p>
+
+    <ol>
+
+      <li><strong>générer la liste</strong> : lance une requête distante pour
+générer le fichier de listing distant</li>
+
+      <li><strong>synchroniser</strong> : lit le fichier distant <span
+class="filename">listing.xml</span> et synchronise avec la base de données
+locale</li>
+
+      <li><strong>nettoyer</strong> : supprime le fichier distant de
+listing</li>
+
+      <li><strong>détruire</strong> : supprime le site (et tous les éléments
+qui y sont associés) dans la base de données</li>
+
+    </ol>
+
+  </li>
+
+</ol>
+
+<!--<p>Vous pouvez également effectuer ces opérations manuellement en éditant
+le fichier <span class="filename">listing.xml</span> à la main et en le
+déplaçant vers votre répertoire racine. Se rendre sur <span
+class="pwgScreen">Administration, Catégories, Sites distant</span> :
+Piwigo détecte le fichier et propose de s'en servir.</p>-->
Index: /tags/2.0.2/language/fr_FR/help/synchronize.html
===================================================================
--- /tags/2.0.2/language/fr_FR/help/synchronize.html	(revision 3278)
+++ /tags/2.0.2/language/fr_FR/help/synchronize.html	(revision 3278)
@@ -0,0 +1,19 @@
+<h2>Synchroniser</h2>
+
+<ul>
+
+  <li>Il existe 2 types de synchronisations : structure et
+meta-données. Synchroniser la structure revient à synchroniser votre arbre
+des répertoires et fichiers avec la représentation de la structure dans la
+base de données. Synchroniser les méta-données permet de mettre à jour les
+informations comme le poids du fichier, les dimensions, les données EXIF ou
+IPTC.</li>
+
+  <li>La première synchronisation à effectuer doit être celle sur la
+structure.</li>
+
+  <li>Le processus de synchronisation peut prendre du temps (en fonction de
+la charge du serveur et de la quantité de fichiers à gérer), il est donc
+possible d'avancer pas à pas : catégorie par catégorie.</li>
+
+</ul>
Index: /tags/2.0.2/language/fr_FR/help/thumbnail.html
===================================================================
--- /tags/2.0.2/language/fr_FR/help/thumbnail.html	(revision 3278)
+++ /tags/2.0.2/language/fr_FR/help/thumbnail.html	(revision 3278)
@@ -0,0 +1,36 @@
+<h2>Création des miniatures</h2>
+
+<p>Création des miniatures manquantes. L'utilisation de cette fonctionnalité
+n'est pas conseillé si votre galerie est hébergée sur un serveur
+mutualisé (resources machine partagées).</p>
+
+<dl>
+
+  <dt>Version de GD</dt>
+
+  <dd>GD est une librairie graphique de manipulation d'images pour
+PHP. Choisissez la version installée sur votre serveur. Si vous choisissez
+la mauvaise, des messages d'erreurs apparaîtront, revenez sur la page
+précédente et choisissez l'autre version. Si aucune version ne marche, cela
+signifie que GD n'est pas disponible.</dd>
+
+  <dt>Largeur et hauteur</dt>
+
+  <dd>Dimensions maximum que les miniatures peuvent prendre. Le ratio
+largeur/hauteur original est conservée. Les valeurs par défaut sont
+modifiables grâce aux paramètres de configuration <code>tn_width</code> et
+<code>tn_height</code> (voir le fichier <span
+class="filename">include/config_default.inc.php</span>).</dd>
+  
+  <dt>Nombre de miniatures à créer</dt>
+
+  <dd>N'hésayez pas de miniaturiser un trop grand nombre d'images à la
+fois. En effet, la miniaturisation requiert une relativement grosse
+utilisation processeur.</dd>
+
+  <dt>Format de fichier</dt>
+
+  <dd>Les miniatures sont créées au format JPEG. Seuls les formats PNG et
+JPEG peuvent être miniaturisés.</dd>
+
+</dl>
Index: /tags/2.0.2/language/fr_FR/help/user_list.html
===================================================================
--- /tags/2.0.2/language/fr_FR/help/user_list.html	(revision 3278)
+++ /tags/2.0.2/language/fr_FR/help/user_list.html	(revision 3278)
@@ -0,0 +1,39 @@
+<h2>Liste des utilisateurs</h2>
+
+<p>Manipulation des propriétés des utilisateurs enregistrés. Seules les
+permissions sont gérées dans un écran différent.</p>
+
+<h3>Ajouter un utilisateur</h3>
+
+<p>L'administrateur peut ajouter manuellement des utilisateurs.</p>
+
+<h3>Liste des utilisateurs</h3>
+
+<p>La liste peut être filtrée avec le nom d'utilisateur (* = joker), avec le
+groupe ou encore le statut. La liste peut être ordonnée selon la date
+d'enregistrement ou le nom d'utilisateur, par ordre croissant on
+décroissant.</p>
+
+<p>Cet écran fonctionne par modification de plusieurs utilisateurs
+simultanément:</p>
+
+<ul>
+  <li>supprimer des utilisateurs (nécessite une confirmation)</li>
+  <li>changer le statut</li>
+  <li>associer ou dissocier des groupes</li>
+  <li>modifier les propriétés d'affichage</li>
+  <li>modifier les propriétés annexes</li>
+</ul>
+
+<p>La cible est la liste des utilisateurs sélectionnés (par défaut) ou bien
+tous les utilisateurs de la liste filtrée.</p>
+
+<h3>Conseiller</h3>
+<p>Définition d'un utilisateur conseiller:</p>
+<ul>
+  <li>permet d'accéder à tous les écrans permis par son statut</li>
+  <li>accès uniquement en consultation ou en simulation</li>
+</ul>
+
+<p>Il est possible de permettre l'assignation du mode conseiller avec la variable $conf['allow_adviser'].</p>
+<p>Si cette variable est à 'true', il sera possible de définir l'utilisateur comme un conseiller</p>
Index: /tags/2.0.2/language/fr_FR/index.php
===================================================================
--- /tags/2.0.2/language/fr_FR/index.php	(revision 3278)
+++ /tags/2.0.2/language/fr_FR/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/language/fr_FR/install.lang.php
===================================================================
--- /tags/2.0.2/language/fr_FR/install.lang.php	(revision 3278)
+++ /tags/2.0.2/language/fr_FR/install.lang.php	(revision 3278)
@@ -0,0 +1,74 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+$lang['Installation'] = 'Installation';
+$lang['Initial_config'] = 'Configuration de Base';
+$lang['Default_lang'] = 'Langue par défaut de la galerie';
+$lang['step1_title'] = 'Configuration de la Base de données';
+$lang['step2_title'] = 'Configuration du compte Administrateur';
+$lang['Start_Install'] = 'Démarrer l\'installation';
+$lang['reg_err_mail_address'] = 'L\'adresse mail doit être de la forme xxx@yyy.eee (exemple : jack@altern.org)';
+
+$lang['install_webmaster'] = 'Administrateur';
+$lang['install_webmaster_info'] = 'Cet identifiant apparaîtra à tous vos visiteurs. Il vous sert pour administrer le site';
+
+$lang['step1_confirmation'] = 'Les paramètres rentrés sont corrects';
+$lang['step1_err_db'] = 'La connexion au serveur est OK, mais impossible de se connecter à cette base de données';
+$lang['step1_err_server'] = 'Impossible de se connecter au serveur';
+
+$lang['step1_host'] = 'Hôte MySQL';
+$lang['step1_host_info'] = 'localhost, sql.multimania.com, toto.freesurf.fr';
+$lang['step1_user'] = 'Utilisateur';
+$lang['step1_user_info'] = 'nom d\'utilisateur pour votre hébergeur';
+$lang['step1_pass'] = 'Mot de passe';
+$lang['step1_pass_info'] = 'celui fourni par votre hébergeur';
+$lang['step1_database'] = 'Nom de la base';
+$lang['step1_database_info'] = 'celui fourni par votre hébergeur';
+$lang['step1_prefix'] = 'Préfixe des noms de table';
+$lang['step1_prefix_info'] = 'le nom des tables apparaîtra avec ce préfixe (permet de mieux gérer sa base de données)';
+$lang['step2_err_login1'] = 'veuillez rentrer un pseudo pour le webmaster';
+$lang['step2_err_login3'] = 'le pseudo du webmaster ne doit pas comporter les caractère " et \'';
+$lang['step2_err_pass'] = 'veuillez retaper votre mot de passe';
+$lang['install_end_title'] = 'Installation terminée';
+$lang['step2_pwd'] = 'Mot de passe';
+$lang['step2_pwd_info'] = 'Il doit rester confidentiel, il permet d\'accéder au panneau d\'administration.';
+$lang['step2_pwd_conf'] = 'Mot de passe [ Confirmer ]';
+$lang['step2_pwd_conf_info'] = 'Vérification';
+$lang['step1_err_copy'] = 'Copiez le texte en rose entre les tirets et collez-le dans le fichier mysql.inc.php qui se trouve dans le répertoire "include" à la base de l\'endroit où vous avez installé Piwigo (le fichier mysql.inc.php ne doit comporter QUE ce qui est en rose entre les tirets, aucun retour à la ligne ou espace n\'est autorisé)';
+$lang['install_help'] = 'Besoin d\'aide ? Posez votre question sur le <a href="%s">forum de Piwigo</a>.';
+$lang['install_end_message'] = 'La configuration de l\'application s\'est correctement déroulée, place à la prochaine étape<br /><br />
+* allez sur la page d\'identification et connectez-vous avec le pseudo donné pour le webmaster<br />
+* celui-ci vous permet d\'accéder à la partie administration et aux instructions pour placer les images dans les répertoires.';
+$lang['conf_mail_webmaster'] = 'Adresse e-mail de l\'Administrateur';
+$lang['conf_mail_webmaster_info'] = 'Les visiteurs pourront vous contacter par ce mail';
+
+$lang['PHP 5 is required'] = 'PHP 5 est requis';
+$lang['It appears your webhost is currently running PHP %s.'] = 'Apparemment, la version PHP de votre hébergeur est PHP %s.';
+$lang['Piwigo may try to switch your configuration to PHP 5 by creating or modifying a .htaccess file.'] = 'Piwigo va essayer de passer en PHP 5 en créant ou en modifiant le fichier .htaccess.';
+$lang['Note you can change your configuration by yourself and restart Piwigo after that.'] = 'Notez que vous pouvez changer vous-même la configuration PHP et re-lancer Piwigo après.';
+$lang['Try to configure PHP 5'] = 'Essayer de configurer PHP 5';
+$lang['Sorry!'] = 'Désolé!';
+$lang['Piwigo was not able to configure PHP 5.'] = 'Piwigo n\'a pas pu configurer PHP 5.';
+$lang["You may referer to your hosting provider's support and see how you could switch to PHP 5 by yourself."] = 'Vous devez contacter votre hébergeur afin de savoir comment configurer PHP 5.';
+$lang['Hope to see you back soon.'] = 'En espérant vous revoir très prochainement...';
+?>
Index: /tags/2.0.2/language/fr_FR/iso.txt
===================================================================
--- /tags/2.0.2/language/fr_FR/iso.txt	(revision 3278)
+++ /tags/2.0.2/language/fr_FR/iso.txt	(revision 3278)
@@ -0,0 +1,1 @@
+Français [FR]
Index: /tags/2.0.2/language/fr_FR/upgrade.lang.php
===================================================================
--- /tags/2.0.2/language/fr_FR/upgrade.lang.php	(revision 3278)
+++ /tags/2.0.2/language/fr_FR/upgrade.lang.php	(revision 3278)
@@ -0,0 +1,44 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+$lang['Upgrade'] = 'Mise à jour';
+$lang['introduction message'] = 'Cette page vous propose de mettre à jour la base de donnée correspondante à votre ancienne version de piwigo vers la nouvelle version.
+L\'assistant de mise à jour pense que la version actuelle est une <strong>version %s</strong> (ou équivalente).';
+$lang['Upgrade from %s to %s'] = 'Mise à jour de la version %s à %s';
+$lang['Statistics'] = 'Statistiques';
+$lang['total upgrade time'] = 'temps total de la mise à jour';
+$lang['total SQL time'] = 'temps total des requêtes SQL';
+$lang['SQL queries'] = 'nombre de requêtes SQL';
+$lang['Upgrade informations'] = 'Informations sur la mise à jour';
+$lang['perform a maintenance check'] = 'Veuillez effectuer une maintenance dans [Administration>Spéciales>Maintenance] si vous rencontrez des problèmes.';
+$lang['deactivated plugins'] = 'Par précaution, les plugins suivants ont été désactivés. Vérifiez s\'il existe des mises à jour avant de les réactiver:';
+$lang['upgrade login message'] = 'Seul un administrateur peut lancer la mise à jour: veuillez vous identifier ci-dessous.';
+$lang['You do not have access rights to run upgrade'] = 'Vous n\'avez pas les droits necessaires pour lancer la mise à jour.';
+$lang['in include/mysql.inc.php, before ?>, insert:'] = 'Dans le fichier <i>include/mysql.inc.php</i>, avant <b>?></b>, insérez:';
+
+// Upgrade informations from upgrade_1.3.1.php
+$lang['all sub-categories of private categories become private'] = 'Toutes les sous-catégories de catégories privées deviennent privées';
+$lang['user permissions and group permissions have been erased'] = 'Les permissions des utilisateurs et des groupes ont été effacées';
+$lang['only thumbnails prefix and webmaster mail saved'] = 'Seuls le préfixe des miniatures et l\'adresse email du webmestre ont étés sauvegardés de la configuration précédente';
+
+?>
Index: /tags/2.0.2/language/hr_HR/about.html
===================================================================
--- /tags/2.0.2/language/hr_HR/about.html	(revision 3278)
+++ /tags/2.0.2/language/hr_HR/about.html	(revision 3278)
@@ -0,0 +1,6 @@
+  <li>Piwigo je web aplikacija koja vam omogućava izradu web galerije na lak način.</li>
+
+  <li>Tehnički, Piwigo je potpuno razvijen korištenjem PHP (the elePHPant) te MySQL baze podataka (the SQuirreL).</li>
+
+  <li>Ako imate prijedloga i komentara, molimo posjetite <a href="http://piwigo.org">Piwigo</a> službenu stranicu, te njoj posvećen <a href="http://piwigo.org/forum">forum</a>.</li>
+
Index: /tags/2.0.2/language/hr_HR/admin.lang.php
===================================================================
--- /tags/2.0.2/language/hr_HR/admin.lang.php	(revision 3278)
+++ /tags/2.0.2/language/hr_HR/admin.lang.php	(revision 3278)
@@ -0,0 +1,650 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+$lang['%d association'] = '%d poveznica';
+$lang['%d associations'] = '%d poveznica';
+$lang['cat_inclu_part1_S'] = '%d skupina obuhvata ';
+$lang['cat_inclu_part1_P'] = '%d skupine obuhvata ';
+$lang['cat_inclu_part2_S'] = '%d stvarna';
+$lang['cat_inclu_part2_P'] = '%d stvarnih';
+$lang['cat_inclu_part3_S'] = ' i %d nestvrana';
+$lang['cat_inclu_part3_P'] = ' i %d nestvarnih';
+$lang['%d category moved'] = '%d skupina premještena';
+$lang['%d categories moved'] = '%d skupina premješteno';
+$lang['%d group'] = '%d grupa';
+$lang['%d groups'] = '%d grupa';
+$lang['%d member'] = '%d član';
+$lang['%d members'] = '%d članova';
+$lang['%d tag'] = '%d tag';
+$lang['%d tags'] = '%d tagova';
+$lang['%d user comment rejected'] = '%d korisnički komentar odbačen';
+$lang['%d user comments rejected'] = '%d korisničkih komentara odbačeno';
+$lang['%d user comment validated'] = '%d korisnički kometar odobren';
+$lang['%d user comments validated'] = '%d korisničkih komentara odobreno';
+$lang['%d user deleted'] = '%d korisnik izbrisan';
+$lang['%d users deleted'] = '%d korisnika izbrisano';
+$lang['%d user'] = '%d korisnik';
+$lang['%d users'] = '%d korisnika';
+$lang['%d waiting for validation'] = '%d čekanje na ovjeri';
+$lang['%d waiting pictures rejected'] = '%d slika na čekanju odbačeno';
+$lang['%d waiting pictures validated'] = '%d slika na čekanju odobreno';
+$lang['Actions'] = 'Postupci';
+$lang['Activate'] = 'Uključi';
+$lang['Add/delete a permalink'] = 'Dodaj/izbriši stalnu poveznicu';
+$lang['Add a tag'] = 'Dodaj';
+$lang['Add a user'] = 'Dodaj korisnika';
+$lang['Add group'] = 'Dodaj grupu';
+$lang['Add selected elements to caddie'] = 'Dodaj odabrane stavke u ladicu';
+$lang['Add'] = 'Dodaj';
+$lang['Allow user registration'] = 'Odobri upis korisnika';
+$lang['Apply to subcategories'] = 'Primjeni na podskupine';
+$lang['Are you sure?'] = 'Sigurni ste?';
+$lang['Associated'] = 'Povezanost';
+$lang['Association to categories'] = 'Povezanost sa skupinama';
+$lang['Batch management'] = 'Slijedna uprava';
+$lang['Caddie management'] = 'Uprava ladice';
+$lang['Caddie'] = 'Ladica';
+$lang['Categories authorized thanks to group associations'] = 'Skupine ovjerene zahvaljujući grupnoj povezanosti';
+$lang['Categories manual order was saved'] = 'Stvarni redoslijed skupina je pohranjen';
+$lang['Categories ordered alphanumerically'] = 'Skupine poredane abecedno';
+$lang['Category elements associated to the following categories: %s'] = 'Stavke skupine povezane su sa slijedećim skupinama: %s';
+$lang['Check for upgrade failed for unknown reasons.'] = 'Provjera nadogradnje neuspješna iz nepoznatog razloga.';
+$lang['Check for upgrade'] = 'Provjera nadogradnje';
+$lang['Comments for all'] = 'Komentari za sve';
+$lang['Controversy'] = 'Osporavanja';
+$lang['Current name'] = 'Trenutni naziv';
+$lang['Database'] = 'Baza podataka';
+$lang['Deactivate'] = 'Isključi';
+$lang['Delete Representant'] = 'Izbriši Predstavnika';
+$lang['Delete selected tags'] = 'Izbriši odabrane tagove';
+$lang['Delete selected users'] = 'Izbriši odabrane korisnike';
+$lang['Deletions'] = 'Brisanja';
+$lang['Deny selected groups'] = 'Zabrani odabrane grupe';
+$lang['Deny selected users'] = 'Zabrani odabrane korisnike';
+$lang['Description'] = 'Opis';
+$lang['Display options'] = 'Mogućnosti prikaza';
+$lang['Dissociated'] = 'Odvojeno';
+$lang['Does not represent'] = 'Ne predstavlja';
+$lang['Edit all picture informations'] = 'Uredi sve podatke o slici';
+$lang['Edit selected tags'] = 'Uredi odabrane tagove';
+$lang['Edit tags'] = 'Uredi tagove';
+$lang['Elements'] = 'Stavke';
+$lang['Email administrators when a new user registers'] = 'E-mail upraviteljima pri upisu novih korisnika';
+$lang['Email administrators when a valid comment is entered'] = 'E-mail upraviteljima pri upisu novih komentara';
+$lang['Email administrators when a comment requires validation'] = 'Email upraviteljima kada komentar treba ovjeru';
+$lang['Email administrators when a picture is uploaded'] = 'Email upraviteljima pri prebačaju novih slika';
+$lang['Empty caddie'] = 'Isprazni ladicu';
+$lang['Environment'] = 'Okruženje';
+$lang['Form'] = 'Oblik';
+$lang['Gallery URL'] = 'URL Galerije';
+$lang['Gallery description'] = 'Opis Galerije';
+$lang['Gallery title'] = 'Naziv galerije';
+$lang['Grant selected groups'] = 'Ovlasti odabrane grupe';
+$lang['Grant selected users'] = 'Ovlasti odabrane korisnike';
+$lang['Group name'] = 'Naziv grupe';
+$lang['Groups'] = 'Grupa';
+$lang['Guests'] = 'Gostiju';
+$lang['History'] = 'Povijest';
+$lang['Informations'] = 'Obavijesti';
+$lang['Install'] = 'Ugradi';
+$lang['Link all category elements to a new category'] = 'Poveži sve stavke skupine sa novom skupinom';
+$lang['Link all category elements to some existing categories'] = 'Poveži sve stavke skupine sa nekom postojećom skupinom';
+$lang['Linked categories'] = 'Povezane skupine';
+$lang['Lock gallery'] = 'Zaključaj galeriju';
+$lang['Maintenance'] = 'Održavanje';
+$lang['Manage permissions for a category'] = 'Upravljanje ovlastima za skupinu';
+$lang['Manage permissions for group "%s"'] = 'Upravljanje ovlastima za grupu "%s"';
+$lang['Manage permissions for user "%s"'] = 'Upravljanje ovlastima za korisnika "%s"';
+$lang['Manage tags'] = 'Upravljanje tagovima';
+$lang['Members'] = 'Članovi';
+$lang['Metadata synchronized from file'] = 'Usklađivanje meta podataka iz zapisa';
+$lang['Move categories'] = 'Premjesti skupine';
+$lang['Move'] = 'Premjesti';
+$lang['Name'] = 'Naziv';
+$lang['New name'] = 'Novi naziv';
+$lang['New parent category'] = 'Nova nadređena skupina';
+$lang['New tag'] = 'Novi tag';
+$lang['No tag defined. Use Administration>Pictures>Tags'] = 'Tag nije određen. Koristi Uprava>Slike>Tagovi';
+$lang['Number of comments per page'] = 'Broj komentara po stranici';
+$lang['Number of rates'] = 'Broj ocjena';
+$lang['Number of thumbnails to create'] = 'broj poveznih sličica za izradu';
+$lang['Only private categories are listed'] = 'Samo osobne skupine su ispisane';
+$lang['Operating system'] = 'Operativni sustav';
+$lang['Options'] = 'Mogućnosti';
+$lang['Order alphanumerically'] = 'Abecedno slaganje';
+$lang['Other private categories'] = 'Ostale osobne skupine';
+$lang['Page banner'] = 'Baner stranice';
+$lang['Parent category'] = 'Nadređena skupina';
+$lang['Path'] = 'Putanja';
+$lang['Permalink'] = 'Stalna poveznica';
+$lang['Permalink_%s_histo_used_by_%s'] = 'Stalna poveznica %s je prethodno korištena od skupine %s. Prvo je izbrišite iz starih zapisa';
+$lang['Permalink_name_rule'] = 'Stalna poveznica mora biti sastavljena od znakova a-z, A-Z, 0-9, "-", "_" ili "/". Ne smije biti brojčana vrijednost ili počinjati brojem pa znakom "-"';
+$lang['Permalink %s is already used by category %s'] = 'Stalnu poveznicu %s već koristi skupina %s';
+$lang['Permalink history'] = 'Povijest stalnih poveznica';
+$lang['Permalinks'] = 'Stalne poveznice';
+$lang['Permission denied'] = 'Dozvola uskraćena';
+$lang['Permission granted thanks to a group'] = 'Dozvola odobrena zahvaljujući grupi';
+$lang['Permission granted'] = 'Dozvola odobrena';
+$lang['Picture informations updated'] = 'Podaci o slikama obnovljeni';
+$lang['Plugins'] = 'Dodaci';
+$lang['Position'] = 'Položaj';
+$lang['Preferences'] = 'Postavke';
+$lang['Properties'] = 'Svojstva';
+$lang['Random picture'] = 'Slika slučajnog odabira';
+$lang['Rate date'] = 'Nadnevak ocjene';
+$lang['Rating by guests'] = 'Ocjene gostiju';
+$lang['Rating'] = 'Ocjenjivanje';
+$lang['Reject All'] = 'Odbaci Sve';
+$lang['Reject'] = 'Odbaci';
+$lang['Representant'] = 'Predstavnik';
+$lang['Representation of categories'] = 'Predstavljanje skupina';
+$lang['Representative'] = 'Predstavljeno';
+$lang['Represents'] = 'Predstavlja';
+$lang['Save order'] = 'Redoslijed pohrane';
+$lang['Save to permalink history'] = 'Pohrani u povjest stalnih poveznica';
+$lang['Select at least one category'] = 'Odaberite najmanje jednu skupinu';
+$lang['Select at least one picture'] = 'Odaberite najmanje jednu sliku';
+$lang['Select at least one user'] = 'Odaberite najmanje jednog korisnika';
+$lang['Show info'] = 'Prikaz podataka';
+$lang['Site manager'] = 'Upravnik galerije';
+$lang['Status'] = 'Stanje';
+$lang['Statistics'] = 'Statistika';
+$lang['Storage category'] = 'Skupina pohrane';
+$lang['Sum of rates'] = 'Zbroj ocjena';
+$lang['Tag "%s" already exists'] = 'Tag "%s" već postoji';
+$lang['Tag "%s" was added'] = 'Tag "%s" dodan';
+$lang['Tag selection'] = 'Odabir tagova';
+$lang['Take selected elements out of caddie'] = 'Izvuci odabrane stavke iz ladice';
+$lang['The %d following tag were deleted'] = 'slijedeći tag je izbrisan';
+$lang['The %d following tags were deleted'] = 'Slijedeći %d tagovi su izbrisani';
+$lang['Unable to check for upgrade.'] = 'Ne mogu provjeriti za nadogradnju.';
+$lang['Uninstall'] = 'Ukloni';
+$lang['Use default sort order']='Koristi pretpostavljeni redoslijed slaganja slika (određeno u zapisu postave)';
+$lang['User comments validation'] = 'Ovjera korisničkih komentara';
+$lang['Users'] = 'Korisnici';
+$lang['Validate All'] = 'Ovjeri Sve';
+$lang['Validate'] = 'Ovjeri';
+$lang['Validation'] = 'Ovjera';
+$lang['Version'] = 'Inačica';
+$lang['Virtual categories movement'] = 'Premještanje nestvarnih skupina';
+$lang['Virtual categories to move'] = 'Nestvarne skupine za premještaj';
+$lang['Virtual category name'] = 'Naziv nestvarne skupine';
+$lang['Webmaster cannot be deleted'] = 'Webmaster ne može biti izbrisan';
+$lang['You are running on development sources, no check possible.'] = 'Vi koristite razvojni izvorni kod, provjera nemoguća.';
+$lang['You cannot delete your account'] = "Ne možete izbrisati svoj račun";
+$lang['You cannot move a category in its own sub category'] = 'Ne možete premjestiti skupinu u njenu vlastitu podskupinu';
+$lang['You need to confirm deletion'] = 'trebate potvrditi brisanje';
+$lang['add tags'] = 'dodaj tagove';
+$lang['adviser'] = 'Savjetnik';
+$lang['associate to category'] = 'poveži sa skupinom';
+$lang['associate to group'] = 'poveži sa grupom';
+$lang['authorized'] = 'Ovlašteno';
+$lang['cat_add'] = 'Dodaj nestvarnu skupinu';
+$lang['cat_comments_title'] = 'Ovlastite korisnike za davanje komentara u odabranim skupinama';
+$lang['cat_error_name'] = 'Naziv skupine ne bi trebao biti prazan';
+$lang['cat_lock_title'] = 'Zaključaj skupine';
+$lang['cat_private'] = 'Osobna skupina';
+$lang['cat_public'] = 'Javna skupina';
+$lang['cat_representant'] = 'Izbor novog predstavnika slučajnim odabirom';
+$lang['cat_security'] = 'Javno / Osobno';
+$lang['cat_status_title'] = 'Upravljanje ovlastima za odabrane skupine';
+$lang['cat_upload_title'] = 'Odaberite skupine za prebačaj';
+$lang['cat_virtual_added'] = 'Nestvarna skupina dodana';
+$lang['cat_virtual_deleted'] = 'Nestvarna skupina izbrisana';
+$lang['category'] = 'Skupina';
+$lang['conf_access'] = 'Vrsta pristupa';
+$lang['conf_comments_title'] = 'Komentari';
+$lang['conf_confirmation'] = 'Podaci upisani u bazu podataka';
+$lang['conf_display'] = 'Pretpostavljeni prikaz';
+$lang['conf_history_title'] = 'Povijest';
+$lang['conf_gallery_url_error'] = 'URL galerije nije valjan.';
+$lang['conf_main_title'] = 'Glavno';
+$lang['conf_nb_comment_page_error'] = 'Broj komentara po stranici mora biti između 5 i 50 uključivo.';
+$lang['config'] = 'Postavljanje';
+$lang['confirm'] = 'potvrdi';
+$lang['Date'] = 'Nadnevak';
+$lang['delete category'] = 'izbriši skupinu';
+$lang['dissociate from category'] = 'odspoji od skupine';
+$lang['dissociate from group'] = 'odspoji od grupe';
+$lang['edit category permissions'] = 'uredi ovlasti skupine';
+$lang['editcat_confirm'] = 'Podaci skupine uspješno obnovljeni.';
+$lang['editcat_uploadable'] = 'Odobri prebačaj';
+$lang['elements per page'] = 'stavaka po stranici';
+$lang['elements'] = 'stavke';
+$lang['enabled_high'] = 'Visoka razlučljivost omogućena';
+$lang['file'] = 'Zapis';
+$lang['filesize'] = 'Veličina zapisa';
+$lang['first element added on %s'] = 'prva stavka dodana %s';
+$lang['forbidden'] = 'Zabranjeno';
+$lang['conf_general'] = 'Glavno';
+$lang['global mode'] = 'sveopći način';
+$lang['group "%s" added'] = 'grupa "%s" dodana';
+$lang['group "%s" deleted'] = 'grupa "%s" izbrisana';
+$lang['group "%s" updated'] = 'grupa "%s" obnovljena';
+$lang['group'] = 'grupa';
+$lang['group_add_error1'] = 'Naziv grupe ne može sadržavati  " ili \' ili biti prazan.';
+$lang['group_add_error2'] = 'Ovaj naziv već koristi druga grupa.';
+$lang['groups'] = 'Grupe';
+$lang['instructions'] = 'Upute';
+$lang['is_high_disabled'] = '';
+$lang['is_high_enabled'] = 'Visoka razlučljivost';
+$lang['jump to category'] = 'skok u skupina';
+$lang['jump to image'] = 'skok na sliku';
+$lang['leave'] = 'ostavi';
+$lang['lock'] = 'Zaključaj';
+$lang['locked'] = 'Zaključanp';
+$lang['manage category elements'] = 'upravljanje stavkama skupine';
+$lang['manage sub-categories'] = 'upravljanje podskupinama';
+$lang['manage'] = 'Uprava';
+$lang['maximum height'] = 'najveća visina';
+$lang['maximum width'] = 'najveća širina';
+$lang['nbm_background_treatment_redirect_second'] = 'Vrijeme izvršenja je isteklo, obrada se mora nastaviti [Procijenjeno vrijeme: %d sekunde].';
+$lang['nbm_background_treatment_redirect_seconds'] = 'Vrijeme izvršenja je isteklo, obrada se mora nastaviti [Procijenjeno vrijeme: %d sekundi].';
+$lang['nbm_break_timeout_list_user'] = 'Predviđeno vrijeme za popis korisnika za slanje poruka je ograničeno. Ostali korisnici nisu izlistani.';
+$lang['nbm_break_timeout_send_mail'] = 'Vrijeme za slanje poruke je ograničeno. Ostale poruke su preskočene.';
+$lang['nbm_col_check_user_send_mail'] = 'Poslati ?';
+$lang['nbm_col_last_send'] = 'Zadnje poslano';
+$lang['nbm_col_mail'] = 'e-mail';
+$lang['nbm_col_user'] = 'Korisnik';
+$lang['nbm_complementary_mail_content'] = 'Poptpuni sadržaj e-mail poruke';
+$lang['nbm_content_byebye'] = 'Vidimo se uskoro,';
+$lang['nbm_content_goto_1'] = 'Idi na ';
+$lang['nbm_content_goto_2'] = '.';
+$lang['nbm_content_hello_1'] = 'Pozdrav ';
+$lang['nbm_content_hello_2'] = ',';
+$lang['nbm_content_new_elements'] = 'Nove stavke su dodane ';
+$lang['nbm_content_new_elements_single'] = ' na ';
+$lang['nbm_content_new_elements_between_1'] = 'između ';
+$lang['nbm_content_new_elements_between_2'] = ' i ';
+$lang['nbm_content_subscribe_by_admin'] = 'Webmaster vas je pretlatio na primanje e-mail obavijesti.';
+$lang['nbm_content_subscribe_by_himself'] = 'Pretplatili ste se na primanje e-mail obavijesti.';
+$lang['nbm_content_subscribe_link'] = 'Pretplata';
+$lang['nbm_content_problem_contact'] = 'Ukoliko ste naišli na probleme ili imate pitanja, molimo pošaljite poruku za ';
+$lang['nbm_content_pb_contact_object'] = '[NBM] Problemi ili pitanja';
+$lang['nbm_content_unsubscribe_by_admin'] = 'Webmaster vas je uklonio sa popisa za primanje e-mail obavijesti.';
+$lang['nbm_content_unsubscribe_by_himself'] = 'Uklonili ste se sa popisa za primanje e-mail obavijesti.';
+$lang['nbm_content_click_on'] = ', kliknite na ';
+$lang['nbm_content_unsubscribe_link'] = 'Za uklanjanje';
+$lang['nbm_info_send_mail_as'] = 'Sa praznim poljem, koristiti će se naziv galerijeg';
+$lang['nbm_item_notification'] = 'Obavijest';
+$lang['nbm_msg_error_sending_email_to'] = 'Greška prilikom slanja e-mail poruke za %s [%s].';
+$lang['nbm_msg_mail_sent_to'] = 'Poruka poslana za %s [%s].';
+$lang['nbm_msg_n_mail_sent'] = '%d poruka poslana.';
+$lang['nbm_msg_n_mails_sent'] = '%d poruke poslane.';
+$lang['nbm_msg_n_mail_not_send'] = '%d poruka nije poslane.';
+$lang['nbm_msg_n_mails_not_send'] = '%d poruke nisu poslane.';
+$lang['nbm_no_mail_to_send'] = 'Nema poruke za slanje.';
+$lang['nbm_no_user_available_to_send_L1'] = 'Nema dostupnih primatelja za slanje poruka.';
+$lang['nbm_no_user_available_to_send_L2'] = 'Pretplatnici mogu biti izlistani (dostupni) samo ako ima novih stavki za obavijest.';
+$lang['nbm_no_user_available_to_send_L3'] = 'U svakom slučaju samo webmaster može pristupiti ovoj ploči a nikad upravitelji.';
+$lang['nbm_no_user_to send_notifications_by_mail'] = 'Nema korisnika za slanje e-mail obavijesti.';
+$lang['nbm_object_news'] = 'Nove stavke dodane';
+$lang['nbm_object_subscribe'] = 'Pretplatite se za e-mail obavijesti';
+$lang['nbm_object_unsubscribe'] = 'Uklonite se iz sustava primanja e-mail obavijesti';
+$lang['nbm_param_mode'] = 'Stavka';
+$lang['nbm_redirect_msg'] = 'Obrada postupka.'."\n\n".'Molimo sačekajte...';
+$lang['nbm_repost_submit'] = 'Nastavi obradu postupka';
+$lang['nbm_send_complementary_mail_content'] = 'Cjelokupni sadržaj poruke';
+$lang['nbm_send_detailed_content'] = 'Dodaj cjeli sadržaj';
+$lang['nbm_send_mail_as'] = 'Pošalji poruku kao ';
+$lang['nbm_send_mail_to_users'] = 'Pošalji poruku korisnicima';
+$lang['nbm_send_mode'] = 'Pošalji';
+$lang['nbm_send_options'] = 'Mogućnosti';
+$lang['nbm_send_submit'] = 'Pošalji';
+$lang['nbm_subscribe_col'] = 'Pretplaćen';
+$lang['nbm_subscribe_mode'] = 'Pretplatite se';
+$lang['nbm_title_param'] = 'Stavke';
+$lang['nbm_title_send'] = 'Odaberite primatelje';
+$lang['nbm_title_subscribe'] = 'Pretplati/poništi pretplatu korosnika';
+$lang['nbm_unsubscribe_col'] = 'Pretplata poništena';
+$lang['nbm_updated_param_count'] = '%d stavka je obnovljena.';
+$lang['nbm_updated_params_count'] = '%d stavke su poništene.';
+$lang['nbm_user_change_enabled_error_on_updated_data_count'] = '%d korisnik nije obnovljen.';
+$lang['nbm_users_change_enabled_error_on_updated_data_count'] = '%d korisnici nisu obnovljeni.';
+$lang['nbm_user_change_enabled_false'] = 'User %s [%s] je uklonjen iz popisa pretplatnika.';
+$lang['nbm_user_change_enabled_true'] = 'User %s [%s] je dodan na popis pretplatnika.';
+$lang['nbm_user_change_enabled_updated_data_count'] = '%d korisnik je obnovljen.';
+$lang['nbm_users_change_enabled_updated_data_count'] = '%d korisnici su obnovljeni.';
+$lang['nbm_user_not_change_enabled_false'] = 'Korisnik %s [%s] nije uklonjen iz popisa pretplatnika.';
+$lang['nbm_user_not_change_enabled_true'] = 'Korisnik %s [%s] nije dodan na popis pretplatnika.';
+$lang['nbm_user_x_added'] = 'Korisnik %s [%s] dodan.';
+$lang['nbm_warning_subscribe_unsubscribe'] = 'Upozorenje: pretplata ili ukidanje pretplate će poslati e-mail poruke korisnicima';
+$lang['nbm_send_html_mail'] = 'Pošalji poruku u HTML obliku';
+$lang['nbm_send_recent_post_dates'] = 'Uključi prikaz nedavnih slika složenih po nadnevcima';
+$lang['nbm_info_send_recent_post_dates'] = 'Dostupno samo u HTML obliku';
+$lang['no_write_access'] = 'nema dozvole upisa';
+$lang['path'] = 'putanja';
+$lang['permissions'] = 'Dozvole';
+$lang['private'] = 'osobno';
+$lang['properties'] = 'Svojstva';
+$lang['public'] = 'javno';
+$lang['purge never used notification feeds'] = 'Isprazni nikad korištene obavijesne izvore';
+$lang['purge sessions'] = 'Isprazni sjednice';
+$lang['randomly represented'] = 'predstavljen slučajnim odabirom';
+$lang['registration_date'] = 'nadnevak upisa';
+$lang['remote_site'] = 'Udaljeno mjesto';
+$lang['remote_site_clean'] = 'čisto';
+$lang['remote_site_clean_hint'] = 'ukloni udaljeni listing.xml zapis';
+$lang['remote_site_generate'] = 'izradi popis';
+$lang['remote_site_generate_hint'] = 'izradi listing.xml zapis na udaljenom mjestu';
+$lang['remote_site_local_create'] = 'Izgradi ovo mjesto';
+$lang['remote_site_local_found'] = 'Mjesni listing.xml zapis je pronađen za ';
+$lang['remote_site_local_update'] = 'čitam mjesni listing.xml i obnavljam';
+$lang['remote_site_test'] = 'proba';
+$lang['remote_site_test_hint'] = 'isprobajte ovo udaljeno mjesto';
+$lang['remote_site_uncorrect_url'] = 'URL udaljeno mjesta mora počinjati sa http ili https i može sadržavati samo znakove "/", "a-zA-Z0-9", "-" ili "_"';
+$lang['remove tags'] = 'ukloni tagove';
+$lang['repair and optimize database'] = 'Popravi i ugodi bazu podataka';
+$lang['selection'] = 'odabir';
+$lang['set to'] = 'postavljeno na';
+$lang['singly represented'] = 'jednoznačno predstavljeno';
+$lang['site_already_exists'] = 'Ovo mjesto već postoji';
+$lang['site_create'] = 'Izradi novo mjesto : (odreite njegov URL za izradu create_listing_file.php)';
+$lang['site_created'] = 'izrađeno';
+$lang['site_delete'] = 'izbriši';
+$lang['site_delete_hint'] = 'izbriši ovo mjesto i sve njegove pridodane stavke';
+$lang['site_deleted'] = 'izbrisano';
+$lang['site_err'] = 'došlo je do greške';
+$lang['site_err_remote_file_not_found'] = 'zapis create_listing_file.php na udaljenom mjestu nije pronađen';
+$lang['site_local'] = 'Mjesno';
+$lang['site_remote'] = 'Udaljeno';
+$lang['site_synchronize'] = 'uskladi';
+$lang['site_synchronize_hint'] = 'obnovi bazu podataka pomoću zapisa';
+$lang['status'] = 'stanje';
+$lang['storage'] = 'Mapa';
+$lang['sub-categories'] = 'podskupine';
+$lang['synchronize metadata'] = 'uskladi meta podatke';
+$lang['synchronize'] = 'uskladi';
+$lang['target'] = 'odredište';
+$lang['thumbnail'] = 'Povezne sličice';
+$lang['title'] = 'naslov';
+$lang['title_categories'] = 'Upravljanje skupinama';
+$lang['title_configuration'] = 'Piwigo postave';
+$lang['title_default'] = 'Piwigo uprava';
+$lang['title_edit_cat'] = 'Uredi skupinu';
+$lang['title_groups'] = 'Upravljanje grupama';
+$lang['title_liste_users'] = 'Popis korisnika';
+$lang['title_picmod'] = 'Promjena podataka o slici';
+$lang['title_thumbnails'] = 'Izrada poveznij sličica';
+$lang['title_update'] = 'Usklađivanje baze podataka sa zapisima';
+$lang['title_upload'] = 'Slike na čekanju ovjere';
+$lang['tn_all'] = 'sve';
+$lang['tn_alone_title'] = 'slike bez poveznih sličica (samo jpeg i png)';
+$lang['tn_err_height'] = 'visina mora biti broj veći od ';
+$lang['tn_err_width'] = 'širina mora biti broj veći od';
+$lang['tn_format'] = 'za zapisni oblik';
+$lang['tn_no_missing'] = 'Nema nedostajućih poveznih sličica';
+$lang['tn_no_support'] = 'Slika nedohvatna ili bez podrške';
+$lang['tn_params_GD'] = 'GD inačica';
+$lang['tn_params_title'] = 'Postavke umanjivanja';
+$lang['tn_results_gen_time'] = 'izrađena u';
+$lang['tn_results_title'] = 'ishodi umanjivanja';
+$lang['tn_stats'] = 'Glavna statistika';
+$lang['tn_stats_max'] = 'najveće vrijeme';
+$lang['tn_stats_mean'] = 'prosječno vrijeme';
+$lang['tn_stats_min'] = 'najmanje vrijeme';
+$lang['tn_stats_nb'] = 'broj umanjenih slika';
+$lang['tn_stats_total'] = 'sveukupno vrijeme';
+$lang['tn_thisformat'] = 'za ovu vrstu zapisa';
+$lang['unit mode'] = 'jedinični način';
+$lang['unlocked'] = 'Otključano';
+$lang['unset'] = 'razdešeno';
+$lang['up'] = 'Premjesti gore';
+$lang['update categories informations'] = 'Obnovi podatke o skupinama';
+$lang['update images informations'] = 'Obnovi podatke o slikama';
+$lang['update'] = 'Uskladi';
+$lang['update_cats_subset'] = 'suzi na jednu postojeću skupinu-e';
+$lang['update_default_title'] = 'Izaberite mogućnost';
+$lang['update_display_info'] = 'najopširniji mogući prikaz podataka (dodane skupine i stavke, izbrisane  skupine i stavke)';
+$lang['update_err_pwg_version_differs'] = 'Piwigo inačica na udaljenom mjestu se razlikuje';
+$lang['update_err_pwg_version_differs_info'] = 'Inačica create_listing_file.php na udaljenom mjestu i Piwigo-u mora biti jednaka';
+$lang['update_err_remote_listing_not_found'] = 'listing.xml zapis nije pronađen';
+$lang['update_err_remote_listing_not_found_info'] = 'listing.xml zapis nije pronađen na udaljenom mjestu. Ovaj zapis se izrađuje odabirom "izradi popis" mogućnosti u Upravi mjesta';
+$lang['update_error_list_title'] = 'Greška popisa';
+$lang['update_errors_caption'] = 'Zaglavlja grešaka';
+$lang['update_infos_title'] = 'Podrobnije obavjesti';
+$lang['update_missing_file_or_dir'] = 'Greška čitanja zapisa/mape';
+$lang['update_missing_file_or_dir_info'] = 'Zapisu ili mapi se ne može pristupiti (ne postoji ili je pristup zabranjen)';
+$lang['update_missing_tn_info'] = 'tip slikovnog zapisa zahtjeva poveznu sličicu. Povezna sličica mora biti prisutna u podmapi "thumbnail" mape skupine. Naziv povezne sličice mora počinjati sa pretpostavljenim predznakom i nastavak mora biti jedan od popisanih :';
+$lang['update_missing_tn_short'] = 'nedostajuće povezne sličice';
+$lang['update_nb_del_categories'] = 'skupine izbrisane iz baze podataka';
+$lang['update_nb_del_elements'] = 'stavke izbrisane iz baze podataka';
+$lang['update_nb_elements_metadata_available'] = 'slika kandidata za usklađivanje meta podataka';
+$lang['update_nb_elements_metadata_sync'] = 'podataka stavaka usklađeno sa meta podacima zapisa';
+$lang['update_nb_errors'] = 'grešaka tijekom usklađivanja';
+$lang['update_nb_new_categories'] = 'skupina dodano u bazu podataka';
+$lang['update_nb_new_elements'] = 'stavaka dodano u bazu podataka';
+$lang['update_nb_upd_elements'] = 'stavaka obnovljeno u bazi podataka';
+$lang['update_part_research'] = 'Pretraživanje novih slika u mapama';
+$lang['update_research_added'] = 'dodano';
+$lang['update_research_deleted'] = 'izbrisano';
+$lang['update_result_metadata'] = 'Ishodi usklađivanja meta podataka';
+$lang['update_simulate'] = 'izvrši samo oponašanje (nema promjena u bazi podataka)';
+$lang['update_simulation_title'] = '[Oponašanje]';
+$lang['update_sync_all'] = 'mape + zapise';
+$lang['update_sync_dirs'] = 'samo mape';
+$lang['update_sync_files'] = 'uskladi sastav zapisa sa bazom podataka';
+$lang['update_sync_metadata'] = 'uskladi meta podatke zapisa sa podacima stavki baze podataka';
+$lang['update_sync_metadata_all'] = 'čak i već usklađene stavke';
+$lang['update_used_metadata'] = 'Korišteni meta podaci';
+$lang['update_wrong_dirname_info'] = 'Nazivi mapa i zapisa moraju biti sastavljeni od slova, brojva, "-", "_" ili "."';
+$lang['update_wrong_dirname_short'] = 'krivi naziv zapisa';
+$lang['upload'] = 'Prebaci';
+$lang['user "%s" added'] = 'korisnik "%s" dodan';
+$lang['user_status'] = 'Stanje korisnika';
+$lang['user_status_admin'] = 'Upravnik';
+$lang['user_status_generic'] = 'Općenit';
+$lang['user_status_guest'] = 'Gost';
+$lang['user_status_normal'] = 'Korisnik';
+$lang['user_status_webmaster'] = 'Webmaster';
+$lang['username'] = 'korisničko ime';
+$lang['users'] = 'Korisnici';
+$lang['virtual_category'] = 'Nestvarna skupina';
+$lang['waiting'] = 'Čekanje';
+$lang['is_default_group'] = 'pretpostavljeno';
+$lang['toggle_is_default_group'] = 'Promijeni \'pretpostavljena grupa\' svojstva';
+$lang['Advanced_features'] = 'Napredne mogućnosti';
+$lang['Elements_not_linked'] = 'Nema povezanih stavki';
+$lang['special_admin_menu'] = 'Posebnosti';
+$lang['Duplicates'] = 'Zapisi istog imena u više od jednoj stvarnoj skupini';
+
+$lang['Overall'] = 'Sveukupno';
+$lang['Year'] = 'Godina';
+$lang['Month'] = 'Mjesec';
+$lang['Day'] = 'Dan';
+$lang['Pages seen'] = 'Stranica viđeno';
+$lang['Pictures'] = 'Slika';
+$lang['time'] = 'Vrijeme';
+$lang['user'] = 'Korisnik';
+$lang['IP'] = 'IP';
+$lang['image'] = 'Stavka';
+$lang['section'] = 'Odjeljak';
+$lang['tags'] = 'Tagovi';
+$lang['conf_history_guest'] = 'Pohrani posjete stranicama po gostima';
+$lang['conf_history_user'] = 'Pohrani posjete stranicama po korisnicima';
+$lang['conf_history_admin'] = 'Pohrani posjete stranicama upraviteljima';
+$lang['cat_options_title'] = 'Svojstva';
+$lang['An information email was sent to group "%s"'] = 'Obavijesna e-mail poruka je poslana grupi "%s';
+$lang['Send an information email to group members'] = 'Pošalji obavijesni e-mail članovima grupe';
+$lang['Group'] = 'Grupa';
+$lang['[%s] Come to visit the category %s'] = '[%s] Dođite i pogledajte skupinu %s';
+$lang['Hello,'] = 'Pozdrav,';
+$lang['See you soon.'] = 'Do skorog viđenja.';
+$lang['Come to discover the category:'] = 'Dođite i otkrijte skupinu:';
+$lang['mail_content'] = 'sadržaj e-mail poruke';
+$lang['none'] = 'ni jedan';
+$lang['high'] = 'visoko';
+$lang['other'] = 'ostalo';
+$lang['Element type'] = 'Tip stavke';
+$lang['User'] = 'Korisnik';
+$lang['Image id'] = 'ID slike';
+$lang['Summary'] = 'Zbirno';
+$lang['%d line filtered'] = '%d linija pročišćena';
+$lang['%d lines filtered'] = '%d linija pročišćeno';
+$lang['%d guest'] = '%d gost';
+$lang['%d guests'] = '%d gostiju';
+$lang['Hour'] = 'Sat';
+$lang['is_the_guest'] = 'gost';
+$lang['is_the_default'] = 'pretpostavljene vrijednosti';
+$lang['High filesize'] = 'Visoka veličina zapisa';
+// --------- Starting below: New or revised $lang ---- from version 1.7.1
+$lang['Guest cannot be deleted'] = 'Gost ne može biti izbrisan';
+$lang['Default user cannot be deleted'] = 'Pretpostavljeni korisnik ne može biti izbrisan';
+$lang['purge history detail'] = 'Isprazni povijesne pojedinosti';
+$lang['purge history summary'] = 'Isprazni povijesni zbir';
+$lang['c13y_title'] = 'Provjera cjelovitosti';
+$lang['c13y_Anomaly'] = 'Nepravilnost';
+$lang['c13y_Correction'] = 'Ispravak';
+$lang['c13y_Automatic_correction'] = 'Samostalno ispravljanje';
+$lang['c13y_Impossible_automatic_correction'] = 'Samostalno ispravljanje nemoguće';
+$lang['c13y_Correction_applied_success'] = 'Ispravka uspješno ugrađena';
+$lang['c13y_Correction_applied_error'] = 'Ispravka ugrađena s greškom';
+$lang['c13y_anomaly_count'] = '%d nepravilnost je otkrivena.';
+$lang['c13y_anomalies_count'] = '%d nepravilnosti su otkrivene.';
+$lang['c13y_anomaly_corrected_count'] = '%d nepravilnost je ispravljena.';
+$lang['c13y_anomalies_corrected_count'] = '%d nepravilnosti je ispravljeno.';
+$lang['c13y_anomaly_not_corrected_count'] = '%d nepravilnost nije ispravljena.';
+$lang['c13y_anomalies_not_corrected_count'] = '%d nepravilnosti nije ispravljeno.';
+$lang['c13y_more_info'] = 'Idite na %s ili %s za više pojedinosti';
+$lang['c13y_more_info_forum'] = 'forum';
+$lang['c13y_more_info_wiki'] = 'wiki';
+$lang['c13y_exif_anomaly'] = '%s vrijednost nije valjani zapis jer exif nije podržan';
+$lang['c13y_exif_correction'] = '%s mora biti postavljeno na false u config_local.inc.php file';
+$lang['c13y_guest_non_existent'] = 'Glavni "guest" korisnik ne postoji';
+$lang['c13y_bad_guest_status'] = 'Stanje glavnog "guest" korisnika je neispravno';
+$lang['c13y_default_non_existent'] = 'Pretpostavljeni korisnik ne postojit';
+$lang['c13y_webmaster_non_existent'] = 'Glavni "webmaster" korisnik ne postoji';
+$lang['c13y_bad_webmaster_status'] = 'Stanje glavnog "webmaster" korisnika je neispravno';
+$lang['c13y_user_created'] = 'Korisnik "%s" izrađen sa "%s" kao zaporkom';
+$lang['c13y_user_status_updated'] = 'Stanje korisnika "%s" obnovljeno';
+$lang['add new elements to caddie'] = 'dodaj nove stavke u ladicu';
+// --------- Starting below: New or revised $lang ---- from Butterfly
+$lang['no_display_thumbnail'] = 'Bez prikaza';
+$lang['display_thumbnail_classic'] = 'Klasični prikaz';
+$lang['display_thumbnail_hoverbox'] = 'Prikaz lebdećim prozorom';
+$lang['Thumbnails'] = 'Povezne sličice';
+$lang['obligatory_user_mail_address'] = 'E-mail adresa je obavezna za sve korisnike';
+$lang['Minimum privacy level'] = 'Najniža razina privatnosti';
+$lang['Privacy level'] = 'Razina privatnosti';
+$lang['Level 0'] = '---';
+$lang['Level 1'] = 'Poznanici';
+$lang['Level 2'] = 'Prijatelji';
+$lang['Level 4'] = 'Obitelj';
+$lang['Level 8'] = 'Upravnici';
+$lang['c13y_maintenance'] = 'Ponovi provjeru cjelovitosti';
+$lang['Check all'] = 'Označi sve';
+$lang['Uncheck all'] = 'Odznači sve';
+$lang['c13y_check_auto'] = 'Označi samoispravke';
+$lang['c13y_submit_correction'] = 'Primjeni odabrane ispravke';
+$lang['c13y_submit_ignore'] = 'Zanemari odabrane nepravilnosti';
+$lang['c13y_submit_refresh'] = 'Osvježi';
+$lang['c13y_ignore_msg1'] = 'Nepravilnost će se zanemariti do slijedeće inačice galerije';
+$lang['c13y_ignore_msg2'] = 'Ispravak nepravilnosti će poništiti činjenicu da je zanemarena';
+$lang['c13y_anomaly_ignored_count'] = '%d nepravilnost je zanemarena.';
+$lang['c13y_anomalies_ignored_count'] = '%d nepravilnosti su zanemarene.';
+$lang['plugins_need_update'] = 'Dodaci koji trebaju nadogradnju';
+$lang['plugins_dontneed_update'] = 'Dodaci su usklađeni';
+$lang['plugins_cant_check'] = 'Inačice dodataka ne mogu se provjeriti';
+$lang['plugins_actual_version'] = 'Trenutna <br>inačica';
+$lang['plugins_new_version'] = 'Dostupna<br>inačica';
+$lang['plugins_auto_update'] = 'Samostalna nadogradnja';
+$lang['plugins_auto_install'] = 'Samostalna ugradba';
+$lang['plugins_download'] = 'Preuzmi zapis';
+$lang['plugins_tab_list'] = 'Popis dodataka';
+$lang['plugins_tab_update'] = 'Provjera nadogradnji';
+$lang['plugins_tab_new'] = 'Ostali dodaci';
+$lang['plugins_revisions'] = 'Zadnja izdanja';
+$lang['plugins_delete'] = 'Izbriši';
+$lang['plugins_confirm_delete'] = 'Sigurno želite ukloniti ovaj dodatak?';
+$lang['plugins_confirm_install'] = 'Sigurno želite ugraditi ovaj dodatak?';
+$lang['plugins_confirm_upgrade'] = 'Sigurno želite ugraditi ovaj dodatak? Morate ovjeriti ako ova inačica ne treba uklanjanje.';
+$lang['plugins_upgrade_ok'] = '%s je uspješno obnovljen.';
+$lang['plugins_install_ok'] = 'Dodatak je uspješno preslikan';
+$lang['plugins_install_need_activate'] = 'Možete ići na popis dodataka za ugradbu i pokretanje.';
+$lang['plugins_temp_path_error'] = 'Ne mogu napraviti privremeni zapis.';
+$lang['plugins_dl_archive_error'] = 'Ne mogu preuzeti zapis.';
+$lang['plugins_archive_error'] = 'Ne mogu očitati ili izlučiti zapis.';
+$lang['plugins_extract_error'] = 'Došlo je do greške prilikom izlučivanja (%s).';
+$lang['plugins_check_chmod'] = 'Provjerite "plugins" mapu i dozvole podmapa (CHMOD).';
+$lang['plugins_server_error'] = 'Ne mogu se povezati na poslužitelj.';
+$lang['Purge compiled templates'] = 'Isprazni obrađene predloške';
+$lang['Caddie is currently empty'] = 'Ladica je trenutno prazna';
+$lang['conf_upload_title'] = 'Prebaci';
+$lang['Show upload link every time'] = 'Prikaži poveznicu prebačaja svaki put';
+$lang['User access level to upload'] = 'Pristupna korisnička razina potrebna za prebačaj';
+$lang['ACCESS_0'] = 'Slobodan pristup';
+$lang['ACCESS_1'] = 'Pristup svima';
+$lang['ACCESS_2'] = 'Pristup pretplatnicima';
+$lang['ACCESS_3'] = 'Pristup upraviteljima';
+$lang['ACCESS_4'] = 'Pristup webmaster-ima';
+$lang['ACCESS_5'] = 'Bez pristupa';
+$lang['DEMO'] = 'Demo';
+$lang['HOME'] = 'Piwigo naslovnica';
+$lang['FORUM'] = 'Podrška';
+$lang['BUGS'] = 'Greške';
+$lang['EXTENSIONS'] = 'Proširenja';
+$lang['WIKI / DOC'] = 'Dokumentacija';
+$lang['A new version of Piwigo is available.'] = 'Nova Piwigo inačica je dostupna.';
+$lang['Piwigo Administration'] = 'Piwigo Uprava';
+$lang['Piwigo version'] = 'Piwigo inačica';
+$lang['You are running the latest version of Piwigo.'] = 'Koristite najnoviju inačicu Piwigo-a.';
+$lang['c13y_version_anomaly'] = 'Inačica od %s [%s] postavljene nije sukladna potrebnoj inačici [%s]';
+$lang['c13y_version_correction'] = 'trebate nadograditi vaš sustav da biste imali sve pogodnosti u protivnom sustav neće raditi uredno ili uopće neće raditi';
+$lang['Deleted on'] = 'Izbrisan na';
+$lang['Last hit'] =  'Zadnji posjet';
+$lang['Hits'] = 'Posjeta';
+$lang['GD library is missing'] = 'Nedostaje GD biblioteka';
+$lang['conf_extents'] = 'Predlošci';
+$lang['extend_for_templates'] = 'Proširenje za predloške';
+$lang['Replacement of original templates'] =
+ 'Zamjena izvornih predložaka prilagođenima iz podmape template-extension';
+$lang['Replacers'] = 'Zamjene (prilagođeni predlošci)';
+$lang['Original templates'] = 'Izvorni predlošci';
+$lang['Optional URL keyword'] = 'Izborna URL ključna riječ';
+$lang['Templates recorded.'] = 'Postava predložaka je pohranjena.';
+$lang['Optimizations completed'] = 'Sva poboljšanja su uspješno dovršena.';
+$lang['Optimizations errors'] = 'Poboljšanja su izvršena uz neke greške.';
+$lang['delete this comment'] = 'izbriši ovaj komentar';
+$lang['link_info_image'] = 'Promijeni podatak';
+$lang['edit category informations'] = 'uredi podatke o skupini';
+$lang['nothing'] = 'ništa';
+$lang['overrides existing values with empty ones'] = 'prekucava postojeće vrijednosti praznim poljima';
+$lang['manage image ranks'] = 'upravljanje poretkom slika';
+$lang['Manage image ranks'] = 'Uprava poretkom';
+$lang['Edit ranks'] = 'Uredi poredak';
+$lang['No element in this category'] = 'Nema stavke u ovoj skupini';
+$lang['Images manual order was saved'] = 'Pohranjen je izvorni redoslijed slika';
+$lang['ranks'] = 'poretci';
+$lang['Drag to re-order'] = 'Povuci za preslagivanje';
+$lang['Unable to retrieve server informations since allow_url_fopen is disabled.'] = 'Dohvat poslužiteljskih podataka nemoguć jer je allow_url_fopen onemogućen.';
+$lang['Quick Local Synchronization'] = 'Brzo Mjesno Usklađivanje';
+$lang['No photo can be deleted'] = 'Nema slike koja se može brisati';
+$lang['Note: Only deletes photos added with pLoader'] = 'Obavjest: Briše samo slike dodane sa pLoader-om';
+$lang['Delete selected photos'] = 'Briši odabrane slike';
+$lang['%d photo was deleted'] = '%d slika je izbrisana';
+$lang['%d photos were deleted'] = '%d slike su izbrisane';
+$lang['Bound template'] = 'Poveži predložak';
+$lang['Downloads'] = 'Preuzimanja';
+$lang['Released on'] = 'Objavljeno dana';
+$lang['Number of downloads'] = 'Broj preuzimanja';
+?>
Index: /tags/2.0.2/language/hr_HR/common.lang.php
===================================================================
--- /tags/2.0.2/language/hr_HR/common.lang.php	(revision 3278)
+++ /tags/2.0.2/language/hr_HR/common.lang.php	(revision 3278)
@@ -0,0 +1,368 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Langage informations
+$lang_info['language_name'] = 'Hrvatski';
+$lang_info['country'] = 'Hrvatska';
+$lang_info['direction'] = 'ltr';
+$lang_info['code'] = 'hr';
+$lang_info['zero_plural'] = true;
+
+$lang['%.2f (rated %d times, standard deviation = %.2f)'] = '%.2f (ocijenjeno %d puta, standardno odstupanje = %.2f)';
+$lang['%d Kb'] = '%d Kb';
+$lang['%d category updated'] = '%d skupina obnovljena';
+$lang['%d categories updated'] = '%d skupine obnovljene';
+$lang['%d comment to validate'] = '%d komentar za ovjeru';
+$lang['%d comments to validate'] = '%d komentari za ovjeru';
+$lang['%d new comment'] = '%d novi komentar';
+$lang['%d new comments'] = '%d novi komentari';
+$lang['%d comment'] = '%d komentar';
+$lang['%d comments'] = '%d komentari';
+$lang['%d hit'] = '%d posjet';
+$lang['%d hits'] = '%d posjeta';
+$lang['%d new element'] = '%d nova slika';
+$lang['%d new elements'] = '%d nove slike';
+$lang['%d new user'] = '%d novi korisnik';
+$lang['%d new users'] = '%d novi korisnici';
+$lang['%d waiting element'] = '%d stavka na čekanju';
+$lang['%d waiting elements'] = '%d stavke na čekanju';
+$lang['About'] = 'O...';
+$lang['All tags must match'] = 'Svi tagovi se moraju poklapati';
+$lang['All tags'] = 'Svi tagovi';
+$lang['Any tag'] = 'Bilo koji tag';
+$lang['At least one listed rule must be satisfied.'] = 'Najmanje jedno od navedenih pravila mora biti zadovoljeno.';
+$lang['At least one tag must match'] = 'Najmanje jedan tag se mora poklapati';
+$lang['Author'] = 'Autor';
+$lang['Average rate'] = 'Prosječna ocjena';
+$lang['Categories'] = 'Skupine';
+$lang['Category'] = 'Skupina';
+$lang['Close this window'] = 'Zatvori prozor';
+$lang['Complete RSS feed'] = 'Potpuni RSS izvori (slike, komentari)';
+$lang['Confirm Password'] = 'Potvrdi Zaporku';
+$lang['Connection settings'] = 'Postavke povezivanja';
+$lang['Connection'] = 'Prijava';
+$lang['Contact webmaster'] = 'Pišite webmaster-u';
+$lang['Create a new account'] = 'Izradi novi račun';
+$lang['Created on'] = 'Izrađen na';
+$lang['Creation date'] = 'Nadnevak izrade';
+$lang['Current password is wrong'] = 'Trenutna zaporka je neispravna';
+$lang['Dimensions'] = 'Veličine';
+$lang['Display'] = 'Prikaz';
+$lang['Each listed rule must be satisfied.'] = 'Svako navedeno pravilo mora biti zadovoljeno.';
+$lang['Email address is missing'] = 'Nedostaje E-mail adresa';
+$lang['Email address'] = 'E-mail adresa';
+$lang['Enter your personnal informations'] = 'Upišite svoje osobne podatke';
+$lang['Error sending email'] = 'Greška prilikom slanja e-mail poruke';
+$lang['File name'] = 'Naziv zapisa';
+$lang['File'] = 'Zapis';
+$lang['Filesize'] = 'Veličina zapisa';
+$lang['Filter and display'] = 'Filter i prikaz';
+$lang['Filter'] = 'Filter';
+$lang['Forgot your password?'] = 'Zaboravili ste zaporku?';
+$lang['Go through the gallery as a visitor'] = 'Pregledajte galeriju kao posjetitelj';
+$lang['Help'] = 'Pomoć';
+$lang['Identification'] = 'Prijavnica';
+$lang['Image only RSS feed'] = 'RSS izvor samo za slike';
+$lang['Keyword'] = 'Ključna riječ';
+$lang['Links'] = 'Poveznice';
+$lang['Mail address'] = 'E-Mail adresa';
+$lang['N/A'] = 'N/D';
+$lang['New on %s'] = 'Novi na on %s';
+$lang['New password confirmation does not correspond'] = 'Potvrda nove zaporke ne odgovara';
+$lang['New password sent by email'] = 'Nova zaporka poslana e-mail porukom';
+$lang['No email address'] = 'Nema e-mail adrese';
+$lang['No user matches this email address'] = 'Nijedan korisnik se ne poklapa s ovom e-mail adresom';
+$lang['Notification'] = 'Obavijest';
+$lang['Number of items'] = 'Broj stavki';
+$lang['Original dimensions'] = 'Izvorne veličine';
+$lang['Password forgotten'] = 'Zaboravljena zaporka';
+$lang['Password'] = 'Zaporka';
+$lang['Post date'] = 'Nadnevak objave';
+$lang['Posted on'] = 'Objavljeno u';
+$lang['Profile'] = 'Profil';
+$lang['Quick connect'] = 'Brza veza';
+$lang['RSS feed'] = 'RSS izvor';
+$lang['Rate'] = 'Ocjena';
+$lang['Register'] = 'Upišite se';
+$lang['Registration'] = 'Upis';
+$lang['Related tags'] = 'Odnosni tagovi';
+$lang['Reset'] = 'Poništi';
+$lang['Retrieve password'] = 'Dohvati zaporku';
+$lang['Search rules'] = 'Pravila pretrage';
+$lang['Search tags'] = 'Tagovi pretrage';
+$lang['Search'] = 'Pretraživanje';
+$lang['See available tags'] = 'Pogledaj dostupne tagove';
+$lang['Send new password'] = 'Pošalji novu zaporku';
+$lang['Since'] = 'Od';
+$lang['Sort by'] = 'Složeno po';
+$lang['Sort order'] = 'Redoslijed slaganja';
+$lang['Tag'] = 'Tag';
+$lang['Tags'] = 'Tagovi';
+$lang['The RSS notification feed provides notification on news from this website : new pictures, updated categories, new comments. Use a RSS feed reader.'] = 'RSS obavijesni izvor omogućava obavještavanje o novostima sa ovog web mjesta : nove slike, obnovljene skupine, nove komentare. Koristite čitač RSS izvora.';
+$lang['Unknown feed identifier'] = 'Nepoznata oznaka izvora';
+$lang['User comments'] = 'Korisnički komentari';
+$lang['Username'] = 'Korisničko ime';
+$lang['Visits'] = 'Posjeta';
+$lang['Webmaster'] = 'Webmaster';
+$lang['Week %d'] = 'Tjedan %d';
+$lang['about_page_title'] = 'O Piwigo-u';
+$lang['access_forbiden'] = 'Niste ovlašteni za pristup zatraženoj stranici';
+$lang['add to caddie'] = 'dodaj u ladicu';
+$lang['add_favorites_hint'] = 'dodaj ovu sliku u omiljene';
+$lang['admin'] = 'Uprava';
+$lang['adviser_mode_enabled'] = 'Savjetnički modul omogućen';
+$lang['all'] = 'sve';
+$lang['ascending'] = 'uzlazno';
+$lang['author(s) : %s'] = 'autor(i) : %s';
+$lang['auto_expand'] = 'Proširi sve skupine';
+$lang['became available after %s (%s)'] = 'objavljeno nakon %s (%s)';
+$lang['became available before %s (%s)'] = 'objavljeno prije %s (%s)';
+$lang['became available between %s (%s) and %s (%s)'] = 'objavljeno između %s (%s) i %s (%s)';
+$lang['became available on %s'] = 'objavljeno na %s';
+$lang['best_rated_cat'] = 'Najbolje ocijenjeno';
+$lang['best_rated_cat_hint'] = 'prikaz najbolje ocijenjenih stavki';
+$lang['caddie'] = 'ladica';
+$lang['calendar'] = 'Kalendar';
+$lang['calendar_any'] = 'Sve';
+$lang['calendar_hint'] = 'prikaz svakog dana sa slikama, mjesec po mjesec';
+$lang['calendar_picture_hint'] = 'prikaz slika dodanih na';
+$lang['calendar_view'] = 'Pogledaj';
+$lang['chronology_monthly_calendar'] = 'Mjesečni kalendar';
+$lang['chronology_monthly_list'] = 'Mjesečni popis';
+$lang['chronology_weekly_list'] = 'Tjedni popis';
+$lang['click_to_redirect'] = 'Kliknite ovdje ako niste samostalno prebačeni';
+$lang['comment date'] = 'nadnevak komentara';
+$lang['comment'] = 'Komentar';
+$lang['comment_added'] = 'Vaš je komentar upisan';
+$lang['comment_anti-flood'] = 'Anti-flood sustav : molimo sačekajte malo prije objave novog komentara';
+$lang['comment_not_added'] = 'Vaš komentar NIJE upisan jer nije prošao pravila ovjere';
+$lang['comment_to_validate'] = 'Upravnik mora odobriti vaš komentar prije objave.';
+$lang['comment_user_exists'] = 'Ovo korisničko ime se već koristi';
+$lang['comments'] = 'Komentari';
+$lang['comments_add'] = 'Dodaj komentar';
+$lang['created after %s (%s)'] = 'izrađen nakon %s (%s)';
+$lang['created before %s (%s)'] = 'izrađen prije %s (%s)';
+$lang['created between %s (%s) and %s (%s)'] = 'izrađen između %s (%s) i %s (%s)';
+$lang['created on %s'] = 'izrađen na %s';
+$lang['customize'] = 'Prilagodi';
+$lang['customize_page_title'] = 'Prilagodba Vaše Galerije ';
+$lang['day'][0] = 'Nedjelja';
+$lang['day'][1] = 'Ponedjeljak';
+$lang['day'][2] = 'Utorak';
+$lang['day'][3] = 'Srijeda';
+$lang['day'][4] = 'Četvrtak';
+$lang['day'][5] = 'Petak';
+$lang['day'][6] = 'Subota';
+$lang['default_sort'] = 'Pretpostavljeno';
+$lang['del_favorites_hint'] = 'uklonite ovu sliku iz omiljenih';
+$lang['delete'] = 'Ukloni';
+$lang['descending'] = 'silazno';
+$lang['download'] = 'preuzmi';
+$lang['download_hint'] = 'preuzmi ovaj zapis';
+$lang['edit'] = 'uredi';
+$lang['err_date'] = 'krivi nadnevak';
+$lang['excluded'] = 'isključeno';
+$lang['favorite_cat'] = 'Moji omiljeni';
+$lang['favorite_cat_hint'] = 'prikaz mojih omiljenih slika';
+$lang['favorites'] = 'Omiljeni';
+$lang['first_page'] = 'Prvi';
+$lang['gallery_locked_message'] = 'Galerija je zaključana zbog održavanja. Molimo, navratite kasnije.';
+$lang['generation_time'] = 'Stranica izrađena u ';
+$lang['guest'] = 'gost';
+$lang['hello'] = 'Pozdrav';
+$lang['hint_admin'] = 'dostupno samo upraviteljima';
+$lang['hint_category'] = 'prikazuje slike u korijenu skupine';
+$lang['hint_comments'] = 'Pregled zadnjih korisničkih komentara';
+$lang['hint_customize'] = 'prilagodite izgled vaše galerije';
+$lang['hint_search'] = 'pretraži';
+$lang['home'] = 'Naslovnica';
+$lang['identification'] = 'Prijavnica';
+$lang['images_available_cpl'] = 'u ovoj skupini';
+$lang['images_available_cat'] = 'u %d podskupini';
+$lang['images_available_cats'] = 'u %d podskupinama';
+$lang['included'] = 'uključeno';
+$lang['invalid_pwd'] = 'Nevaljana zaporka!';
+$lang['language']='Jezik';
+$lang['last %d days'] = 'zadnjih %d dana';
+$lang['last_page'] = 'Zadnji';
+$lang['logout'] = 'Odjava';
+$lang['mail_address'] = 'E-mail adresa';
+$lang['mandatory'] = 'obvezno';
+$lang['maxheight'] = 'Najveća dozvoljena visina slika';
+$lang['maxheight_error'] = 'Najveća visina mora biti broj veći od 50';
+$lang['maxwidth'] = 'Najveća dozvoljena širina slika';
+$lang['maxwidth_error'] = 'Najveća širina mora biti broj veći od 50';
+$lang['mode_created_hint'] = 'prikaz kalendara po nadnevku izrade';
+$lang['mode_flat_hint'] = 'prikaz svih stavki u svim podskupinama';
+$lang['mode_normal_hint'] = 'povratak u uobičajeni način pregleda';
+$lang['mode_posted_hint'] = 'prikaz kalendara po nadnevku objave';
+$lang['month'][10] = 'Listopad';
+$lang['month'][11] = 'Studeni';
+$lang['month'][12] = 'Prosinac';
+$lang['month'][1] = 'Siječanj';
+$lang['month'][2] = 'Veljača';
+$lang['month'][3] = 'Ožujak';
+$lang['month'][4] = 'Travanj';
+$lang['month'][5] = 'Svibanj';
+$lang['month'][6] = 'Lipanj';
+$lang['month'][7] = 'Srpanj';
+$lang['month'][8] = 'Kolovoz';
+$lang['month'][9] = 'Rujan';
+$lang['most_visited_cat'] = 'Najposjećenije';
+$lang['most_visited_cat_hint'] = 'prikaz najposjećenijih slika';
+$lang['nb_image_line_error'] = 'broj slika po redu mora biti cjelobrojna vrijednost';
+$lang['nb_image_per_row'] = 'Broj slika po redu';
+$lang['nb_line_page_error'] = 'Broj redova po stranici mora biti cjelobrojna vrijednost';
+$lang['nb_row_per_page'] = 'Broj redova po stranici';
+$lang['nbm_unknown_identifier'] = 'Nepoznata oznaka';
+$lang['new_password'] = 'Nova zaporka';
+$lang['new_rate'] = 'Ocjeni ovu sliku';
+$lang['next_page'] = 'Slijedeći';
+$lang['no_category'] = 'Naslovnica';
+$lang['no_rate'] = 'bez ocjene';
+$lang['note_filter_day'] = 'Stavke objavljene u zadnjem %d danu.';
+$lang['note_filter_days'] = 'Stavke objavljene između zadnjih %d dana.';
+$lang['password updated'] = 'zaporka obnovljena';
+$lang['periods_error'] = 'Nedavno razdoblje mora biti pozitivna cjelobrojna vrijednost';
+/* DEPRECATED USED IN comments.php FOR image_id ? */ $lang['picture'] = 'slika';
+$lang['picture_high'] = 'Klikni na sliku za pregled u visokoj razlučljivosti';
+$lang['picture_show_metadata'] = 'Prikaži meta podatke zapisa';
+$lang['powered_by'] = 'Osnaženo sa';
+$lang['preferences'] = 'Postavke';
+$lang['previous_page'] = 'Prethodni';
+$lang['random_cat'] = 'Slike slučajnog odabira';
+$lang['random_cat_hint'] = 'prikaz slika slučajnim odabirom';
+$lang['recent_cats_cat'] = 'Nedavne skupine';
+$lang['recent_cats_cat_hint'] = 'prikaz nedavno obnovljenih skupina';
+$lang['recent_period'] = 'Nedavno razdoblje';
+$lang['recent_pics_cat'] = 'Nedavne slike';
+$lang['recent_pics_cat_hint'] = 'prikaz najnovijih slika';
+$lang['redirect_msg'] = 'Preusmjeravanje...';
+$lang['reg_err_login1'] = 'Molimo, prijavite se';
+$lang['reg_err_login2'] = 'prijava ne smije završavati razmakom';
+$lang['reg_err_login3'] = 'prijava ne smije počinjati razmakom';
+$lang['reg_err_login5'] = 'ovo korisničko ime se već koristi';
+$lang['reg_err_mail_address'] = 'e-mail adresa mora biti oblika xxx@yyy.eee (npr : pasko@stranica.org)';
+$lang['reg_err_pass'] = 'molimo unesite zaporku ponovo';
+$lang['remember_me'] = 'Samoprijava';
+$lang['remove this tag'] = 'ukloni  ovaj tag iz popisa';
+$lang['representative'] = 'predstavnik';
+$lang['return to homepage'] = 'povratak na naslovnicu';
+$lang['search_author'] = 'Pretraživanje po Autoru';
+$lang['search_categories'] = 'Pretraživanje u Skupinama';
+$lang['search_date'] = 'Pretraživanje po Nadnevku';
+$lang['search_date_from'] = 'Nadnevak';
+$lang['search_date_to'] = 'Krajnji Nadnevak';
+$lang['search_date_type'] = 'Vrsta nadnevka';
+$lang['search_keywords'] = 'Pretraživanje po riječima';
+$lang['search_mode_and'] = 'Pretraživanje po svim uvjetima ';
+$lang['search_mode_or'] = 'Pretraživanje po bilo kojem uvjetu';
+$lang['search_one_clause_at_least'] = 'Prazni upit. Nije uneseno ni jedno obilježje.';
+$lang['search_options'] = 'Mogućnosti Pretraživanja';
+$lang['search_result'] = 'Ishodi pretraživanja';
+$lang['search_subcats_included'] = 'Pretraga u podskupinama';
+$lang['search_title'] = 'Pretraživanje';
+$lang['searched words : %s'] = 'tražene riječi : %s';
+$lang['send_mail'] = 'Kontakt';
+$lang['set as category representative'] = 'postavi za predstavnika skupine';
+$lang['show_nb_comments'] = 'Prikaži broj komentara';
+$lang['show_nb_hits'] = 'Prikaži broj posjeta';
+$lang['slideshow'] = 'klizni prikaz';
+$lang['slideshow_stop'] = 'zaustavi klizni prikaz';
+$lang['special_categories'] = 'Posebnosti';
+$lang['sql_queries_in'] = 'SQL upita u ';
+$lang['start_filter_hint'] = 'prikaz samo nedavno objavljenih slika';
+$lang['stop_filter_hint'] = 'povratak u prikaz svih slika';
+$lang['the beginning'] = 'početak';
+$lang['theme'] = 'tema sučelja';
+$lang['thumbnails'] = 'Povezne sličice';
+$lang['title_menu'] = 'Izbornik';
+$lang['title_send_mail'] = 'Komentar na vašem web mjestu';
+$lang['today'] = 'danas';
+$lang['update_rate'] = 'Obnovite svoju ocjenu';
+$lang['update_wrong_dirname'] = 'krivi naziv zapisa';
+$lang['upload_advise_filesize'] = 'veličina slikovnog zapisa ne smije prijeći : ';
+$lang['upload_advise_filetype'] = 'slika mora biti oblika jpg, gif ili png';
+$lang['upload_advise_height'] = 'visina slike ne smije prijeći : ';
+$lang['upload_advise_thumbnail'] = 'Izborno, ali preporučljivo : codaberite poveznu sličicu za vezu na ';
+$lang['upload_advise_width'] = 'Širina slike ne smije prijeći : ';
+$lang['upload_author'] = 'Autor';
+$lang['upload_cannot_upload'] = 'ne mogu prebaciti sliku na poslužitelj';
+$lang['upload_err_username'] = 'mora se upisati korisničko ime';
+$lang['upload_file_exists'] = 'Naziv slike već postoji';
+$lang['upload_filenotfound'] = 'Morate odabrati oblik zapisa za sliku';
+$lang['upload_forbidden'] = 'Ne možete prebacivati slike u ovu skupinu';
+$lang['upload_name'] = 'Naziv slike';
+$lang['upload_picture'] = 'Prebaci sliku';
+$lang['upload_successful'] = 'Slika uspješno prebačena, upravitelj će ovjeriti prebačaj uskoro';
+$lang['upload_title'] = 'Prebačaj slika';
+$lang['useful when password forgotten'] = 'korisno kada se zaboravi zaporka';
+$lang['qsearch'] = 'Brzo pretraživanje';
+$lang['Connected user: %s'] = 'Spojeni korisnik: %s';
+$lang['IP: %s'] = 'IP: %s';
+$lang['Browser: %s'] = 'Preglednik: %s';
+$lang['Author: %s'] = 'Autor: %s';
+$lang['Comment: %s'] = 'Komentar: %s';
+$lang['Delete: %s'] = 'Izbriši: %s';
+$lang['Validate: %s'] = 'Ovjeri: %s';
+$lang['Comment by %s'] = 'Komentirao-la %s';
+$lang['User: %s'] = 'Korisnik: %s';
+$lang['Email: %s'] = 'E-mail: %s';
+$lang['Admin: %s'] = 'Upravitelj: %s';
+$lang['Registration of %s'] = 'Upis od %s';
+$lang['Category: %s'] = 'Skupina: %s';
+$lang['Picture name: %s'] = 'Naziv slike: %s';
+$lang['Creation date: %s'] = 'Nadnevak izrade: %s';
+$lang['Waiting page: %s'] = 'Stranica počeka: %s';
+$lang['Picture uploaded by %s'] = 'Sliku prebacio %s';
+// --------- Starting below: New or revised $lang ---- from version 1.7.1
+$lang['guest_must_be_guest'] = 'Loš status za korisnika "guest", koristi se pretpostavljeni status. Molimo obavjestite webmaster-a.';
+// --------- Starting below: New or revised $lang ---- from Butterfly (2.0)
+$lang['Administrator, webmaster and special user cannot use this method'] = 'Upravitelj, webmaster i posebni korisnik ne mogu koristiti ovu metodu';
+$lang['reg_err_mail_address_dbl'] = 'korisnik već koristi ovu e-mail adresu';
+$lang['Category results for'] = 'Ishodi skupine za ';
+$lang['Tag results for'] = 'Ishodi tagova za';
+$lang['from %s to %s'] = 'od %s do %s';
+$lang['start_play'] = 'Pokreni klizni prikaz';
+$lang['stop_play'] = 'Zaustavi klizni prikaz';
+$lang['start_repeat'] = 'Ponovi klizni prikaz';
+$lang['stop_repeat'] = 'Ne ponavljaj klizni prikaz';
+$lang['inc_period'] = 'Smanji brzinu diaporama-e';
+$lang['dec_period'] = 'Povećaj brzinu diaporama-e';
+$lang['Submit'] = 'Pošalji';
+$lang['Yes'] = 'Da';
+$lang['No'] = 'Ne';
+$lang['%d element']='%d slika';
+$lang['%d elements']='%d slike';
+$lang['%d element are also linked to current tags'] = '%d slika također povezana sa trenutnim tagovima';
+$lang['%d elements are also linked to current tags'] = '%d slike također povezana sa trenutnim tagovima';
+$lang['See elements linked to this tag only'] = 'Pregledaj slike povezane samo sa ovim tag-om';
+$lang['elements posted during the last %d days'] = 'slike objavljene tijekon zadnjih %d dana';
+$lang['Choose an image'] = 'Odaberite sliku';
+$lang['Piwigo Help'] = 'Piwigo Pomoć';
+$lang['Rank'] = 'Redoslijed';
+$lang['group by letters'] = 'složeno po slovima';
+$lang['letters'] = 'slova';
+$lang['show tag cloud'] = 'prikaži tag oblak';
+$lang['cloud'] = 'oblak';
+?>
Index: /tags/2.0.2/language/hr_HR/help.html
===================================================================
--- /tags/2.0.2/language/hr_HR/help.html	(revision 3278)
+++ /tags/2.0.2/language/hr_HR/help.html	(revision 3278)
@@ -0,0 +1,310 @@
+<div class="instructions">
+<h2>Help</h2>
+
+<div id="instructionPLoader" class="instructionBlock">
+  <div
+    id="pLoader_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('pLoader_header', 'pLoader_content')"
+  ><span>
+    Add photos, the pLoader way
+  </span></div>
+  <div
+    id="pLoader_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+    <p><a href="http://piwigo.org/ext/extension_view.php?eid=270">pLoader for Windows</a> or <a href="http://piwigo.org/ext/extension_view.php?eid=269">pLoader for Linux</a> : description, download and details about new revisions.</p>
+    <ol>
+      <li>Create a directory "upload" next to directory "galleries" in your Piwigo installation, with write access.</li>
+      <li>Install pLoader on your computer, start it and fill the connection settings : your gallery URL, your username and password.</li>
+      <li>Drag'n drop photos from your directory browser into pLoader photo selection.</li>
+      <li>Create a category and select it.</li>
+      <li>Select some photos.</li>
+      <li>Click on the green arrow to transfer photos in your gallery</li>
+    </ol>
+Congratulations! You have successfuly created the first category of your photo gallery.
+  </div> <!-- pLoader_content -->
+</div> <!-- instructionPLoader -->
+
+<div id="instructionFTP" class="instructionBlock">
+  <div
+    id="FTP_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('FTP_header', 'FTP_content')"
+  ><span>
+    Add photos, the FTP way
+  </span></div>
+  <div
+    id="FTP_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+
+<h3>Quick Start</h3>
+
+<ol>
+  <li>Create a directory on your computer.</li>  
+
+  <li>Copy some photos inside this directory, resize them for web display. <em>Warning</em>: the name of directories and files must contain only letters, figures, "-", "_" or ".". No blank space, no accentuated characters.</li>
+
+  <li>With a FTP client, copy your directory in the "galleries" directory of your Piwigo installation.</li>
+
+  <li>Logon your gallery and go to <span class="pwgScreen">Administration &raquo; Pictures &raquo; Thumbnails</span> to create missing thumbnails.</li>
+
+  <li>Go to <span class="pwgScreen">Administration</span> and click on the big Synchronization button.</li>
+</ol>
+
+Congratulations! You have successfuly created the first category of your photo gallery.
+
+<h3>Directories and files organization</h3>
+<ul>
+
+  <li>
+
+    <p>Category directories are in the Piwigo directory
+    "galleries". Here follows the directory tree of a very small gallery (but
+    using many features) :</p>
+
+    <pre>
+.
+|-- admin
+|-- doc
+|-- galleries
+|   |-- category-1
+|   |   |-- category-1.1
+|   |   |   |-- category-1.1.1
+|   |   |   |   |-- category-1.1.1.1
+|   |   |   |   |   |-- pwg_high
+|   |   |   |   |   |   +-- wedding.jpg
+|   |   |   |   |   |-- thumbnail
+|   |   |   |   |   |   +-- TN-wedding.jpg
+|   |   |   |   |   +-- wedding.jpg
+|   |   |   |   +-- category-1.1.1.2
+|   |   |   +-- category-1.1.2
+|   |   |-- category-1.2
+|   |   |   |-- pookie.jpg
+|   |   |   +-- thumbnail
+|   |   |       +-- TN-pookie.jpg
+|   |   +-- category-1.3
+|   +-- category-2
+|       |-- piglet.gif
+|       |-- pwg_representative
+|       |   +-- video.jpg
+|       |-- thumbnail
+|       |   +-- TN-piglet.jpg
+|       +-- video.avi
+|-- include
+|-- install
+|-- language
+|-- template
++-- tool</pre>
+
+  </li>
+  
+  <li>Each directory under "galleries" produces a category. There is no limit on deepness.</li>
+
+  <li>Basically, an element is represented by a file. A file can be a
+  Piwigo element if its extenstion is among <code>file_ext</code>
+  configuration parameter possibilities (see <span
+  class="filename">include/config_default.inc.php</span> file). A file can
+  be a picture if its extension is among <code>picture_ext</code>
+  configuration parameter possibilities.</li>
+
+  <li>Picture elements must have an associated thumbnail (see section below
+  about thumbnails)</li>
+
+  <li>Picture elements can have a high quality file associated. As for
+  wedding.jpg in the example above. No prefix on the high quality picture.</li>
+
+  <li>Non picture elements (video, sounds, file texts, what you want...) are
+  by default represented by an icon corresponding to the filename
+  extension. Optionaly, you can associate a thumbnail and a representative
+  file (see video.avi in the example above).</li>
+
+  <li><em>Warning</em>: the name of directories and files must contain only letters, figures, "-", "_" or ".". No blank space, no accentuated characters.</li>
+
+  <li>Once files, thumbnails and representatives are correctly placed in the
+  directories, go to : <span class="pwgScreen">Administration &raquo; Categories &raquo;
+  Synchronize</span></li>
+
+</ul>
+
+<h3>Thumbnails</h3>
+<ul>
+
+  <li>Each photo must have its thumbnail.</li>
+
+  <li>Thumbnails are stored in the sub-directory "thumbnail" of the category
+  directory. The thumbnail has the same filename as the corresponding photo, with <em>TN-</em> as prefix.</li>
+
+  <li><em>Advise</em>: use an external module for thumbnails creation.</li>
+
+  <li>Even if it is not recommended (image quality, web server resource load), you can use <span
+  class="pwgScreen">Administration &raquo; Pictures &raquo; Thumbnails</span> page to create thumbnails.</li>
+
+  <li>Give write access on all category directories.</li>
+
+</ul>
+
+  </div> <!-- FTP_content -->
+</div> <!-- instructionFTP -->
+
+<div id="instructionPermissions" class="instructionBlock">
+  <div
+    id="permissions_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('permissions_header', 'permissions_content')"
+  ><span>
+    Permissions
+  </span></div>
+  <div
+    id="permissions_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+<ul>
+
+  <li>You can forbid access to categories. Switch the category access type to "private" if you want to manage permissions.</li>
+
+  <li>You can set a category to private by editing a single category (<span
+  class="pwgScreen">Administration &raquo; Categories &raquo; Manage &raquo; edit</span>) or by
+  setting options to your whole category tree (<span
+  class="pwgScreen">Administration &raquo; Categories &raquo; Properties &raquo; Public / Private</span>).</li>
+
+  <li>
+
+    <p>Once the category is private, you can manage permissions for groups
+    and users with 3 screens:</p>
+
+    <ul>
+
+      <li><span class="pwgScreen">Administration &raquo; Identification &raquo; Users &raquo;
+      permissions action</span> (one link per user)</li>
+
+      <li><span class="pwgScreen">Administration &raquo; Identification &raquo; Groups &raquo;
+      permissions action</span> (one link per group)</li>
+
+      <li><span class="pwgScreen">Administration &raquo; Categories &raquo; Manage &raquo; edit
+      category permissions action</span> (one link per category)</li>
+
+    </ul>
+
+  </li>
+
+</ul>
+  </div> <!-- permissions_content --> 
+</div> <!-- instructionPermissions -->
+
+<div id="instructionGroups" class="instructionBlock">
+  <div
+    id="groups_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('groups_header', 'groups_content')"
+  ><span>
+    Groups
+  </span></div>
+  <div
+    id="groups_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+<ul>
+
+  <li>Groups is a convenient way to set permissions for a list of users.</li>
+
+  <li>Create groups in <span class="pwgScreen">Administration &raquo;
+  Identification &raquo; Groups</span> and associate users to this group in <span
+  class="pwgScreen">Administration &raquo; Identication &raquo; Users</span>.</li>
+
+  <li>A user can belong to several groups. Authorization is stronger
+  than forbiddance : if user "jack" belongs to groups "family" and
+  "friends", and that only group "family" can see category "Christmas 2003" category then
+  "jack" will be able to see "Christmas 2003".</li>
+
+</ul>
+  </div> <!-- groups_content --> 
+</div> <!-- instructionGroups -->
+
+<div id="instructionUpload" class="instructionBlock">
+  <div
+    id="upload_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('upload_header', 'upload_content')"
+  ><span>
+    Upload by users
+  </span></div>
+  <div
+    id="upload_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+<p>Users can upload their photos too.</p>
+
+<ol>
+
+  <li>Authorize upload on any physical categories (<span
+  class="pwgScreen">Administration &raquo; Categories &raquo; Manage &raquo; edit</span> or <span
+  class="pwgScreen">Administration &raquo; Categories &raquo; Properties &raquo; Upload</span>). Virtual categories can't receive any upload.</li>
+
+  <li>Give write access on corresponding directories.</li>
+
+</ol>
+
+<p>Photos uploaded by users are not directly visible on the website. An administrator
+must validate uploaded photos in <span class="pwgScreen">Administration &raquo; Pictures &raquo; Waiting</span>.</p>
+  </div> <!-- upload_content --> 
+</div> <!-- instructionUpload -->
+
+<div id="instructionCategoryLinks" class="instructionBlock">
+  <div
+    id="categoryLinks_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('categoryLinks_header', 'categoryLinks_content')"
+  ><span>
+    Links between photos and categories, virtual categories
+  </span></div>
+  <div
+    id="categoryLinks_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+<ul>
+
+  <li>Photos are displayed in the category corresponding to the file directory.</li>
+
+  <li>You can also display a picture in several categories, without duplicating the file on your web server. Associate the photo to any category from the photo editing screen (that any administrator can reach from the photo page on the gallery side).</li>
+
+  <li>Virtual categories are based on this concept: they have no corresponding directory. Create virtual categories from <span class="pwgScreen">Administration &raquo; Categories &raquo; Manage</span>.</li>
+
+</ul>
+  </div> <!-- categoryLinks_content --> 
+</div> <!-- instructionCategoryLinks -->
+
+<div id="instructionMisc" class="instructionBlock">
+  <div
+    id="misc_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('misc_header', 'misc_content')"
+  ><span>
+    Miscellanous informations
+  </span></div>
+  <div
+    id="misc_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+<ul>
+
+  <li>As soon as you created your gallery, modify default display properties
+  in <span class="pwgScreen">Administration &raquo; Configuration &raquo;
+  Default</span>. Every new registered user will use these default configuration settings.</li>
+
+  <li>If you have any question, Piwigo community will welcome you on <a
+  href="http://piwigo.org/forum">its forum</a>.</li>
+
+</ul>
+  </div> <!-- misc_content --> 
+</div> <!-- instructionMisc -->
+
+</div>
Index: /tags/2.0.2/language/hr_HR/help/advanced_feature.html
===================================================================
--- /tags/2.0.2/language/hr_HR/help/advanced_feature.html	(revision 3278)
+++ /tags/2.0.2/language/hr_HR/help/advanced_feature.html	(revision 3278)
@@ -0,0 +1,16 @@
+<h2>Napredne mogućnosti</h2>
+
+<p>Popis posebnih funkcionalnosti za napredne PWG upravitelje:</p>
+
+<ul>
+
+  <li>
+    <strong>Nepovezane stavke:</strong>
+    Prikaz slika koje nisu povezane ni s jednom nestvarnom skupinom.
+  </li>
+  <li>
+    <strong>Slike istog naziva u više od jednoj stvarnoj skupini:</strong>
+    Prikaz slika istog naziva koje se nalaze u više skupina.
+  </li>
+
+</ul>
Index: /tags/2.0.2/language/hr_HR/help/cat_modify.html
===================================================================
--- /tags/2.0.2/language/hr_HR/help/cat_modify.html	(revision 3278)
+++ /tags/2.0.2/language/hr_HR/help/cat_modify.html	(revision 3278)
@@ -0,0 +1,141 @@
+<h2>Edit a category</h2>
+
+<h3>Informations</h3>
+
+<ul>
+
+  <li><strong>name</strong>: rename the category (a virtual rename in case 
+  of physical category).</li>
+
+  <li><strong>description</strong>: give a general idea of the content,
+  this text will be display under the thumbnail page.</li>
+
+</ul>
+
+<h3>Move</h3>
+
+<p>If the category is virtual, you can move it. Moving a category means
+changing its parent category.</p>
+
+<h3>Options</h3>
+
+<ul>
+
+  <li><strong>Access type</strong>: Permission management. If you make a
+  category private, all its child categories becomes private. If you make a
+  category public, all its parent categories becomes public.</li>
+
+  <li><strong>Lock</strong>: The category and its sub-categories will
+  temporary been disabled for maintenance.</li>
+
+  <li><strong>Comments</strong>: Authorize users to comment elements of this
+  category.</li>
+
+  <li><strong>Authorize upload</strong>: Authorize users to upload
+  files. This option is available only if category is physical (not
+  virtual).</li>
+
+</ul>
+
+<p>You can also manage these options with "Properties"
+management screen (screens <span class="pwgScreen">Upload</span>, <span
+class="pwgScreen">Comments</span>, <span class="pwgScreen">Lock</span>,
+<span class="pwgScreen">Public/Private</span>, <span
+class="pwgScreen">Representative</span> available from <span
+class="pwgScreen">Administration, Categories, Properties</span>).</p>
+
+<h3>Sort order</h3>
+
+<p>Choose if the default sort order will be used.</p>
+
+<p>Indicate if this sort order will be applied to subcategories.</p>
+
+<p>Select specific sort by columns to use with this category.</p>
+<ul>
+<li><strong>Creation date</strong>: Picture creation date</li>
+<li><strong>Post date</strong>: Synchronization date</li>
+<li><strong>Average rate (*)</strong>: Average rate could be changed by the visitor</li>
+<li><strong>Most visited (*)</strong>: The current visit change the most visited order</li>
+<li><strong>File name</strong>: Given name in informations field</li>
+<li><strong>Id</strong>: Internal Id (recent categories have an higher id than previous ones.</li>
+
+</ul>
+<p><strong>(*)</strong>Take care and test it for your self since it can give unpredictable results.</p>
+
+
+<h3>Representant</h3>
+
+<p>The representant of the category is the thumbnail displayed to represent
+the category on main page (<span class="pwgScreen">category.php</span>) when
+a category contains only sub-categories (just as the root category).</p>
+
+<p>There are 4 ways to set the representative picture of a category :</p>
+
+<ul>
+
+  <li><span class="pwgScreen">Picture page</span>: in the action buttons bar,
+  one of them let you set the displayed picture as representative for the
+  displayed category. This button is available only for administrators.</li>
+
+  <li><span class="pwgScreen">Modify informations about a picture</span> in
+  administration. This screen can be reach from <span
+  class="pwgScreen">picture.php</span> or <span class="pwgScreen">Batch
+  management</span> in <em>unit mode</em>. See the help of this screen for
+  details.</li>
+
+  <li><span class="pwgScreen">Administration, Categories, Properties,
+  Representative</span>. See the help of this screen for details.</li>
+
+  <li><span class="pwgScreen">Edit a category</span> (this screen).</li>
+
+</ul>
+
+<p>The representation depends on configuration parameter
+<code>allow_random_representative</code> (see <span
+class="filename">include/config_default.inc.php</span>).</p>
+
+<p>In default mode (<code>allow_random_representative</code> set to false)
+each category containing at least one element is represented by a fixed
+element. Once set (at category creation), the representative changes only
+when an administrator ask for it. If the representant is not appropriate,
+you can ask to <strong>Find a new representant by random</strong>.</p>
+
+<p>If configuration parameter <code>allow_random_representative</code> is
+set to true, a category containing elements can have no fixed
+representant. Just use <strong>Delete representant</strong> button.</p>
+
+<p>If the category contains no element (but only sub-categories) it can be
+represented by any element thanks to screen <span class="pwgScreen">Modify
+informations about a picture</span>. The only option on the current screen
+is to <strong>Delete representant</strong> button, after using this button,
+no representant option to set anymore.</p>
+
+<h3>Link all category elements to a new category</h3>
+
+<ul>
+
+<li><strong>Virtual category name</strong>: New category name to be created, 
+all pictures of the current category will be linked to the new one.</li>
+
+<li><strong>Parent category</strong>: Where the new category will be, 
+leave empty to create it from home.</li>
+
+</ul>
+
+<h3>Link all category elements to some existing categories</h3>
+
+<ul>
+
+<li><strong>Categories</strong>: Choose the destination category.</li>
+
+</ul>
+
+<h3>Send an information email to group members</h3>
+
+<ul>
+
+<li><strong>Group</strong>: addressees group</li>
+
+<li><strong>Mail content</strong>: Free text to be sent to them.</li>
+
+</ul>  
Index: /tags/2.0.2/language/hr_HR/help/cat_move.html
===================================================================
--- /tags/2.0.2/language/hr_HR/help/cat_move.html	(revision 3278)
+++ /tags/2.0.2/language/hr_HR/help/cat_move.html	(revision 3278)
@@ -0,0 +1,14 @@
+<h2>Premještanje nestvarnih skupina</h2>
+
+<p>Samo nestvarne skupine mogu imati novu nadređenu skupinu.</p>
+
+<h3>Nestvarne skupine za premještaj</h3>
+
+<p>Odaberite bilo koje nestvarne skupine koje želite premjestiti. 
+Ako je popis prazan, to znači da niste izradili ni jednu.</p>
+
+<h3>Nova nadređena skupina</h3>
+
+<p>Odaberite novu nadređenu skupinu (nestvarnu ili stvarnu). 
+Ukoliko ne odaberete, odabrane nestvarne skupine će se prebaciti u korijensku mapu.
+Ne možete premještati skupinu u  nju samu ili njoj podređenu skupinu.</p>
Index: /tags/2.0.2/language/hr_HR/help/cat_options.html
===================================================================
--- /tags/2.0.2/language/hr_HR/help/cat_options.html	(revision 3278)
+++ /tags/2.0.2/language/hr_HR/help/cat_options.html	(revision 3278)
@@ -0,0 +1,31 @@
+<h2>Mogućnosti skupine</h2>
+
+<p>Ovaj prozor omogućava upravniku upravljanje mogućnostima skupina za više njih odjednom.</p>
+
+<dl>
+
+  <dt>Prebačaj</dt>
+  <dd>Postavi skupine otvorene za prebačaj slika posjetiteljima galerije. Prikazane su samo stvarne i mjesne skupine.</dd>
+
+  <dt>Komentari</dt>
+  <dd>Ovlasti korisnicima za dodavanje komentara u odabranim skupinama.
+Odabire skupine koje su otvorene za komentare. 
+Slika se može komentirati ako pripada najmanje jednoj skupini sa odobrenim komentiranjem.</dd>
+
+  <dt>Zaključaj</dt>
+  <dd>Odabrane skupine će privremeno biti nedostupne zbog održavanja. Ako
+  zaključate skupinu, sve njoj podređene skupine se također zaključavaju. Ako otključavate
+  skupinu, sve njoj nadređene skupine se također otključavaju.</dd>
+
+  <dt>Javno / osobno</dt>
+  <dd>Upravljanje ovlastima za odabrane skupine. Ako su odabrane skupine osobne
+   : trebate ovlastiti korisnike i/ili grupe za pristup. Ako postavite skupinu za osobnu, sve njoj nadređene skupine postaju osobne
+ . Ako postavite skupinu kao javnu, sve njene podređene skupine postaju javne.</dd>
+
+  <dt>Prestavnik</dt>
+  <dd>Ovom mogučnošću se može upravljati samo ako je postavljena stavka
+  <code>allow_random_representative</code> (vidi <span
+  class="filename">include/config_defaults.inc.php</span>) na 
+  <em>true</em>. Svaka skupina se može predstaviti slikom slučajnog odabira ili baš određenom slikom.</dd>
+
+</dl>
Index: /tags/2.0.2/language/hr_HR/help/cat_perm.html
===================================================================
--- /tags/2.0.2/language/hr_HR/help/cat_perm.html	(revision 3278)
+++ /tags/2.0.2/language/hr_HR/help/cat_perm.html	(revision 3278)
@@ -0,0 +1,14 @@
+<h2>Upravljanje dozvolama (ovlastima) za skupinu</h2>
+
+<p>Ovaj prozor je dostupan samo za osobne skupine. Ovdje možete odabrati korisnike
+i grupe koji imaju dozvolu pristupa.</p>
+
+<h3>Grupe</h3>
+
+<p>Možete dati ili uskratiti dozvole grupama za trenutnu skupinu. Promjenom 
+grupnih ovlasti vjerojatno će te promijeniti popis odobrenih korisnika zahvaljujući grupnoj pripadnosti.</p>
+
+<h3>Korisnici</h3>
+
+<p>Možete dati ili uskratiti dozvole pojedinim korisnicima. Korisnici dozvoljeni grupnom pripadnošću mogu biti posebno
+odobreni ili zabranjeni.</p>
Index: /tags/2.0.2/language/hr_HR/help/configuration.html
===================================================================
--- /tags/2.0.2/language/hr_HR/help/configuration.html	(revision 3278)
+++ /tags/2.0.2/language/hr_HR/help/configuration.html	(revision 3278)
@@ -0,0 +1,136 @@
+<h2>Configuration</h2>
+
+<p>This screen let the administrator do basic configuration. Indeed, this
+screen only shows simple configuration parameters that should be enough for
+the vast majority of administrators. If you want to see other numerous (and
+advanced) configuration parameters, read file <span
+class="filename">include/config_default.inc.php</span>.</p>
+
+<p>This screen is divided in several sections, regrouping configuration
+parameters by theme.</p>
+
+
+<h3>Main</h3>
+<ul>
+  <li><strong>Gallery title</strong>: used in RSS feed and notifications by
+email.</li>
+
+  <li><strong>Page banner</strong>: displayed on top of each public
+page.</li>
+
+  <li><strong>Gallery URL</strong>: used for the RSS feed.</li>
+
+  <li><strong>Lock gallery</strong>: Lock the entire gallery for
+  maintenance. Only administrator users will be able to reach the
+  gallery.</li>
+
+  <li><strong>Rating</strong>: Picture rating feature is enabled.</li>
+
+  <li><strong>Rating by guests</strong>: Even non registered users can rate images.</li>
+
+  <li><strong>Allow user registration</strong>: Registration is free for all.</li>
+
+  <li><strong>Mail address is obligatory for all users</strong>: Mail address will checked on registration or profile update except if the action is done on administration part.</li>
+
+  <li><strong>Email admins when a new user registers</strong>: Administrators will be received mail for each registration.</li>
+
+</ul>
+
+<h3>History</h3>
+
+  <p>Visits on pages <span
+  class="pwgScreen">category.php</span> and <span
+  class="pwgScreen">picture.php</span> will be saved in the
+  <code>history</code> table.</p>
+  
+  <p>Visits will be shown in <span
+  class="pwgScreen">Administration, Specials, History</span>.</p>
+
+<ul>
+  <li><strong>Save page visits by guests</strong>: page visits by guests will be saved.</li>
+
+  <li><strong>Save page visits by users</strong>: visits by registrered users will be saved.</li>
+
+  <li><strong>Save page visits by administrators</strong>: page visits by administrators will be saved.</li>
+
+</ul>
+
+<h3>Comments</h3>
+<ul>
+
+  <li><strong>Comments for all</strong>: Even guest not registered can post
+  comments.</li>
+
+  <li><strong>Number of comments per page</strong>.</li>
+
+  <li><strong>Validation</strong>: an administrator validate users posted
+  comments before they become visible on the site. User comments validation
+  takes place in screen <span class="pwgScreen">Administration, Pictures,
+  Comments</span>.</li>
+
+  <li><strong>Email admins when a valid comment is entered</strong>:
+Sends an email to the administrators when a user enters a comment and this comment is validated.</li>
+
+  <li><strong>Email admins when a comment requires validation</strong>:
+Sends an email to the administrators when a user enters a comment that requires validation by the admin.
+User comments validation takes place in the screen <span class="pwgScreen">Administration, Pictures, Comments</span>.</li>
+
+</ul>
+
+<!--TODO --><h3>Upload</h3>
+<ul>
+<!--TODO -->  <li><strong>Show upload link every time</strong>: If exists uploadeable categories, add link will be show for each categoy.</li>
+<!--TODO -->  <li><strong>User access level to upload</strong>: Allows to restrict upload by users</li>
+  <li><strong>Email adminis when a picture is uploaded</strong>: Administrators will be received mail for each picture uploaded by a user.</li>
+</ul>
+
+<h3>Default display</h3>
+
+<p>Here you can change display options used by default, when guest is not
+connected. Once connected, these options are overloaded by user own options
+(modifiable in <span class="pwgScreen">profile</span>).</p>
+
+<p>It is possible to change display options for all existing users, but the
+screen to consider is <span class="pwgScreen">Administration,
+Identification, Users</span>, where you can options for a selected list of
+users.</p>
+
+<ul>
+
+  <li><strong>Language</strong>: concerns only Piwigo
+  labels. Category names, picture names and all descriptions are not
+  localized.</li>
+
+  <li><strong>Number of images per row</strong></li>
+
+  <li><strong>Number of rows per page</strong></li>
+
+  <li><strong>Interface theme</strong></li>
+
+  <li><strong>Recent period</strong>: By days. Period within a picture is
+  shown as new. Must be superior to 1 day.</li>
+
+  <li><strong>Expand all categories</strong>: Expand all categories by
+  default in the menu? <em>Warning</em>: this option is resources consuming
+  and may generate a huge menu if your category tree is contains many
+  categories.</li>
+
+  <li><strong>Show number of comments</strong>: show the number of comments
+  for each picture on the thumbnails page. Resource consuming.</li>
+
+  <li><strong>Show hits count</strong>: display hits observed on picture
+  just under its thumbnail on the thumbnails page. 
+  Only when advanced configuration parameter is: <br />
+  $conf['show_nb_hits'] = true; <br />
+  Notice: it is false by default.</li>
+
+  <li><strong>Maximum width of the pictures</strong>: maximum displayed
+  width. If pictures are larger than this setting, they will be resized on
+  display. If you consider filling this option, you'd better consider
+  modifying the width of your pictures instead.</li>
+
+  <li><strong>Maximum height of the pictures</strong>: same remarks as for
+  previous setting.</li>
+
+</ul>
+
Index: /tags/2.0.2/language/hr_HR/help/extend_for_templates.html
===================================================================
--- /tags/2.0.2/language/hr_HR/help/extend_for_templates.html	(revision 3278)
+++ /tags/2.0.2/language/hr_HR/help/extend_for_templates.html	(revision 3278)
@@ -0,0 +1,100 @@
+<h2>Extend for templates configuration</h2>
+
+<h3>Goal</h3>
+<p>Define replacement conditions for each template from template-extension
+(template called "replacer").</p>
+
+<p>"original template" from ./template/yoga (or any other than yoga)
+ will be replaced by a "replacer" if the replacer is linked to this "original template"
+ (and optionally, when the requested URL contains an "optional URL keyword").</p>
+
+<p>"Optional URL keywords" are those you can find after the module name in URLs.</p>
+
+<p>Therefore "Optional URL keywords" can be an active "permalink" 
+(see permalinks in our documentation for further explanation).</p>
+
+<p>Read: `<a href="#warnings">Warning</a>` usage conditions.</p>
+
+<h3>What are template extensions?</h3>
+
+<p>This configuration tool is powerfull for beginners and advanced users.
+By FTP, in the template-extension folder, the Webmaster can duplicate a lot of
+ the distributed .tpl files ("original template") with a different name 
+ ("replacer").
+ 
+ "Original templates", current original supported templates are:</p>
+<ul>
+  <li><span class="filename">index.tpl</span></li>
+  <li><span class="filename">mainpage_categories.tpl</span> and/or <span class="filename">thumbnails.tpl</span></li>
+  <li><span class="filename">menubar.tpl</span></li>
+  <li><span class="filename">header.tpl</span> and/or <span class="filename">footer.tpl</span></li>
+  <li><span class="filename">picture_content.tpl</span> and/or <span class="filename">picture.tpl</span></li>
+  <!-- <li><span class="filename">slideshow.tpl</span></li> -->
+  <li><span class="filename">profile.tpl</span> and/or <span class="filename">profile_content.tpl</span></li>
+  <li><span class="filename">tags.tpl</span></li>
+  <li><span class="filename">upload.tpl</span></li>
+  <li><span class="filename">about.tpl</span></li>
+  <li><span class="filename">popuphelp.tpl</span></li>
+  <li><span class="filename">search.tpl</span> and/or <span class="filename">search_rules.tpl</span></li>
+  <li><span class="filename">nbm.tpl</span> and/or <span class="filename">notification.tpl</span></li>
+  <li><span class="filename">identification.tpl</span> and/or <span class="filename">register.tpl</span></li>
+  <li><span class="filename">redirect.tpl</span></li>
+</ul>
+
+<h3>Where can I find "original templates"?</h3>
+
+<p>Distributed original templates are in template/yoga/ 
+(don't edit them in place for upgrade perspectives). So with "original templates", 
+any webmaster can create his "replacers (customized templates)".</p>
+
+<h3>Where should I save "replacers"?</h3>
+
+<p><strong>Replacers (customized templates)</strong> must be placed in the 
+template-extension folder (or its subfolders).
+Replacers can have any filename with the .tpl extension. For example: <span
+class="filename">template-extension/my-extension/video.tpl</span>.</p>
+
+
+<h3>How can I activate my "replacers"?</h3>
+<p>An <strong>original template</strong> should be assigned to each
+ <strong>replacer (customized templates)</strong> to activate the related replacements.
+ This is the goal of "Extend for templates" in the Configuration Administration menu.</p>
+
+<p>If you select an <strong>optional URL keyword</strong> then replacements 
+will be operate only on pages with this keyword. For example: <span
+  class="pwgScreen">index.php?/<strong>most_visited</strong></span></p>
+  
+<p>Advanced users will use permalinks as <strong>optional URL keyword</strong>. </p>
+
+<p>If you select a <strong>Bound template</strong> then replacements will be operate only on this template.</p>
+
+<h3>How can I deactivate my "replacers"?</h3>
+<ul>
+<li>Unselect related "Original templates".</li>
+<li>By FTP delete of "replacers".</li>
+</ul>
+<a name="warnings"></a>
+<h3>Warnings</h3>
+<ul>
+
+  <li><strong>Original template</strong> must be the "original" template 
+  otherwise you could have unpredictable results!</li>
+
+  <li>On several <strong>replacers (customized templates)</strong> with the
+  same<strong>Original template</strong> and the same <strong>optional URL 
+  keyword</strong> only the last replacer is active.</li>
+
+  <li>Unselected <strong>optional URL keyword</strong> will active the replacer
+  on any template usage. As previous point, order can override previous
+  selected replacers.</li>
+
+  <li>Subfolders:
+Subfolders are ignored but they are usefull to change current order.<br />
+distributed-samples: for test purpose are distributed! 
+<strong>Don't edit them</strong> create your own ones.
+</li>
+
+  <li>On delete of a replacer the <strong>Original template</strong> is 
+  immediately reactivated.</li>
+
+</ul>
Index: /tags/2.0.2/language/hr_HR/help/group_list.html
===================================================================
--- /tags/2.0.2/language/hr_HR/help/group_list.html	(revision 3278)
+++ /tags/2.0.2/language/hr_HR/help/group_list.html	(revision 3278)
@@ -0,0 +1,22 @@
+<h2>Popis grupa</h2>
+
+<p>ovo je mjesto gdje možete upravljati postojećim grupama.</p>
+
+<h3>Dodaj grupu</h3>
+
+<p>Upravnik može dodavati grupe.</p>
+
+<h3>Popis grupa</h3>
+
+<p>Popis dozvoljava za svaku stavku da:</p>
+
+
+<ul>
+  <li>idi na popis članova</li>
+  <li>idi na ovlasti</li>
+  <li>izbriši grupu (zahtijeva odabir potvrdne kućice)</li>
+  <li>promijeni "default" tj. pretpostavljeno stanje(zahtijeva odabir potvrdne kućice)</li>
+</ul>
+
+<h3>Pretpostavljene grupe</h3>
+<p>Pretpostavljene grupe su grupe koje se same povezuju sa novim korisnikom.</p>
Index: /tags/2.0.2/language/hr_HR/help/history.html
===================================================================
--- /tags/2.0.2/language/hr_HR/help/history.html	(revision 3278)
+++ /tags/2.0.2/language/hr_HR/help/history.html	(revision 3278)
@@ -0,0 +1,45 @@
+<h2>History</h2>
+
+<p>These screens allows you to follow the historical navigation en Piwigo
+according to the options yo have chosen in - Administration - General - History index.</p>
+	
+<h3>Statistics</h3>
+<ul>
+  <p>If you have chosen to keep the pages visited (<span
+class="pwgScreen">index.php</span> and <span
+class="pwgScreen">picture.php</span>) in the table <code>history. </code>
+This index allow you to follow the pages visited.</p>
+	
+	<li><strong>Global statistics</strong> : you can visualize per year. </li>
+	
+	<li><strong>Yearly statistics</strong> : you can visualize per month in the year selected.</li>
+	
+	<li><strong>Monthly statistics</strong> : you can visualize per days in the month selected.</li>
+	
+	<li><strong>Dayly statistics</strong> : you can visualize per hours in the day selected.</li>
+	
+</ul>
+
+<h3>Search</h3>
+<ul>
+  <p>If you have chosen to keep the pages visited (<span
+class="pwgScreen">index.php</span> and <span
+class="pwgScreen">picture.php</span>) in the table <code>history. </code>
+This index allow to follow en details the pages visited on the site with 
+the help of different filters.</p>
+ 
+	<li><strong>Filter per date</strong> : chose interval of date you wisk
+	to observe the activity.</li>
+	
+	<li><strong>Filter per type of element</strong> : chose the type 
+	of element you wisk to observe the activity.</li>
+	
+	<li><strong>Filter per user</strong> : chose user you wisk to 
+	observe the activity.</li>
+	
+	<li><strong>Filter per name of the file</strong> : chose name of the file 
+	you	wisk to observe the activity.</li>
+	
+	<li><strong>Filter per identifying image</strong> : chose identifying image 
+	you wisk to observe the activity.</li>
+</ul>
Index: /tags/2.0.2/language/hr_HR/help/index.php
===================================================================
--- /tags/2.0.2/language/hr_HR/help/index.php	(revision 3278)
+++ /tags/2.0.2/language/hr_HR/help/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/language/hr_HR/help/maintenance.html
===================================================================
--- /tags/2.0.2/language/hr_HR/help/maintenance.html	(revision 3278)
+++ /tags/2.0.2/language/hr_HR/help/maintenance.html	(revision 3278)
@@ -0,0 +1,46 @@
+<h2>Maintenance</h2>
+
+<p>To optimize page generation time, Piwigo uses cached
+information. For example, instead of counting the number of pictures
+contained in each category at each page reload, this information is stored
+in the database. In theory, this information should always be correct, but
+sometimes an error can occur and cached information becomes wrong.</p>
+
+<p>Some informations become useless with time. Deleting this useless
+information from database make you save disk space.</p>
+
+<ul>
+
+  <li><strong>Update categories informations:</strong> For each category,
+  informations to update or control are the following : list of parent
+  categories, number of pictures, date of the last picture, position among
+  brother categories, position among all categories. This action also checks
+  the coherence of representative picture.</li>
+
+  <li><strong>Update images informations:</strong> For each picture,
+  informations to update are : full path to file, average
+  rate. <em>Warning</em>: do not get confuse with metadata informations
+  which can be synchronized from <span class="pwgScreen">Administration,
+  Categories, Synchronize</span> or by reaching the modification screen of a
+  single picture (through <span class="pwgScreen">Picture</span> for
+  example).</li>
+
+  <li><strong>Repair and optimize database:</strong>
+  For each table, re-odrer, repair and optimize operations are done.
+  </li>
+</ul>
+
+<ul>
+  <li><strong>Purge history detail:</strong> Delete all lines from
+  <code>history</code> table. Screen <span class="pwgScreen">Administration,
+  Specials, History</span> shows no informations anymore on past
+  history. <em>Warning</em>: all data will be lost and there is no way to
+  get informations back.</li>
+
+  <li><strong>Purge history summary:</strong> Delete all the summary information about visit history. This summary is calculated from the history detail.</li>
+
+  <li><strong>Purge sessions:</strong> Delete expired user sessions.</li>
+
+  <li><strong>Purge never used notification feeds</strong></li>
+
+</ul>
Index: /tags/2.0.2/language/hr_HR/help/notification_by_mail.html
===================================================================
--- /tags/2.0.2/language/hr_HR/help/notification_by_mail.html	(revision 3278)
+++ /tags/2.0.2/language/hr_HR/help/notification_by_mail.html	(revision 3278)
@@ -0,0 +1,15 @@
+<h2>Obavijesti e-mail porukama</h2>
+
+<p>Ovaj prozor omogućaa postavu i upravljanje e-mail obavijestima korisnicima o novostima u vašoj galeriji.</p>
+
+<p>Sastoji se od 3 kartice:</p>
+
+<h3>Parametri</h3>
+<p>Dostupno samo webmasterima, ova kartica postavlja parametre e-mail obavješćivanja.</p>
+
+<h3>Pretplata</h3>
+<p>Dostupno samo webmasterima, ova kartica upravlja pretplatom/prekidom pretplate korisnika na e-mail obavijesti.</p>
+
+<h3>Envoi</h3>
+<p>Dostupno samo webmasterima i upraviteljima, ova kartica omogućava slanje e-mail poruka za novosti.</p>
+
Index: /tags/2.0.2/language/hr_HR/help/permalinks.html
===================================================================
--- /tags/2.0.2/language/hr_HR/help/permalinks.html	(revision 3278)
+++ /tags/2.0.2/language/hr_HR/help/permalinks.html	(revision 3278)
@@ -0,0 +1,7 @@
+<h2>Stalne poveznice</h2>
+
+<p>Koriste se za ljepši prikaz URL-a skupine. Kada skupina ima određenu stalnu poveznicu, ID skupine nije više nužan u URL-u.</p>
+
+<p>Kada je stalna poveznica izbrisana, imate mogućnost pohraniti je u pismohrani poveznica, tako da vanjske poveznice na PWG stranice i dalje ispravno rade. U pismohrani stalnih poveznica možete vidjeti nadnevak kada je izbrisana, vrijeme posljednjeg korištenja i koliko puta.</p>
+
+<p>Zapamtite da stalna poveznica mora biti jedinstvena po skupini. Isto tako u pismohrani stalnih poveznica ne možete imati istu više puta.</p>
Index: /tags/2.0.2/language/hr_HR/help/search.html
===================================================================
--- /tags/2.0.2/language/hr_HR/help/search.html	(revision 3278)
+++ /tags/2.0.2/language/hr_HR/help/search.html	(revision 3278)
@@ -0,0 +1,21 @@
+<h2>Pretraživanje</h2>
+
+<p>Ova stranica omogućava pretragu slika u cijeloj galeriji.</p>
+
+<dl>
+
+  <dt>Pretraga po riječima</dt>
+  <dd>Pretažuje po upisanim riječima po svim obilježjima povezanim sa slikama prikazanim u galeriji. Koristite * kao zamijenu za djelomična poklapanja.</dd>
+
+  <dt>Pretraga po autoru</dt>
+  <dd>Koristite * kao zamijenu za djelomična poklapanja.</dd>
+
+  <dt>Pretaga po nadnevku</dt>
+  <dd>Odaberite nadnevak i/ili završni nadnevak za vašu pretragu. Ostavite nadnevak prazan 
+  za pretragu "prethodnih" upita. Godina mora biti upisana u zadnje polje u slijedećem obliku : 0000 (i.e. 2009)</dd>
+
+  <dt>Pretraga u skupinama</dt>
+  <dd>Odaberite skupinu ili skupine koje želite pretražiti. Za bržu pretragu sve podskupine
+  mogu biti pretraživane odabirom nadređene skupine i uključenjem mogućnosti pretrage podskupina ispod.</dd>
+
+</dl>
Index: /tags/2.0.2/language/hr_HR/help/site_manager.html
===================================================================
--- /tags/2.0.2/language/hr_HR/help/site_manager.html	(revision 3278)
+++ /tags/2.0.2/language/hr_HR/help/site_manager.html	(revision 3278)
@@ -0,0 +1,51 @@
+<h2>Remote sites</h2>
+
+<p>Piwigo offers the possibility to use several servers to store the
+images which will compose your gallery. It can be useful if your gallery is
+installed on one limited space and that you have a big quantity of images to
+be shown.</p>
+
+<ol>
+
+  <li>edit file <span class="filename">tools/create_listing_file.php</span>,
+  by modifying parameters section such as
+  <code>$conf['prefix_thumbnail']</code> or
+  <code>$conf['use_exif']</code>.</li>
+
+  <li>place file <span class="filename">tools/create_listing_file.php</span>
+  modified on your distant website, in the same directory than your category
+  directories (as the directory <span class="filename">galleries</span> of
+  this website) by ftp. For the example, let's say that you can access <span
+  class="filename">http://example.com/galleries/create_listing_file.php</span>.</li>
+
+  <li>go to <span class="pwgScreen">administration panel, Categories, Site
+  manager</span>. Ask to create a new site, for example <span
+  class="filename">http://example.com/galleries</span>.</li>
+
+  <li>a new remote site is registered. You can perform 4 actions :
+
+    <ol>
+
+      <li><strong>generate listing</strong> : launches a distant request to
+      generate a distant file listing</li>
+
+      <li><strong>synchronize</strong> : reads the distant <span
+      class="filename">listing.xml</span> file and synchronizes with
+      database informations.</li>
+
+      <li><strong>clean</strong> : removes distant <span
+      class="filename">listing.xml</span> file.</li>
+
+      <li><strong>delete</strong> : deletes the site (and all related
+      categories and elements) in the database.</li>
+
+    </ol>
+  </li>
+</ol>
+
+<!-- <p>You can do all this by hand by generating yourself the <span
+class="filename">listing.xml</span> file, moving it from your distant server
+to you local Piwigo root directory and opening the remote site
+management screen : Piwigo will propose you to use the found
+listing.xml file.</p>-->
+
Index: /tags/2.0.2/language/hr_HR/help/synchronize.html
===================================================================
--- /tags/2.0.2/language/hr_HR/help/synchronize.html	(revision 3278)
+++ /tags/2.0.2/language/hr_HR/help/synchronize.html	(revision 3278)
@@ -0,0 +1,11 @@
+<h2>Usklađivanje</h2>
+
+<p>Dvije su mogućnosti usklađivanja: mape/zapisi i meta podatci
+zapisa. mape/zapisi vrše usklađivanje stabla mapa sa skupinskim stablom u bazi podataka.
+Meta podatci usklađuju obavijesne stavke kao što su veličina zapisa, veličina slika u pikselima, EXIF ili IPTC
+podatke.</p>
+
+<p>Prvo usklađivanje mora biti ono od mape/zapisi vrste.</p>
+
+<p>Postupak usklađivanja može potrajati i malo duže (ovisno o opterećenju poslužitelja i količini
+stavaka za obradu) pa je omogućeno da se napreduje korak po korak: skupinu po skupinu.</p>
Index: /tags/2.0.2/language/hr_HR/help/thumbnail.html
===================================================================
--- /tags/2.0.2/language/hr_HR/help/thumbnail.html	(revision 3278)
+++ /tags/2.0.2/language/hr_HR/help/thumbnail.html	(revision 3278)
@@ -0,0 +1,27 @@
+<h2>Izrada poveznih sličica</h2>
+
+<p>Ovdje možete obaviti izradu nedostajućih poveznih sličica.</p>
+
+<dl>
+
+  <dt>GD inačica</dt>
+
+  <dd>GD je sustavna biblioteka za upravljanje obradom slika PHP-a. Odaberite inačicu
+  postavljenu na vašem poslužitelju. Ako krivo odaberete, dobiti ćete poruku greške,
+  vratite se jedan korak unatrag sa vašim web preglednikom i odaberite neku drugu inačicu.
+  Ako ni jedna inačica ne radi, znači da vaš poslužitelj ne podržava GD.</dd>
+
+  <dt>Širina i visina</dt>
+
+  <dd>Najveće vrijednosti koje povezna sličica može imati. Razmjerni odnos se održava.</dd>
+
+  <dt>Broj sličica za izradu</dt>
+
+  <dd>Nemojte pokušavati izradu prevelikog broja sličica u isto vrijeme. Zaista, izrada koristi mnogo CPU snage. Ako ste postavili vašu Piwigo galeriju na besplatnom poslužitelju, preveliko CPU opterećenje može ponekad dovesti do brisanja vašeg web mjesta.</dd>
+
+  <dt>Oblik zapisa</dt>
+
+  <dd>Samo je JPEG oblik zapisa podržan u izradi sličica. Povezne sličice
+  mogu biti izrađene samo za slike oblika PNG i JPEG.</dd>
+
+</dl>
Index: /tags/2.0.2/language/hr_HR/help/user_list.html
===================================================================
--- /tags/2.0.2/language/hr_HR/help/user_list.html	(revision 3278)
+++ /tags/2.0.2/language/hr_HR/help/user_list.html	(revision 3278)
@@ -0,0 +1,42 @@
+<h2>Popis korisnika</h2>
+
+<p>Ovo je mjesto gdje možete upravljati upisanim korisnicima. Jedino se ovlastima
+upravlja u nekim drugim prozorima.</p>
+
+<h3>Dodaj korisnika</h3>
+
+<p>Upravnik može ručno dodavati korisnike.</p>
+
+<h3>Popis korisnika</h3>
+
+<p>Popis može biti pročišćen na korisničko ime (koristite * kao zamjenu), grupu ili
+stanje. Popis može biti poredan po nadnevku upisa ili korisničkom imenu, uzlaznim
+ili silaznim redoslijedom.</p>
+
+<p>Ovaj prozor omogućava upravljenje nekolicinom korisnika odjednom na različitim postupcima
+:</p>
+
+<ul>
+
+  <li>brisanje korisnika (zahtijeva potvrdnu kućicu)</li>
+
+  <li>promjena stanja</li>
+
+  <li>uklučenje ili isključenje u-iz grupa</li>
+
+  <li>prilagodba svojstava prikaza</li>
+
+  <li>promjena dodatnih svojstava</li>
+
+</ul>
+
+<p>Svrha je postaviti korisnike kao odabrane (pretpostavljeno) ili se svi korisnici pitaju.</p>
+<h3>Savjetnik</h3>
+<p>Definicija korisničkog savjetnika:</p>
+<ul>
+  <li>dozvoljava pristup svim prozorima sukladno ovlastima njegovog stanja</li>
+  <li>samo-čitaj ili samo-probaj pristup</li>
+</ul>
+
+<p>Moguće je dodijeliti savjetnički način varijablom $conf['allow_adviser'].</p>
+<p>Ako je postavljena na 'true', moguće je odrediti korisnika kao savjetnika</p>
Index: /tags/2.0.2/language/hr_HR/index.php
===================================================================
--- /tags/2.0.2/language/hr_HR/index.php	(revision 3278)
+++ /tags/2.0.2/language/hr_HR/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/language/hr_HR/install.lang.php
===================================================================
--- /tags/2.0.2/language/hr_HR/install.lang.php	(revision 3278)
+++ /tags/2.0.2/language/hr_HR/install.lang.php	(revision 3278)
@@ -0,0 +1,66 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+$lang['Installation'] = 'Ugradba';
+$lang['Initial_config'] = 'Osnovna postava';
+$lang['Default_lang'] = 'Pretpostavljeni jezik galerije';
+$lang['step1_title'] = 'Postava baze podataka';
+$lang['step2_title'] = 'Upravna postava';
+$lang['Start_Install'] = 'Pokreni ugradbu';
+$lang['reg_err_mail_address'] = 'e-mail adresa mora biti kao xxx@yyy.eee (example : jere@stranica.org)';
+
+$lang['install_webmaster'] = 'Webmaster-ova prijava';
+$lang['install_webmaster_info'] = 'Biti æe prikazano posjetiteljima. Potrebno je za upravljanje web mjestom';
+
+$lang['step1_confirmation'] = 'Postavke su ispravne';
+$lang['step1_err_db'] = 'Povezivanje sa posluiteljem uspjeno, ali je nemoguæe povezivanje sa bazom podataka';
+$lang['step1_err_server'] = 'Ne mogu se povezati sa posluiteljem';
+$lang['step1_err_copy_2'] = 'Slijedeæi korak ugradbe je omoguæen';
+$lang['step1_err_copy_next'] = 'slijedeæi korak';
+$lang['step1_err_copy'] = 'Kopirajte ruièasti tekst izmeðu crtica i prebacite ga u "include/mysql.inc.php"(Pozor : mysql.inc.php mora sadravati samo ruièasti tekst, bez znakova novog reda ili razmaka)';
+
+$lang['step1_host'] = 'MySQL posluitelj';
+$lang['step1_host_info'] = 'localhost, sql.multimania.com, toto.freesurf.fr';
+$lang['step1_user'] = 'Korisnik';
+$lang['step1_user_info'] = 'korisnièko ime dobiveno od davatelja usluge smjetaja';
+$lang['step1_pass'] = 'Zaporka';
+$lang['step1_pass_info'] = 'korisnièka zaporka dobivena od davatelja usluge smjetaja';
+$lang['step1_database'] = 'Naziv baze podataka';
+$lang['step1_database_info'] = 'takoðer dobivena od davatelja usluge smjetaja';
+$lang['step1_prefix'] = 'Predznak tabela baze podataka';
+$lang['step1_prefix_info'] = 'nazivi tabela baze podataka æe biti predznaèeni sa time (omoguæava vam bolje upravljanje tabelama)';
+$lang['step2_err_login1'] = 'upiite korisnièko ime za webmaster-a';
+$lang['step2_err_login3'] = 'webmaster-ovo korisnièko ime ne moe sadravati znakove \' ili "';
+$lang['step2_err_pass'] = 'molimo upiite zaporku ponovo';
+$lang['install_end_title'] = 'Ugradba zavrena';
+$lang['step2_pwd'] = 'Webmaster-ova zaporka';
+$lang['step2_pwd_info'] = 'Èuvajte je na sigurnom mjestu, ona omoguæava pristup upravnoj ploèi';
+$lang['step2_pwd_conf'] = 'Zaporka [potvrdi]';
+$lang['step2_pwd_conf_info'] = 'ovjera';
+$lang['install_help'] = 'Trebate pomoæ? Pitajte na <a href="%s">Piwigo message board</a>.';
+$lang['install_end_message'] = 'Postava Piwigo-a je zavrena, slijedeæi korak je<br /><br />
+* idite na prijavnicu i koristite korisnièko ime/zaporku danu za webmaster-a<br />
+* ova prijava æe vam omoguæiti pristup upravnoj ploèi i uputama za pohranu slika u mape';
+$lang['conf_mail_webmaster'] = 'Webmaster-ova e-mail adresa';
+$lang['conf_mail_webmaster_info'] = 'Posjetitelji æe moæi pisati upravitelju galerije preko ove adrese';
+?>
Index: /tags/2.0.2/language/hr_HR/iso.txt
===================================================================
--- /tags/2.0.2/language/hr_HR/iso.txt	(revision 3278)
+++ /tags/2.0.2/language/hr_HR/iso.txt	(revision 3278)
@@ -0,0 +1,1 @@
+Hrvatski [HR]
Index: /tags/2.0.2/language/hr_HR/upgrade.lang.php
===================================================================
--- /tags/2.0.2/language/hr_HR/upgrade.lang.php	(revision 3278)
+++ /tags/2.0.2/language/hr_HR/upgrade.lang.php	(revision 3278)
@@ -0,0 +1,44 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+$lang['Upgrade'] = 'Nadogradnja';
+$lang['introduction message'] = 'Ova stranica nudi nadogradnju vaše baze podataka sa starije inačice Piwigo-a na trenutnu inačicu.
+Sustav nadogradnje smatra da trenutno koristite  <strong>izdanje %s</strong> (ili odgovarajuće).';
+$lang['Upgrade from %s to %s'] = 'Nadogradnja sa inačice %s na %s';
+$lang['Statistics'] = 'Statistika';
+$lang['total upgrade time'] = 'sveukupno vrijeme nadogradnje';
+$lang['total SQL time'] = 'sveukupno SQL vrijeme';
+$lang['SQL queries'] = 'SQL upita';
+$lang['Upgrade informations'] = 'Podaci o nadogradnji';
+$lang['perform a maintenance check'] = 'Izvršite radnu provjeru [Uprava>Posebnosti>Održavanje] u slučaju bilo kakvih problema.';
+$lang['deactivated plugins'] = 'Za svaki slučaj, slijedeći dodaci su isključeni. Morate provjeriti imaju li dodaci nadogradnje prije nego ih ponovo uključite:';
+$lang['upgrade login message'] = 'Samo upravnik može pokrenuti nadogradnju: molimo, prijavite se dolje.';
+$lang['You do not have access rights to run upgrade'] = 'Nemate pristupna prava za pokretanje nadogradnje';
+$lang['in include/mysql.inc.php, before ?>, insert:'] = 'U <i>include/mysql.inc.php</i>, prije <b>?></b>, ubacite:';
+
+// Upgrade informations from upgrade_1.3.1.php
+$lang['all sub-categories of private categories become private'] = 'Sve podskupine osobnih skupina postaju osobne';
+$lang['user permissions and group permissions have been erased'] = 'Korisničke i grupne dozvole su izbrisane';
+$lang['only thumbnails prefix and webmaster mail saved'] = 'Jedino su predznaci poveznih sličica i webmaster-ova e-mail adresa sačuvane iz prethodne postave';
+
+?>
Index: /tags/2.0.2/language/index.php
===================================================================
--- /tags/2.0.2/language/index.php	(revision 3278)
+++ /tags/2.0.2/language/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/language/it_IT/about.html
===================================================================
--- /tags/2.0.2/language/it_IT/about.html	(revision 3278)
+++ /tags/2.0.2/language/it_IT/about.html	(revision 3278)
@@ -0,0 +1,7 @@
+  <li>Piwigo è un'applicazione web che permette di creare facilmente
+una galleria d'immagini on line.</li>
+
+  <li>Piwigo è sviluppato in PHP con base dati MySQL.</li>
+
+  <li>Per suggerimenti o commenti, visitate il <a
+  href="http://piwigo.org">sito ufficiale</a>.</li>
Index: /tags/2.0.2/language/it_IT/admin.lang.php
===================================================================
--- /tags/2.0.2/language/it_IT/admin.lang.php	(revision 3278)
+++ /tags/2.0.2/language/it_IT/admin.lang.php	(revision 3278)
@@ -0,0 +1,649 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+$lang['%d association'] = '%d associazione';
+$lang['%d associations'] = '%d associazioni';
+$lang['cat_inclu_part1_S'] = '%d categoria di cui ';
+$lang['cat_inclu_part1_P'] = '%d categorie di cui ';
+$lang['cat_inclu_part2_S'] = '%d fisica';
+$lang['cat_inclu_part2_P'] = '%d fisiche';
+$lang['cat_inclu_part3_S'] = ' e %d virtuale';
+$lang['cat_inclu_part3_P'] = ' e %d virtuali';
+$lang['%d category moved'] = '%d categoria spostata';
+$lang['%d categories moved'] = '%d categorie spostate';
+$lang['%d group'] = '%d gruppo';
+$lang['%d groups'] = '%d gruppi';
+$lang['%d member'] = '%d utente';
+$lang['%d members'] = '%d utenti';
+$lang['%d tag'] = '%d tag';
+$lang['%d tags'] = '%d tags';
+$lang['%d user comment rejected'] = '%d commento utente rifiutato';
+$lang['%d user comments rejected'] = '%d commenti utente rifiutati';
+$lang['%d user comment validated'] = '%d commento utente accettato';
+$lang['%d user comments validated'] = '%d commenti utenti accettati';
+$lang['%d user deleted'] = '%d utente cancellato';
+$lang['%d users deleted'] = '%d utenti cancellati';
+$lang['%d user'] = '%d utente';
+$lang['%d users'] = '%d utenti';
+$lang['%d waiting for validation'] = '%d in attesa di accettazione';
+$lang['%d waiting pictures rejected'] = '%d immagini in attesa rifiutate';
+$lang['%d waiting pictures validated'] = '%d immagini in attesa accettate';
+$lang['Actions'] = 'Azioni';
+$lang['Activate'] = 'Attivare';
+$lang['Add/delete a permalink'] = 'Aggiungere/cancellare un permalink';
+$lang['Add a tag'] = 'Aggiungere un tag';
+$lang['Add a user'] = 'Aggiungere un utente';
+$lang['Add group'] = 'Aggiungere un gruppo';
+$lang['Add selected elements to caddie'] = 'Aggiungere gli elementi selezionati al cestino';
+$lang['Add'] = 'Aggiungere';
+$lang['Allow user registration'] = 'Consentire l\'iscrizione degli\'ospiti';
+$lang['Apply to subcategories'] = 'Applicare alle sottocategorie';
+$lang['Are you sure?'] = 'Sei sicuro?';
+$lang['Associated'] = 'Associato a';
+$lang['Association to categories'] = 'Associazione alle categorie';
+$lang['Batch management'] = 'Gestione per lotti';
+$lang['Caddie management'] = 'Gestione del cestino';
+$lang['Caddie'] = 'Cestino';
+$lang['Categories authorized thanks to group associations'] = 'Categorie accessibili grazie all\'appartenenza ai gruppi';
+$lang['Categories manual order was saved'] = 'L\'ordinamento manuale delle categorie è stato salvato';
+$lang['Categories ordered alphanumerically'] = 'Categorie ordinate alfanumericamente';
+$lang['Category elements associated to the following categories: %s'] = 'Gli elementi della categoria sono stati associati alle categorie seguenti : %s';
+$lang['Check for upgrade failed for unknown reasons.'] = 'La verifica dell\'ultima versione sul server è fallita per le ragioni sconosciute.';
+$lang['Check for upgrade'] = 'Ultima versione ?';
+$lang['Comments for all'] = 'Commenti per tutti';
+$lang['Controversy'] = 'Controversia';
+$lang['Current name'] = 'Nome attuale';
+$lang['Database'] = 'Base dati';
+$lang['Deactivate'] = 'Disattivare';
+$lang['Delete Representant'] = 'Cancellare il rappresentante';
+$lang['Delete selected tags'] = 'Cancellare i tags selezionati';
+$lang['Delete selected users'] = 'Cancellare gli utenti selezionati';
+$lang['Deletions'] = 'Soppressioni';
+$lang['Deny selected groups'] = 'Vietare l\'accesso ai gruppi selezionati';
+$lang['Deny selected users'] = 'Vietare l\'accesso agli utenti selezionati';
+$lang['Description'] = 'Descrizione';
+$lang['Display options'] = '0pzioni di visualizzazione';
+$lang['Dissociated'] = 'Dissociata da';
+$lang['Does not represent'] = 'Non rappresenta';
+$lang['Edit all picture informations'] = 'Modificare tutte le informazioni relative all\'immagine';
+$lang['Edit selected tags'] = 'Modificare i tags selezionati';
+$lang['Edit tags'] = 'Modificare i tags';
+$lang['Elements'] = 'Elementi';
+$lang['Email administrators when a new user registers'] = 'Notificare gli amministratori dell\'iscrizzione di un nuovo utente';
+$lang['Email administrators when a valid comment is entered'] = 'Notificare gli amministratori della presenza di un nuovo commento';
+$lang['Email administrators when a comment requires validation'] = 'Notificare gli amministratori quando un commento richiede una convalida';
+$lang['Email administrators when a picture is uploaded'] = 'Notificare gli amministratori quando un\'immagine è caricata';
+$lang['Empty caddie'] = 'Svuotare il cestino';
+$lang['Environment'] = 'Ambiente';
+$lang['Form'] = 'formulario';
+$lang['Gallery URL'] = 'URL della galleria';
+$lang['Gallery description'] = 'Descrizione della galleria';
+$lang['Gallery title'] = 'Titolo della galleria';
+$lang['Grant selected groups'] = 'Dare l\'accesso ai gruppi selezionati';
+$lang['Grant selected users'] = 'Dare l\'accesso agli utenti selezionati';
+$lang['Group name'] = 'Nome del gruppo';
+$lang['Groups'] = 'Gruppi';
+$lang['Guests'] = 'Ospiti';
+$lang['History'] = 'Cronologia';
+$lang['Informations'] = 'Informazioni';
+$lang['Install'] = 'Installare';
+$lang['Link all category elements to a new category'] = 'Associare tutti gli elementi della categoria ad una nuova categoria';
+$lang['Link all category elements to some existing categories'] = 'Associare tutti gli elementi della categoria a delle categorie esistenti';
+$lang['Linked categories'] = 'Categorie associate';
+$lang['Lock gallery'] = 'Blocco della galleria';
+$lang['Maintenance'] = 'Manutenzione';
+$lang['Manage permissions for a category'] = 'Gestire i permessi per una categoria';
+$lang['Manage permissions for group "%s"'] = 'Gestire i permessi per il gruppo "%s"';
+$lang['Manage permissions for user "%s"'] = 'Gestire i permessi per l\'utente "%s"';
+$lang['Manage tags'] = 'Gestire i tags';
+$lang['Members'] = 'Membri';
+$lang['Metadata synchronized from file'] = 'Metadati sincronizzati dal file';
+$lang['Move categories'] = 'Spostare le categorie';
+$lang['Move'] = 'Spostare';
+$lang['Name'] = 'Nome';
+$lang['New name'] = 'Nuovo nome';
+$lang['New parent category'] = 'Nuova categoria principale';
+$lang['New tag'] = 'Nuovo tag';
+$lang['No tag defined. Use Administration>Pictures>Tags'] = 'Nessun tag di definito. Utilizzare lo schermo Amministrazione>Immagini>Tags';
+$lang['Number of comments per page'] = 'Numero di commenti per pagina';
+$lang['Number of rates'] = 'Numero di voti';
+$lang['Number of thumbnails to create'] = 'Numero di miniature da creare';
+$lang['Only private categories are listed'] = 'Solo le categorie private sono elencate';
+$lang['Operating system'] = 'Sistema operativo';
+$lang['Options'] = 'Opzioni';
+$lang['Order alphanumerically'] = 'Ordina alfanumericamente';
+$lang['Other private categories'] = 'Altre categorie private';
+$lang['Page banner'] = 'Banner di pagina';
+$lang['Parent category'] = 'Categoria principale';
+$lang['Path'] = 'Percorso';
+$lang['Permalink'] = 'Permalink';
+$lang['Permalink_%s_histo_used_by_%s'] = 'Il permalink %s è stato usato precedentemente per la categoria %s. Cancellarlo prima dallo storico';
+$lang['Permalink_name_rule'] = 'Il permalink deve essere composto unicamente dai caratteri seguenti : "a-zA-Z0-9", "-" o "_". Non deve essere numerico o iniziare con un numero seguito da "-"';
+$lang['Permalink %s is already used by category %s'] = 'Il permalink %s è già usato nella galleria %s';
+$lang['Permalink history'] = 'Cronologia dei permalinks';
+$lang['Permalinks'] = 'Permalinks';
+$lang['Permission denied'] = 'Accesso non autorizzato';
+$lang['Permission granted thanks to a group'] = 'Accesso autorizzato grazie al\'appartenenza ai gruppi';
+$lang['Permission granted'] = 'Accesso autorizzato';
+$lang['Picture informations updated'] = 'Informazioni dell\'immagine sono state aggiornate';
+$lang['Plugins'] = 'Plugins';
+$lang['Position'] = 'Posizione';
+$lang['Preferences'] = 'Preferenze';
+$lang['Properties'] = 'Proprietà';
+$lang['Random picture'] = 'Immagine a caso';
+$lang['Rate date'] = 'Data del voto';
+$lang['Rating by guests'] = 'Voti degli ospiti';
+$lang['Rating'] = 'Voto';
+$lang['Reject All'] = 'Rifiutare tutto';
+$lang['Reject'] = 'Rifiutare';
+$lang['Representant'] = 'Rappresentante';
+$lang['Representation of categories'] = 'Rappresentazione delle categorie';
+$lang['Representative'] = 'Rappresentativa';
+$lang['Represents'] = 'Rappresenta';
+$lang['Save order'] = 'Salvare l\'ordine';
+$lang['Save to permalink history'] = 'Salvare nello storico (cronologia) dei permalinks';
+$lang['Select at least one category'] = 'Scegliere almeno una categoria';
+$lang['Select at least one picture'] = 'Scegliere almeno un\'immagine';
+$lang['Select at least one user'] = 'Scegliere almeno un\'utente';
+$lang['Show info'] = 'Mostra le informazioni';
+$lang['Site manager'] = 'Gestione dei siti';
+$lang['Status'] = 'Stato';
+$lang['Statistics'] = 'Statistiche';
+$lang['Storage category'] = 'Categoria di memorizzazione';
+$lang['Sum of rates'] = 'Somma dei voti';
+$lang['Tag "%s" already exists'] = 'Il tag "%s" esiste già';
+$lang['Tag "%s" was added'] = 'Il tag "%s" è stato aggiunto';
+$lang['Tag selection'] = 'Selezione dei tags';
+$lang['Take selected elements out of caddie'] = 'Estrarre gli elementi selezionati dal cestino';
+$lang['The %d following tag were deleted'] = 'Il tag seguente è stato cancellato';
+$lang['The %d following tags were deleted'] = 'I %d tags seguenti sono stati cancellati';
+$lang['Unable to check for upgrade.'] = 'Non è stato possibile identificare l\'ultima versione.';
+$lang['Uninstall'] = 'Disinstallare';
+$lang['Use default sort order']='Usare l\'ordinamento delle immagini di defaut (cosi come definito nel file di configurazione)';
+$lang['User comments validation'] = 'Approvare i commenti degli utenti';
+$lang['Users'] = 'Utenti';
+$lang['Validate All'] = 'Approvare tutto';
+$lang['Validate'] = 'Approvare';
+$lang['Validation'] = 'Richiedere la validazione';
+$lang['Version'] = 'Versione';
+$lang['Virtual categories movement'] = 'Spostare categoria virtuale';
+$lang['Virtual categories to move'] = 'Categorie virtuali da spostare';
+$lang['Virtual category name'] = 'Nome della categoria virtuale';
+$lang['Webmaster cannot be deleted'] = 'Il webmaster non può essere cancellato';
+$lang['You are running on development sources, no check possible.'] = 'State lavorando con una versione di sviluppo, impossibile verificare l\'ultima versione.';
+$lang['You cannot delete your account'] = 'Non potete cancellare il vostro conto utente';
+$lang['You cannot move a category in its own sub category'] = 'Non potete spostare una categoria in una sua sottocategoria.';
+$lang['You need to confirm deletion'] = 'Dovete confermare la cancellazione';
+$lang['add tags'] = 'aggiungere i tags';
+$lang['adviser'] = 'Consigliere';
+$lang['associate to category'] = 'associare la categoria';
+$lang['associate to group'] = 'associare al gruppo';
+$lang['authorized'] = 'Autorizzate';
+$lang['cat_add'] = 'Aggiungere una categoria virtuale';
+$lang['cat_comments_title'] = 'Autorizzare gli utenti ad aggiungere dei commenti nelle categorie selezionate';
+$lang['cat_error_name'] = 'Il nome della categoria non deve essere vuoto';
+$lang['cat_lock_title'] = 'Blocco delle categorie';
+$lang['cat_private'] = 'Categoria privata';
+$lang['cat_public'] = 'Categoria pubblica';
+$lang['cat_representant'] = 'Trovare un nuovo rappresentante a caso';
+$lang['cat_security'] = 'Pubblica / Privata';
+$lang['cat_status_title'] = 'Gestire le autorizzazione per le categorie selezionate';
+$lang['cat_upload_title'] = 'Selezionare le categorie su cui è possibile caricare nuove immagini';
+$lang['cat_virtual_added'] = 'Categoria virtuale aggiunta';
+$lang['cat_virtual_deleted'] = 'Categoria virtuale cancellata';
+$lang['category'] = 'Categoria';
+$lang['conf_access'] = 'Tipo di accesso';
+$lang['conf_comments_title'] = 'Commenti utente';
+$lang['conf_confirmation'] = 'Informazioni registrate nella base dati';
+$lang['conf_display'] = 'Visualizzazione di default';
+$lang['conf_history_title'] = 'Cronologia';
+$lang['conf_gallery_url_error'] = 'L\'URL della galleria non è valido.';
+$lang['conf_main_title'] = 'Principale';
+$lang['conf_nb_comment_page_error'] = 'Il numero di commenti utenti per pagina deve essere compreso tra 5 e 50.';
+$lang['config'] = 'Configurazione';
+$lang['confirm'] = 'Confermare';
+$lang['Date'] = 'Data';
+$lang['delete category'] = 'cancellare la categoria';
+$lang['dissociate from category'] = 'dissociare la categoria';
+$lang['dissociate from group'] = 'dissociare dal gruppo';
+$lang['edit category permissions'] = 'Modificare i permessi della categoria';
+$lang['editcat_confirm'] = 'Le informazioni della categoria sono state aggiornate con successo.';
+$lang['editcat_uploadable'] = 'Autorizzare l\'aggiunta d\'immagini';
+$lang['elements per page'] = 'elementi per pagina';
+$lang['elements'] = 'elementi';
+$lang['enabled_high'] = 'Alta definizione attiva';
+$lang['file'] = 'File';
+$lang['filesize'] = 'Dimensione file';
+$lang['first element added on %s'] = 'primo elemento aggiunto il %s';
+$lang['forbidden'] = 'Vietate';
+$lang['conf_general'] = 'Generale';
+$lang['global mode'] = 'modo globale';
+$lang['group "%s" added'] = 'Gruppo "%s" aggiunto';
+$lang['group "%s" deleted'] = 'gruppo "%s" cancellato';
+$lang['group "%s" updated'] = 'gruppo "%s" aggiornato';
+$lang['group'] = 'gruppo';
+$lang['group_add_error1'] = 'Il nome del gruppo non deve contenere " o \' e non deve essere vuoto.';
+$lang['group_add_error2'] = 'Questo nome è già usato per un altro gruppo.';
+$lang['groups'] = 'Gruppi';
+$lang['instructions'] = 'Istruzioni';
+$lang['is_high_disabled'] = '';
+$lang['is_high_enabled'] = 'Alta definizione';
+$lang['jump to category'] = 'andare alla categoria';
+$lang['jump to image'] = 'andare al\'immagine';
+$lang['leave'] = 'Abbandonare';
+$lang['lock'] = 'Bloccare';
+$lang['locked'] = 'Bloccate';
+$lang['manage category elements'] = 'gestire gli elementi della categoria';
+$lang['manage sub-categories'] = 'gestire le sottocategorie';
+$lang['manage'] = 'Gestire';
+$lang['maximum height'] = 'altezza massima';
+$lang['maximum width'] = 'larghezza massima';
+$lang['nbm_background_treatment_redirect_second'] = 'Il tempo di esecuzione è scaduto, il trattamento deve continuare [Tempo stimato: %d secondo].';
+$lang['nbm_background_treatment_redirect_seconds'] = 'Il tempo di esecuzione è scaduto, il trattamento deve continuare [Tempo stimato: %d secondi].';
+$lang['nbm_break_timeout_list_user'] = 'Il tempo di preparazione della lista degli utenti per l\'invio dell\'email è limitato. Gli altri utenti non sono elencati';
+$lang['nbm_break_timeout_send_mail'] = 'Il tempo per l\'invio dell\'email è limitato. L\'invio delle altre email verra ignorato.';
+$lang['nbm_col_check_user_send_mail'] = 'Inviare?';
+$lang['nbm_col_last_send'] = 'Ultimo invio';
+$lang['nbm_col_mail'] = 'email';
+$lang['nbm_col_user'] = 'Utente';
+$lang['nbm_complementary_mail_content'] = 'Contenuto complementare per l\'email';
+$lang['nbm_content_byebye'] = 'A presto,';
+$lang['nbm_content_goto_1'] = 'A presto su ';
+$lang['nbm_content_goto_2'] = '.';
+$lang['nbm_content_hello_1'] = 'Ciao ';
+$lang['nbm_content_hello_2'] = ',';
+$lang['nbm_content_new_elements'] = 'Nuovi elementi sono stati aggiunti ';
+$lang['nbm_content_new_elements_single'] = ' il ';
+$lang['nbm_content_new_elements_between_1'] = 'tra il ';
+$lang['nbm_content_new_elements_between_2'] = ' e il ';
+$lang['nbm_content_subscribe_by_admin'] = 'Siete stati iscritti dal webmaster del sito per la ricezione di notifiche via email.';
+$lang['nbm_content_subscribe_by_himself'] = 'Vi siete iscritti per la ricezione di notifiche via email.';
+$lang['nbm_content_subscribe_link'] = 'Per iscrivervi';
+$lang['nbm_content_problem_contact'] = 'Per qualsiasi domanda o problema inviare un messaggio a ';
+$lang['nbm_content_pb_contact_object'] = '[NBM] Problemi o domande';
+$lang['nbm_content_unsubscribe_by_admin'] = 'Siete stati cancellati dal webmaster dalla sottoscrizione alla ricezione di notifiche via email.';
+$lang['nbm_content_unsubscribe_by_himself'] = 'Vi siete cancellati dalla sottoscrizione alla ricezione di notifiche via email.';
+$lang['nbm_content_click_on'] = ', cliccare su ';
+$lang['nbm_content_unsubscribe_link'] = 'Per cancellare la sottoscrizione ';
+$lang['nbm_info_send_mail_as'] = 'Lasciando vuoto verrà inviato il titolo della galleria';
+$lang['nbm_item_notification'] = 'Notifica';
+$lang['nbm_msg_error_sending_email_to'] = 'Errore durante l\'invio dell\'email a %s [%s].';
+$lang['nbm_msg_mail_sent_to'] = 'Email inviata a %s [%s].';
+$lang['nbm_msg_n_mail_sent'] = '%s email inviata.';
+$lang['nbm_msg_n_mails_sent'] = '%s email inviate.';
+$lang['nbm_msg_n_mail_not_send'] = '%s email non è stata inviata.';
+$lang['nbm_msg_n_mails_not_send'] = '%s email non sono state inviate.';
+$lang['nbm_no_mail_to_send'] = 'Nessuna email da inviare.';
+$lang['nbm_no_user_available_to_send_L1'] = 'Nessun utente da notificare via email.';
+$lang['nbm_no_user_available_to_send_L2'] = 'Un utente è da notificare se ci sono nuovi elementi disponibili.';
+$lang['nbm_no_user_available_to_send_L3'] = 'È possibile che non vi siano utenti iscritti (solo il webmaster può accedere a queste informazioni).';
+$lang['nbm_no_user_to send_notifications_by_mail'] = 'Nessun utente da notificare via email.';
+$lang['nbm_object_news'] = 'Nuovi elementi aggiunti';
+$lang['nbm_object_subscribe'] = 'Sottoscrivere alla notifica via email';
+$lang['nbm_object_unsubscribe'] = 'Cancella dalla notifica via email';
+$lang['nbm_param_mode'] = 'Parametri';
+$lang['nbm_redirect_msg'] = 'Trattamento in corso.'."\n".'Attendere prego...';
+$lang['nbm_repost_submit'] = 'Continuare il trattamento in corso...';
+$lang['nbm_send_complementary_mail_content'] = 'Contenuto aggiuntivo dell\'email';
+$lang['nbm_send_detailed_content'] = 'Invia contenuto dettagliato';
+$lang['nbm_send_mail_as'] = 'Inviare l\'email come';
+$lang['nbm_send_mail_to_users'] = 'Invia un\'email agli utenti';
+$lang['nbm_send_mode'] = 'Invio';
+$lang['nbm_send_options'] = 'Opzioni';
+$lang['nbm_send_submit'] = 'Inviare';
+$lang['nbm_subscribe_col'] = 'Iscritti';
+$lang['nbm_subscribe_mode'] = 'Iscriviti';
+$lang['nbm_title_param'] = 'Parametri';
+$lang['nbm_title_send'] = 'Selezionare gli invii';
+$lang['nbm_title_subscribe'] = 'Iscrivere/Cancellare utenti';
+$lang['nbm_unsubscribe_col'] = 'Non inscritti';
+$lang['nbm_updated_param_count'] = '%d parametro è stato aggiornato.';
+$lang['nbm_updated_params_count'] = '%d parametri sono stati aggiornati.';
+$lang['nbm_user_change_enabled_error_on_updated_data_count'] = '%d utente non è stato aggiornato.';
+$lang['nbm_users_change_enabled_error_on_updated_data_count'] = '%d utenti non sono stati aggiornati.';
+$lang['nbm_user_change_enabled_false'] = 'L\'utente %s [%s] è stato cancellato dalla lista degli iscritti.';
+$lang['nbm_user_change_enabled_true'] = 'L\'utente %s [%s] è stato aggiunto alla lista degli iscritti.';
+$lang['nbm_user_change_enabled_updated_data_count'] = '%d utente aggiornato.';
+$lang['nbm_users_change_enabled_updated_data_count'] = '%d utenti aggiornati.';
+$lang['nbm_user_not_change_enabled_false'] = 'L\'utente %s [%s] non è stato cancellato dalla lista degli iscritti.';
+$lang['nbm_user_not_change_enabled_true'] = 'L\'utente %s [%s] non è stato aggiunto alla lista degli iscritti.';
+$lang['nbm_user_x_added'] = 'Utente %s [%s] aggiunto.';
+$lang['nbm_warning_subscribe_unsubscribe'] = 'Attenzione: la sottoscrizione o la cancellazione invierà un\'email agli utenti in questione';
+$lang['nbm_send_html_mail'] = 'Invio dell\'email in formato HTML';
+$lang['nbm_send_recent_post_dates'] = 'Includere le ultime immagini per data';
+$lang['nbm_info_send_recent_post_dates'] = 'Disponibile unicamente con il formato HTML';
+$lang['no_write_access'] = 'Nessun accesso in scrittura';
+$lang['path'] = 'percorso';
+$lang['permissions'] = 'Permessi';
+$lang['private'] = 'privato';
+$lang['properties'] = 'Proprietà';
+$lang['public'] = 'pubblico';
+$lang['purge never used notification feeds'] = '"Ripulire" i flussi di notifica mai usate';
+$lang['purge sessions'] = '"Ripulire" le sessioni';
+$lang['randomly represented'] = 'rappresentante a caso';
+$lang['registration_date'] = 'data di registrazione';
+$lang['remote_site'] = 'Sito remoto';
+$lang['remote_site_clean'] = 'ripulire';
+$lang['remote_site_clean_hint'] = 'Rimuovere il file remoto "listing.xml"';
+$lang['remote_site_generate'] = 'generare il listing';
+$lang['remote_site_generate_hint'] = 'generare il file "listing.xml" sul sito remoto';
+$lang['remote_site_local_create'] = 'Creare sito';
+$lang['remote_site_local_found'] = 'Un file "listing.xml" è stato trovato per ';
+$lang['remote_site_local_update'] = 'leggere il file "listing.xml" e aggiornare';
+$lang['remote_site_test'] = 'verificare';
+$lang['remote_site_test_hint'] = 'verificare sito remoto';
+$lang['remote_site_uncorrect_url'] = 'L\'URL del sito remoto deve iniziare con http o https e contenere unicamente i caratteri "/", "a-zA-Z0-9", "-" o "_"';
+$lang['remove tags'] = 'Rimuovere i tags';
+$lang['repair and optimize database'] = 'Riparare o ottimizzare la base dati';
+$lang['selection'] = 'selezione';
+$lang['set to'] = 'Impostare a';
+$lang['singly represented'] = 'rappresentante fisso';
+$lang['site_already_exists'] = 'Questo sito esiste già';
+$lang['site_create'] = 'Creare un nuovo sito: (indicare URL verso "create_listing_file.php")';
+$lang['site_created'] = 'creato';
+$lang['site_delete'] = 'cancellare';
+$lang['site_delete_hint'] = 'cancellare questo sito e tutti gli elementi ad esso connessi';
+$lang['site_deleted'] = 'cancellato';
+$lang['site_err'] = 'Si è verificato un errore';
+$lang['site_err_remote_file_not_found'] = 'file "create_listing_file.php" introvabile sul sito remoto';
+$lang['site_local'] = 'Locale';
+$lang['site_remote'] = 'Remoto';
+$lang['site_synchronize'] = 'sincronizzare';
+$lang['site_synchronize_hint'] = 'Aggiornare la base dati dai files';
+$lang['status'] = 'stato';
+$lang['storage'] = 'Directory';
+$lang['sub-categories'] = 'Sottocategorie';
+$lang['synchronize metadata'] = 'sincronizzare i metadati';
+$lang['synchronize'] = 'sincronizzare';
+$lang['target'] = 'Target';
+$lang['thumbnail'] = 'Miniatura';
+$lang['title'] = 'titolo';
+$lang['title_categories'] = 'Gestione delle categorie';
+$lang['title_configuration'] = 'Configurazione di Piwigo';
+$lang['title_default'] = 'Amministrazione di Piwigo';
+$lang['title_edit_cat'] = 'Modificare una categoria';
+$lang['title_groups'] = 'Gestione gruppi';
+$lang['title_liste_users'] = 'Lista utenti';
+$lang['title_picmod'] = 'Modificare le informazioni dell\'immagine';
+$lang['title_thumbnails'] = 'Creazione delle miniature';
+$lang['title_update'] = 'Sincronizzazione della base dati con i files';
+$lang['title_upload'] = 'Immagini in attesa di convalida';
+$lang['tn_all'] = 'tutto';
+$lang['tn_alone_title'] = 'immagini senza miniature (solo jpeg e png)';
+$lang['tn_err_height'] = 'l\'altezza deve essere un numero superiore a';
+$lang['tn_err_width'] = 'la larghezza deve essere un numero superiore a';
+$lang['tn_format'] = 'per il formato del file';
+$lang['tn_no_missing'] = 'Nessuna miniatura mancante';
+$lang['tn_no_support'] = 'Immagine non trovata o non supportata';
+$lang['tn_params_GD'] = 'versione GD';
+$lang['tn_params_title'] = 'Parametri di miniaturizzazione';
+$lang['tn_results_gen_time'] = 'generata in';
+$lang['tn_results_title'] = 'Risultati della miniaturizzazione';
+$lang['tn_stats'] = 'Statistiche generali';
+$lang['tn_stats_max'] = 'tempo massimo';
+$lang['tn_stats_mean'] = 'tempo medio';
+$lang['tn_stats_min'] = 'tempo minimo';
+$lang['tn_stats_nb'] = 'numero di foto miniaturizzate';
+$lang['tn_stats_total'] = 'tempo totale';
+$lang['tn_thisformat'] = 'per questo formato di file';
+$lang['unit mode'] = 'modo unitario';
+$lang['unlocked'] = 'Sbloccate';
+$lang['unset'] = 'Svuotare';
+$lang['up'] = 'Sposta su';
+$lang['update categories informations'] = 'Aggiorna le informazioni delle categorie';
+$lang['update images informations'] = 'Aggiorna le informazioni delle immagini';
+$lang['update'] = 'Sincronizzare';
+$lang['update_cats_subset'] = 'eseguire unicamente sulle categorie selezionate';
+$lang['update_default_title'] = 'Scegli un\'opzione';
+$lang['update_display_info'] = 'Mostra tutte le informazioni possibili (categorie ed elementi aggiunti o eliminati)';
+$lang['update_err_pwg_version_differs'] = 'La versione di Piwigo differisce da quella sul server remoto';
+$lang['update_err_pwg_version_differs_info'] = 'La versione del file "create_listing_file.php" sul server remoto deve essere la stessa di Piwigo';
+$lang['update_err_remote_listing_not_found'] = 'Il file "listing.xml" non è stato trovato';
+$lang['update_err_remote_listing_not_found_info'] = 'Il file "listing.xml" non è stato trovato. Questo file è generato scegliendo il comando "genera la lista" nella sezione "Amministrazione del sito"';
+$lang['update_error_list_title'] = 'Lista degli errori';
+$lang['update_errors_caption'] = 'Significato degli errori';
+$lang['update_infos_title'] = 'Informazioni dettagliate';
+$lang['update_missing_file_or_dir'] = 'Errore in letture del file/directory';
+$lang['update_missing_file_or_dir_info'] = 'Non è possibile accedere al file o alla directory (probabilmente non esiste o l\'accesso è stato negato)';
+$lang['update_missing_tn_info'] = 'Ogni file immagine richiede una miniatura. La miniatura deve essere presente nella sottodirectory "thumbnail" della directory. Il nome del file della miniatura deve iniziare con il parametro di configurazione "prefix_thumbnail" e l\'estensione deve essere uno di valori della lista seguente:';
+$lang['update_missing_tn_short'] = 'miniature mancanti';
+$lang['update_nb_del_categories'] = 'categorie eliminate dalla base dati';
+$lang['update_nb_del_elements'] = 'elementi eliminati dalla base dati';
+$lang['update_nb_elements_metadata_available'] = 'immagini in coda per la sincronizzazione dei metadati';
+$lang['update_nb_elements_metadata_sync'] = 'informazioni sugli elementi sincronizzate con i metadati';
+$lang['update_nb_errors'] = 'errori durante la sincronizzazione';
+$lang['update_nb_new_categories'] = 'categorie aggiunte nella base dati';
+$lang['update_nb_new_elements'] = 'elementi aggiunti nella base dati';
+$lang['update_nb_upd_elements'] = 'elementi aggiornati nella base dati';
+$lang['update_part_research'] = 'Cercare nuove immagini nelle directory';
+$lang['update_research_added'] = 'aggiunto';
+$lang['update_research_deleted'] = 'cancellato';
+$lang['update_result_metadata'] = 'Risultato della sincronizzazione dei metadati';
+$lang['update_simulate'] = 'Solo simulazione (non sarà fatta nessuna modifica nella base dati)';
+$lang['update_simulation_title'] = '[Simulazione]';
+$lang['update_sync_all'] = 'directory + file';
+$lang['update_sync_dirs'] = 'solo directory';
+$lang['update_sync_files'] = 'sincronizzare la struttura dei files con la base dati';
+$lang['update_sync_metadata'] = 'sincronizzare gli elementi della base dati con le informazioni presenti nei metadati dei files';
+$lang['update_sync_metadata_all'] = 'anche gli elementi già sincronizzati';
+$lang['update_used_metadata'] = 'Metadati usati';
+$lang['update_wrong_dirname_info'] = 'Il nome delle directory e dei files deve essere composto da lettere, numeri, "-", "_" o "."';
+$lang['update_wrong_dirname_short'] = 'Nome file errato';
+$lang['upload'] = 'Caricare';
+$lang['user "%s" added'] = 'utente "%s" aggiunto';
+$lang['user_status'] = 'Statuto del\'utente';
+$lang['user_status_admin'] = 'Amministratore';
+$lang['user_status_generic'] = 'Generico';
+$lang['user_status_guest'] = 'Ospite';
+$lang['user_status_normal'] = 'Utente';
+$lang['user_status_webmaster'] = 'Webmaster';
+$lang['username'] = 'Nome utente';
+$lang['users'] = 'Utenti';
+$lang['virtual_category'] = 'Categorie virtuale';
+$lang['waiting'] = 'In attesa';
+$lang['is_default_group'] = 'di default';
+$lang['toggle_is_default_group'] = 'Invertire la proprietà "gruppo di default"';
+$lang['Advanced_features'] = 'Funzioni avanzate';
+$lang['Elements_not_linked'] = 'Elementi sciolti';
+$lang['special_admin_menu'] = 'Speciale';
+$lang['Duplicates'] = 'File con stesso nome in più di una categoria fisica';
+
+$lang['Overall'] = 'Vista globale';
+$lang['Year'] = 'Anno';
+$lang['Month'] = 'Mese';
+$lang['Day'] = 'Giorno';
+$lang['Pages seen'] = 'Pagine viste';
+$lang['Pictures'] = 'Immagini';
+$lang['time'] = 'Ora';
+$lang['user'] = 'Utente';
+$lang['IP'] = 'IP';
+$lang['image'] = 'Elemento';
+$lang['section'] = 'Selezione';
+$lang['tags'] = 'Tags';
+$lang['conf_history_guest'] = 'Registrare le pagini visitate da gli ospiti';
+$lang['conf_history_user'] = 'Registrare le pagini visitate da gli utenti';
+$lang['conf_history_admin'] = 'Registrare le pagini visitate da gli amministratori';
+$lang['cat_options_title'] = 'Propietà';
+$lang['An information email was sent to group "%s"'] = 'Un\'email d\'informazione è stato inviato agli utenti del gruppo';
+$lang['Send an information email to group members'] = 'Inviare un\'email d\'informazione agli utenti di un gruppo';
+$lang['Group'] = 'Gruppo';
+$lang['[%s] Come to visit the category %s'] = '[%s] Venite a visitare la categoria %s';
+$lang['Hello,'] = 'Ciao,';
+$lang['See you soon.'] = 'A presto.';
+$lang['Come to discover the category:'] = 'Venite a scoprire la categoria:';
+$lang['mail_content'] = 'Contenuto dell\'email';
+$lang['none'] = 'nessuno';
+$lang['high'] = 'high';
+$lang['other'] = 'altro';
+$lang['Element type'] = 'tipo di elemento';
+$lang['User'] = 'Utente';
+$lang['Image id'] = 'Id immagine';
+$lang['Summary'] = 'Riassunto';
+$lang['%d line filtered'] = '%d linea filtrata';
+$lang['%d lines filtered'] = '%d linee filtrate';
+$lang['%d guest'] = '%d ospite';
+$lang['%d guests'] = '%d ospiti';
+$lang['Hour'] = 'Ora';
+$lang['is_the_guest'] = 'ospite';
+$lang['is_the_default'] = 'valore di default';
+$lang['High filesize'] = 'Dimenzione del file Alta Risoluzione';
+// --------- Starting below: New or revised $lang ---- from version 1.7.1
+$lang['Guest cannot be deleted'] = 'L\'utente "ospite" non può essere cancellato';
+$lang['Default user cannot be deleted'] = 'L\'utente di default non può essere cancellato';
+$lang['purge history detail'] = '"Ripulire" i dettagli dalla cronoligia';
+$lang['purge history summary'] = '"Ripulire" il sommario dalla cronoligia';
+$lang['c13y_title'] = 'Controllo d\'integrità';
+$lang['c13y_Anomaly'] = 'Anomalia';
+$lang['c13y_Correction'] = 'Correzione';
+$lang['c13y_Automatic_correction'] = 'Correzione automatica';
+$lang['c13y_Impossible_automatic_correction'] = 'Correzione automatica impossibile';
+$lang['c13y_Correction_applied_success'] = 'Correzione applicata con sucesso';
+$lang['c13y_Correction_applied_error'] = 'Correzione applicata con errori';
+$lang['c13y_anomaly_count'] = 'individuata %d anomalia.';
+$lang['c13y_anomalies_count'] = 'individuate %d anomalie.';
+$lang['c13y_anomaly_corrected_count'] = '%d anomalia corretta.';
+$lang['c13y_anomalies_corrected_count'] = '%d anomalie corrette.';
+$lang['c13y_anomaly_not_corrected_count'] = 'non è stato possibile correggere %d anomalia.';
+$lang['c13y_anomalies_not_corrected_count'] = 'non è stato possibile correggere %d anomalie.';
+$lang['c13y_more_info'] = 'Recarsi su : %s o %s per avere più informazioni';
+$lang['c13y_more_info_forum'] = 'il forum';
+$lang['c13y_more_info_wiki'] = 'il wiki';
+$lang['c13y_exif_anomaly'] = 'Il valore di %s non è corretto per causa del exif che non è sopportato';
+$lang['c13y_exif_correction'] = '%s deve essere impostato a "false" nel vostro file config_local.inc.php';
+$lang['c13y_guest_non_existent'] = 'L\'utente "ospite" principale non esiste più';
+$lang['c13y_bad_guest_status'] = 'Lo statuto del\'utente "ospite" principale non è corretto';
+$lang['c13y_default_non_existent'] = 'L\'utente di default non esiste più';
+$lang['c13y_webmaster_non_existent'] = 'L\'utente "webmaster" principal non esiste più';
+$lang['c13y_bad_webmaster_status'] = 'Lo statuto del\'utente "webmaster" principal non è corretto';
+$lang['c13y_user_created'] = 'L\'utente "%s" creato con la password "%s"';
+$lang['c13y_user_status_updated'] = 'Statuto del\'utente "%s" aggiornato';
+$lang['add new elements to caddie'] = 'aggiungere i nuovi elementi al cestino';
+// --------- Starting below: New or revised $lang ---- from Butterfly
+$lang['no_display_thumbnail'] = 'Nessuna visualizzazione';
+$lang['display_thumbnail_classic'] = 'Visualizzazione classica';
+$lang['display_thumbnail_hoverbox'] = 'Visualizzazione durante il passaggio del mouse';
+$lang['Thumbnails'] = 'Miniature';
+$lang['obligatory_user_mail_address'] = 'L\'indirizzo email è obligatorio per tutti gli utenti';
+$lang['Minimum privacy level'] = 'Livello minimo di confidenzialità';
+$lang['Privacy level'] = 'Livello di confidenzialità';
+$lang['Level 0'] = '---';
+$lang['Level 1'] = 'Contatti';
+$lang['Level 2'] = 'Amici';
+$lang['Level 4'] = 'Famiglia';
+$lang['Level 8'] = 'Amministratori';
+$lang['c13y_maintenance'] = 'Reinizalizzare i controlli d\'integrità';
+$lang['Check all'] = 'Selezionare tutto';
+$lang['Uncheck all'] = 'Deselezionare tutto';
+$lang['c13y_check_auto'] = 'Selezionare le correzioni automatiche';
+$lang['c13y_submit_correction'] = 'Applicare le correczioni selezionate';
+$lang['c13y_submit_ignore'] = 'Ignorare le anomalie selezionate';
+$lang['c13y_submit_refresh'] = 'Aggiornare';
+$lang['c13y_ignore_msg1'] = 'L\'anomalia verra ignorata fino alla prossima versione del\'applicazione';
+$lang['c13y_ignore_msg2'] = 'La correczion del\'anomalia annulera il fatto che sia ignorata';
+$lang['c13y_anomaly_ignored_count'] = '%d anomalia è stata ignorata.';
+$lang['c13y_anomalies_ignored_count'] = '%d anomalie sono state ignorate.';
+$lang['plugins_need_update'] = 'Plugins che necessitano un aggiornamento';
+$lang['plugins_dontneed_update'] = 'Plugins aggiorno';
+$lang['plugins_cant_check'] = 'È impossibile verificare i plugins seguenti';
+$lang['plugins_actual_version'] = 'Versione<br>attuale';
+$lang['plugins_new_version'] = 'Versione<br>disponibile';
+$lang['plugins_auto_update'] = 'Aggiornamento automatico';
+$lang['plugins_auto_install'] = 'Installazione automatica';
+$lang['plugins_download'] = 'Scaricare il file';
+$lang['plugins_tab_list'] = 'Lista dei plugins';
+$lang['plugins_tab_update'] = 'Verificare gli aggiornamenti';
+$lang['plugins_tab_new'] = 'Altri plugins disponibili';
+$lang['plugins_revisions'] = 'Ultimi aggiornamenti';
+$lang['plugins_delete'] = 'Cancellare';
+$lang['plugins_confirm_install'] = 'Siete sicuri di volere installare questo plugin?';
+$lang['plugins_confirm_delete'] = 'Siete sicuri di volere cancellare questo plugin?';
+$lang['plugins_confirm_upgrade'] = 'Siete sicuri di volere installare questo aggiornamento? Dovete verificare che questo aggiornamento non necessiti una disinstallazione.';
+$lang['plugins_upgrade_ok'] = '%s é stato aggiornato con successo.';
+$lang['plugins_install_ok'] = 'Il plugin é stato copiato con sucesso.';
+$lang['plugins_install_need_activate'] = 'Recatevi nella lista dei plugins per installarlo e attivarlo.';
+$lang['plugins_temp_path_error'] = 'È impossibile creare un file temporaneo.';
+$lang['plugins_dl_archive_error'] = 'È impossibile recuperare l\'archivio.';
+$lang['plugins_archive_error'] = 'È impossibile leggere o di eseguire l\'archivio.';
+$lang['plugins_extract_error'] = 'Un errore è avvenuto durante l\'esecuzione del file (%s).';
+$lang['plugins_check_chmod'] = 'Verificate i permessi della cartella "plugins" et delle sue sotto cartelle (CHMOD).';
+$lang['plugins_server_error'] = 'Non é possibile connettersi al server.';
+$lang['Purge compiled templates'] = 'Spurgare i templates compilati';
+$lang['Caddie is currently empty'] = 'Il cestino è attualente vuoto.';
+$lang['DEMO'] = 'Demo';
+$lang['HOME'] = 'Home Piwigo';
+$lang['FORUM'] = 'Forum';
+$lang['BUGS'] = 'Bugs';
+$lang['EXTENSIONS'] = 'Estensioni';
+$lang['WIKI / DOC'] = 'Documentazione';
+$lang['conf_upload_title'] = 'Upload';
+$lang['Show upload link every time'] = 'Sempre visualizzare il link per aggiungere le immagini';
+$lang['User access level to upload'] = 'Livello d\'accesso utente per l\'upload';
+$lang['ACCESS_0'] = 'Accesso libero';
+$lang['ACCESS_1'] = 'Accesso a tutti';
+$lang['ACCESS_2'] = 'Accesso agli iscritti';
+$lang['ACCESS_3'] = 'Accesso agli amministratori';
+$lang['ACCESS_4'] = 'Accesso agli webmaster';
+$lang['ACCESS_5'] = 'Nessun accesso';
+$lang['A new version of Piwigo is available.'] = 'Una nuova versione di Piwigo è disponibile.';
+$lang['Piwigo Administration'] = 'Amministrazione di Piwigo';
+$lang['Piwigo version'] = 'Versione di Piwigo';
+$lang['You are running the latest version of Piwigo.'] = 'State già usando l\'ultima versione di Piwigo.';
+$lang['c13y_version_anomaly'] = 'La versione di %s [%s] installata non è compatible con la versione richiesta [%s]';
+$lang['c13y_version_correction'] = 'Dovete aggiornare il vostro sistema per potere proffittare pienamente del\'applicazione se no l\'applicazione non funzionera correttamente, o non funzionera per niente';
+$lang['Deleted on'] = 'Cancellato il';
+$lang['Last hit'] = 'Ultimo accesso';
+$lang['Hits'] = 'Uso';
+$lang['GD library is missing'] = 'la biblioteca GD è manquante';
+$lang['conf_extents'] = 'Templates (modelli)';
+$lang['extend_for_templates'] = 'Estendere i templates';
+$lang['Replacement of original templates'] = 'Sostitizione dei templates d\'origine con i vostri templates personalizzati dalla sottodirectory template-extension';
+$lang['Replacers'] = 'Sostituzione (templates personalizzati)';
+$lang['Original templates'] = 'Templates d\'origine';
+$lang['Optional URL keyword'] = 'Parametro facultativo del\'URL';
+$lang['Templates recorded.'] = 'La configurazione dei templates è stata registrata.';
+$lang['Optimizations completed'] = 'Ottimizzazioni realissate correttamente.';
+$lang['Optimizations errors'] = 'Ottimizzazioni concluse con errori.';
+$lang['delete this comment'] = 'cancellare commenti';
+$lang['link_info_image'] = 'Modifica le informazioni';
+$lang['edit category informations'] = 'Modificare le informazioni della categoria';
+$lang['nothing'] = 'niente';
+$lang['overrides existing values with empty ones'] = 'sovrascrivere i valori esistenti con i nuovi anche vuoti';
+$lang['manage image ranks'] = 'gestire l\'ordinamento delle immagini';
+$lang['Manage image ranks'] = 'Gestire l\'ordinamento delle immagini';
+$lang['Edit ranks'] = 'Modificare l\'ordine';
+$lang['No element in this category'] = 'Nessun elemento in questa categoria';
+$lang['Images manual order was saved'] = 'L\'ordinamento manuale delle immagini è stato salvato';
+$lang['ranks'] = 'rangs';
+$lang['Drag to re-order'] = 'Clicca e trascina per riorganizzare';
+$lang['Unable to retrieve server informations since allow_url_fopen is disabled.'] = 'È impossibile connettersi al server perche la funzione allow_url_fopen è disattivata.';
+$lang['Quick Local Synchronization'] = 'Sincronizzazione rapida';
+$lang['No photo can be deleted'] = 'Nessuna foto può essere soppressa';
+$lang['Note: Only deletes photos added with pLoader'] = 'Nota: solo le foto agiunte con pLoader possono essere rimosse';
+$lang['Delete selected photos'] = 'Cancellare le foto';
+$lang['%d photo was deleted'] = '%d foto cancellata';
+$lang['%d photos were deleted'] = '%d foto cancellate';
+$lang['Bound template'] = 'Template legato';
+$lang['Downloads'] = 'Downloads';
+$lang['Released on'] = 'Aggiunto il';
+$lang['Number of downloads'] = 'Totale dei downloads';
+?>
Index: /tags/2.0.2/language/it_IT/common.lang.php
===================================================================
--- /tags/2.0.2/language/it_IT/common.lang.php	(revision 3278)
+++ /tags/2.0.2/language/it_IT/common.lang.php	(revision 3278)
@@ -0,0 +1,368 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Langage informations
+$lang_info['language_name'] = 'Italiano';
+$lang_info['country'] = 'Italia';
+$lang_info['direction'] = 'ltr';
+$lang_info['code'] = 'it';
+$lang_info['zero_plural'] = false;
+
+$lang['%.2f (rated %d times, standard deviation = %.2f)'] = '%.2f (votata %d volte, media = %.2f)';
+$lang['%d Kb'] = '%d Ko';
+$lang['%d category updated'] = '%d categoria aggiornata';
+$lang['%d categories updated'] = '%d categorie aggiornate';
+$lang['%d comment to validate'] = '%d commento utente da approvare';
+$lang['%d comments to validate'] = '%d commenti utente da approvare';
+$lang['%d new comment'] = '%d nuovo commento utente';
+$lang['%d new comments'] = '%d nuovi commenti utente';
+$lang['%d comment'] = '%d commento';
+$lang['%d comments'] = '%d commenti';
+$lang['%d hit'] = 'vista %d volte';
+$lang['%d hits'] = 'viste %d volte';
+$lang['%d new element'] = '%d nuovo elemento';
+$lang['%d new elements'] = '%d nuovi elementi';
+$lang['%d new user'] = '%d nuovo utente';
+$lang['%d new users'] = '%d nuovi utenti';
+$lang['%d waiting element'] = '%d elemento in attesa';
+$lang['%d waiting elements'] = '%d elementi in attesa';
+$lang['About'] = 'Informazioni su...';
+$lang['All tags must match'] = 'Tutti i tags devono corrispondere';
+$lang['All tags'] = 'Tutti i tags';
+$lang['Any tag'] = 'Qualsiasi tag';
+$lang['At least one listed rule must be satisfied.'] = 'Almeno una delle regole elencate deve essere soddisfatta.';
+$lang['At least one tag must match'] = 'Almeno un tag deve corrispondere';
+$lang['Author'] = 'Autore';
+$lang['Average rate'] = 'Voto medio';
+$lang['Categories'] = 'Categorie';
+$lang['Category'] = 'Categoria';
+$lang['Close this window'] = 'Chiudi questa finestra';
+$lang['Complete RSS feed'] = 'Flussi RSS completo (immagini, commenti)';
+$lang['Confirm Password'] = 'Conferma la Password';
+$lang['Connection settings'] = 'Parametri di connessione';
+$lang['Connection'] = 'Connessione';
+$lang['Contact webmaster'] = 'Contattare il webmaster';
+$lang['Create a new account'] = 'Sei un nuovo utente?';
+$lang['Created on'] = 'Creato il';
+$lang['Creation date'] = 'Data di creazione';
+$lang['Current password is wrong'] = 'La password non è esatta';
+$lang['Dimensions'] = 'Dimensioni';
+$lang['Display'] = 'Visualizzazione';
+$lang['Each listed rule must be satisfied.'] = 'Tutti i criteri devono essere soddisfatti';
+$lang['Email address is missing'] = 'Manca l\'indirizzo email';
+$lang['Email address'] = 'Indirizzo email';
+$lang['Enter your personnal informations'] = 'Inserire le informazioni personali';
+$lang['Error sending email'] = 'Errore durante l\'invio dell\'email';
+$lang['File name'] = 'Nome file';
+$lang['File'] = 'File';
+$lang['Filesize'] = 'Dimensione';
+$lang['Filter and display'] = 'Filtra e visualizza';
+$lang['Filter'] = 'Filtro';
+$lang['Forgot your password?'] = 'Password dimenticata ?';
+$lang['Go through the gallery as a visitor'] = 'Visita la galleria come ospite';
+$lang['Help'] = 'Aiuto';
+$lang['Identification'] = 'Identificazione';
+$lang['Image only RSS feed'] = 'Flussi RSS delle immagini';
+$lang['Keyword'] = 'Parola chiave';
+$lang['Links'] = 'Links';
+$lang['Mail address'] = $lang['Email address'];
+$lang['N/A'] = 'N/A';
+$lang['New on %s'] = 'Nuovo il %s';
+$lang['New password confirmation does not correspond'] = 'La conferma della nuova password non corrisponde';
+$lang['New password sent by email'] = 'La nuova password ti è stata inviata via email';
+$lang['No email address'] = 'Nessun indirizzo email';
+$lang['No user matches this email address'] = 'Non esiste nessun utente con questo indirizzo email';
+$lang['Notification'] = 'Notifica';
+$lang['Number of items'] = 'Numero di elementi';
+$lang['Original dimensions'] = 'Dimensioni originali';
+$lang['Password forgotten'] = 'Password dimenticata';
+$lang['Password'] = 'Password';
+$lang['Post date'] = 'Data d\'invio';
+$lang['Posted on'] = 'Inviato il';
+$lang['Profile'] = 'Profilo';
+$lang['Quick connect'] = 'Connessione veloce';
+$lang['RSS feed'] = 'flussi RSS';
+$lang['Rate'] = 'Voto';
+$lang['Register'] = 'Registrati';
+$lang['Registration'] = 'Registrazione';
+$lang['Related tags'] = 'Tags correlati';
+$lang['Reset'] = 'Cancellare';
+$lang['Retrieve password'] = 'Recuperare la password';
+$lang['Search rules'] = 'Criteri di ricerca';
+$lang['Search tags'] = 'Ricercare i tags';
+$lang['Search'] = 'Cerca';
+$lang['See available tags'] = 'Mostra i tags disponibili';
+$lang['Send new password'] = 'Inviare una nuova password';
+$lang['Since'] = 'Dal';
+$lang['Sort by'] = 'Ordina per';
+$lang['Sort order'] = 'Tipo di ordinamento';
+$lang['Tag'] = 'Tag';
+$lang['Tags'] = 'Tags';
+$lang['The RSS notification feed provides notification on news from this website : new pictures, updated categories, new comments. Use a RSS feed reader.'] = 'I flussi RSS informno sulle novità della galleria: nuove immagini, aggiornamento delle categorie, nuovi commenti. Da usarsi con un lettore di flussi RSS.';
+$lang['Unknown feed identifier'] = 'Identificatore di flusso sconosciuto';
+$lang['User comments'] = 'Commenti utenti';
+$lang['Username'] = 'Nome utente';
+$lang['Visits'] = 'Visite';
+$lang['Webmaster'] = 'Webmaster';
+$lang['Week %d'] = 'Settimana %d';
+$lang['about_page_title'] = 'Mostra le informazioni su Piwigo';
+$lang['access_forbiden'] = 'Non sei autorizzato a visualizzare la pagina richiesta';
+$lang['add to caddie'] = 'Aggiungi al cestino';
+$lang['add_favorites_hint'] = 'Aggiungi la pagina ai tuoi preferiti';
+$lang['admin'] = 'Amministrazione';
+$lang['adviser_mode_enabled'] = 'Modo consigliere attivo';
+$lang['all'] = 'tutto';
+$lang['ascending'] = 'ascendente';
+$lang['author(s) : %s'] = 'autore(i) : %s';
+$lang['auto_expand'] = 'Espandi tutte le categorie';
+$lang['became available after %s (%s)'] = 'disponibile dopo il %s (%s)';
+$lang['became available before %s (%s)'] = 'disponibile prima del %s (%s)';
+$lang['became available between %s (%s) and %s (%s)'] = 'disponibile tra %s (%s) e il %s (%s)';
+$lang['became available on %s'] = 'disponibile il %s';
+$lang['best_rated_cat'] = 'Le più votate';
+$lang['best_rated_cat_hint'] = 'Mostra gli elementi i più votati';
+$lang['caddie'] = 'Cestino';
+$lang['calendar'] = 'Calendario';
+$lang['calendar_any'] = 'Tutto';
+$lang['calendar_hint'] = 'Mostra anno per anno, mese per mese, giorno per giorno';
+$lang['calendar_picture_hint'] = 'Mostra le immagini del ';
+$lang['calendar_view'] = 'Vista';
+$lang['chronology_monthly_calendar'] = 'Calendario mensile';
+$lang['chronology_monthly_list'] = 'Lista mensile';
+$lang['chronology_weekly_list'] = 'Lista settimanale';
+$lang['click_to_redirect'] = 'Cliccare qui se non siete reindirizzati automaticamente.';
+$lang['comment date'] = 'data del commento';
+$lang['comment'] = 'Commento';
+$lang['comment_added'] = 'Il vostro commento è stato registrato';
+$lang['comment_anti-flood'] = 'Sistema di sicurezza: attendere prima di aggiungere un nuovo commento';
+$lang['comment_not_added'] = 'Il vostro commento non è stato registrato perchè non rispetta le regole di convalidazione';
+$lang['comment_to_validate'] = 'Un amministratore deve autorizzare il tuo commento affinchè sia visibile.';
+$lang['comment_user_exists'] = 'Questo nome utente esiste già';
+$lang['comments'] = 'Commenti';
+$lang['comments_add'] = 'Aggiunti un commento';
+$lang['created after %s (%s)'] = 'creata dopo il %s (%s)';
+$lang['created before %s (%s)'] = 'creata prima del %s (%s)';
+$lang['created between %s (%s) and %s (%s)'] = 'creata tra il %s (%s) e il %s (%s)';
+$lang['created on %s'] = 'creata il %s';
+$lang['customize'] = 'Personalizza';
+$lang['customize_page_title'] = 'Personalizzare visualizzazione ';
+$lang['day'][0] = 'Domenica';
+$lang['day'][1] = 'Lunedì';
+$lang['day'][2] = 'Martedì';
+$lang['day'][3] = 'Mercoledì';
+$lang['day'][4] = 'Giovedì';
+$lang['day'][5] = 'Venerdì';
+$lang['day'][6] = 'Sabato';
+$lang['default_sort'] = 'Di default';
+$lang['del_favorites_hint'] = 'Cancellare questa immagine dalle vostre preferite';
+$lang['delete'] = 'Cancellare';
+$lang['descending'] = 'discendente';
+$lang['download'] = 'Scaricare';
+$lang['download_hint'] = 'Scaricare questo file';
+$lang['edit'] = 'modificare';
+$lang['err_date'] = 'data errata';
+$lang['excluded'] = 'Escluso';
+$lang['favorite_cat'] = 'Le mie preferite';
+$lang['favorite_cat_hint'] = 'Mostra le mie foto preferite';
+$lang['favorites'] = 'Preferite';
+$lang['first_page'] = 'Primo';
+$lang['gallery_locked_message'] = 'La galleria è chiusa per manutenzione. Tornare più tardi.';
+$lang['generation_time'] = 'Pagina generata in';
+$lang['guest'] = 'ospite';
+$lang['hello'] = 'Ciao';
+$lang['hint_admin'] = 'Disponibile sono per gli amministratori';
+$lang['hint_category'] = 'Mostra le foto alla base di questa categoria';
+$lang['hint_comments'] = 'Mostra gli ultimi commenti degli utenti';
+$lang['hint_customize'] = 'Personalizza l\'aspetto della galleria';
+$lang['hint_search'] = 'Cerca nella galleria';
+$lang['home'] = 'Home';
+$lang['identification'] = 'Identificazione';
+$lang['images_available_cpl'] = 'in questa categoria';
+$lang['images_available_cat'] = 'in %d sottocategoria';
+$lang['images_available_cats'] = 'in %d sottocategorie';
+$lang['included'] = 'incluso';
+$lang['invalid_pwd'] = 'Password non valida !';
+$lang['language'] = 'Lingua';
+$lang['last %d days'] = 'Ultimi %d giorni';
+$lang['last_page'] = 'Ultima';
+$lang['logout'] = 'Logout';
+$lang['mail_address'] = $lang['Email address'];
+$lang['mandatory'] = 'obbligatorio';
+$lang['maxheight'] = 'Altezza massima delle immagini';
+$lang['maxheight_error'] = 'L\'altezza massima deve essere un numero superiore a 50';
+$lang['maxwidth'] = 'Larghezza massima delle immagini';
+$lang['maxwidth_error'] = 'La larghezza massima deve essere un numero superiore a 50';
+$lang['mode_created_hint'] = 'Mostra il calendario per data di creazione';
+$lang['mode_flat_hint'] = 'Mostra gli elementi delle categorie e sottocategorie in modalità flat';
+$lang['mode_normal_hint'] = 'Ritorna alla visualizzazione normale';
+$lang['mode_posted_hint'] = 'Mostra il calendario per data d\'inserimento nella galleria';
+$lang['month'][10] = 'Ottobre';
+$lang['month'][11] = 'Novembre';
+$lang['month'][1] = 'Gennaio';
+$lang['month'][2] = 'Febbraio';
+$lang['month'][3] = 'Marzo';
+$lang['month'][4] = 'Aprile';
+$lang['month'][5] = 'Maggio';
+$lang['month'][6] = 'Giugno';
+$lang['month'][7] = 'Luglio';
+$lang['month'][8] = 'Agosto';
+$lang['month'][9] = 'Settembre';
+$lang['month'][12] = 'Dicembre';
+$lang['most_visited_cat'] = 'Le più viste';
+$lang['most_visited_cat_hint'] = 'Mostra le foto le più viste';
+$lang['nb_image_line_error'] = 'Il numero d\'immagini per riga deve essere un intero non nullo';
+$lang['nb_image_per_row'] = 'Numero d\'immagini per riga';
+$lang['nb_line_page_error'] = 'Il numero di righe per pagina deve essere un intero non nullo';
+$lang['nb_row_per_page'] = 'Numero di righe per pagina';
+$lang['nbm_unknown_identifier'] = 'Identificante sconosciuto';
+$lang['new_password'] = 'Nuova password';
+$lang['new_rate'] = 'Vota questa foto';
+$lang['next_page'] = 'Prossima';
+$lang['no_category'] = 'Home';
+$lang['no_rate'] = 'nessun voto';
+$lang['note_filter_day'] = 'L\'insieme degli elementi sono filtrati per visualizzare solo gli elementi recenti di meno di %d giorno.';
+$lang['note_filter_days'] = 'L\'insieme degli elementi sono filtrati per visualizzare solo gli elementi recenti di meno di %d giorni.';
+$lang['password updated'] = 'password aggiornata';
+$lang['periods_error'] = 'Il periodo deve essere un valore intero positivo';
+$lang['picture'] = 'immagini';
+$lang['picture_high'] = 'Cliccare sull\'immagine per vederla in alta definizione';
+$lang['picture_show_metadata'] = 'Mostrare i metadati del file';
+$lang['powered_by'] = 'Sito realizzato grazie a';
+$lang['preferences'] = 'Preferenze';
+$lang['previous_page'] = 'Precendente';
+$lang['random_cat'] = 'Immagini a caso';
+$lang['random_cat_hint'] = 'Mostra un insieme d\'immagini in modo casuale';
+$lang['recent_cats_cat'] = 'Ultime categorie';
+$lang['recent_cats_cat_hint'] = 'Mostra le categorie recentemente create o aggiornate';
+$lang['recent_period'] = 'Periodo recente';
+$lang['recent_pics_cat'] = 'Ultime immagini';
+$lang['recent_pics_cat_hint'] = 'Mostra le immagini le più recenti';
+$lang['redirect_msg'] = 'Reindirizzamento in corso...';
+$lang['reg_err_login1'] = 'Inserire nome utente, grazie';
+$lang['reg_err_login2'] = 'Il nome utente non deve finire con uno spazio';
+$lang['reg_err_login3'] = 'Il nome utente non deve iniziare con uno spazio';
+$lang['reg_err_login5'] = 'Nome utente già esistente';
+$lang['reg_err_mail_address'] = 'l\'indirizzo email deve essere del tipo xxx@yyy.eee (ad esempio: cippalippa@libero.rio)';
+$lang['reg_err_pass'] = 'Reinserire la password, grazie.';
+$lang['remember_me'] = 'Conessione automatica';
+$lang['remove this tag'] = 'Eliminare tag dalla lista';
+$lang['representative'] = 'rappresentative';
+$lang['return to homepage'] = 'Torna alla homepage';
+$lang['search_author'] = 'Cercare un Autore';
+$lang['search_categories'] = 'Cercare nelle categorie';
+$lang['search_date'] = 'Cercare per data';
+$lang['search_date_from'] = 'data';
+$lang['search_date_to'] = 'Data di fine';
+$lang['search_date_type'] = 'Tipo data';
+$lang['search_keywords'] = 'Cercare le parole';
+$lang['search_mode_and'] = 'Cercare tutte le parole';
+$lang['search_mode_or'] = 'Cercare una delle parole';
+$lang['search_one_clause_at_least'] = 'Selezione vuota. Nessun criterio di ricerca inserito.';
+$lang['search_options'] = 'Opzioni di ricerca';
+$lang['search_result'] = 'Risultato della ricerca';
+$lang['search_subcats_included'] = 'Cercare nelle sottocategorie';
+$lang['search_title'] = 'Cercare';
+$lang['searched words : %s'] = 'parole cercate : %s';
+$lang['send_mail'] = 'Contattare';
+$lang['set as category representative'] = 'Usare immagine come rappresentativa della categoria';
+$lang['show_nb_comments'] = 'Mostrare il numero dei commenti';
+$lang['show_nb_hits'] = 'Mostrare il numero di visualizzazioni';
+$lang['slideshow'] = 'diaporama';
+$lang['slideshow_stop'] = 'fermare il diaporama';
+$lang['special_categories'] = 'Speciale';
+$lang['sql_queries_in'] = 'selezioni SQL in';
+$lang['start_filter_hint'] = 'Mostra solo gli elementi recenti';
+$lang['stop_filter_hint'] = 'ritornare alla visualizzazione di tutti gli elementi';
+$lang['the beginning'] = 'L\'inizio';
+$lang['theme'] = 'Tema dell\'interfaccia';
+$lang['thumbnails'] = 'Miniature';
+$lang['title_menu'] = 'Menu';
+$lang['title_send_mail'] = 'Un commento sul sito';
+$lang['today'] = 'Oggi';
+$lang['update_rate'] = 'Aggiorna il tuo voto';
+$lang['update_wrong_dirname'] = 'nome della directory errata';
+$lang['upload_advise_filesize'] = 'La dimensione del file immagine non deve eccedere: ';
+$lang['upload_advise_filetype'] = 'L\'immagine deve essere in formato jpg, png o gif';
+$lang['upload_advise_height'] = 'L\'altezza dell\'immagine non deve eccedere: ';
+$lang['upload_advise_thumbnail'] = 'Opzionale ma raccomandato: scegliere una miniatura da associare a ';
+$lang['upload_advise_width'] = 'La larghezza dell\'immagine non deve eccedere: ';
+$lang['upload_author'] = 'Autore';
+$lang['upload_cannot_upload'] = 'non è stato possibile caricare il file sul server';
+$lang['upload_err_username'] = 'nome utente obbligatorio';
+$lang['upload_file_exists'] = 'file già esistente';
+$lang['upload_filenotfound'] = 'il formato del file non è un formato immagine';
+$lang['upload_forbidden'] = 'Non è possibile caricare una foto in questa categoria';
+$lang['upload_name'] = 'Nome dell\'immagine';
+$lang['upload_picture'] = 'Caricare un\'immagine';
+$lang['upload_successful'] = 'Immagine caricata con successo. Un amministratore convaliderà l\'operazione il più presto possibile';
+$lang['upload_title'] = 'Caricare un\'immagine';
+$lang['useful when password forgotten'] = 'utile se si dimentica la password';
+$lang['qsearch'] = 'Ricerca rapida';
+$lang['Connected user: %s'] = 'Utente(i) connesso(i): %s';
+$lang['IP: %s'] = 'IP: %s';
+$lang['Browser: %s'] = 'Navigatore: %s';
+$lang['Author: %s'] = 'Autore: %s';
+$lang['Comment: %s'] = 'Commento: %s';
+$lang['Delete: %s'] = 'Sopressione: %s';
+$lang['Validate: %s'] = 'Convalida: %s';
+$lang['Comment by %s'] = 'Commento per %s';
+$lang['User: %s'] = 'Utente: %s';
+$lang['Email: %s'] = 'Email: %s';
+$lang['Admin: %s'] = 'Amministrazione: %s';
+$lang['Registration of %s'] = 'Registrazione di %s';
+$lang['Category: %s'] = 'Categoria: %s';
+$lang['Picture name: %s'] = 'Nome dell\'immagine: %s';
+$lang['Creation date: %s'] = 'Data di creazione: %d';
+$lang['Waiting page: %s'] = 'Pagina in attesa: %s';
+$lang['Picture uploaded by %s'] = 'Immagine caricata da %s';
+// --------- Starting below: New or revised $lang ---- from version 1.7.1
+$lang['guest_must_be_guest'] = 'Lo status del\'utente "guest" non è conforme, viene usato lo status di default. Vogliate avvertire il webmaster.';
+// --------- Starting below: New or revised $lang ---- from Butterfly (1.8)
+$lang['Administrator, webmaster and special user cannot use this method'] = 'Amministratore, webmaster et utente speciale non possono utilizzare questo metodo';
+$lang['reg_err_mail_address_dbl'] = 'un utente usa già questo indirizzo mail';
+$lang['Category results for'] = 'Risultato delle categorie per';
+$lang['Tag results for'] = 'Risultato dei tag per';
+$lang['from %s to %s'] = 'da %s a %s';
+$lang['start_play'] = 'Lettura del diaporama';
+$lang['stop_play'] = 'Pausa del diaporama';
+$lang['start_repeat'] = 'Ricominciare il diaporama';
+$lang['stop_repeat'] = 'Non ricominciare il diaporama';
+$lang['inc_period'] = 'Ralentare la velocità del diaporama';
+$lang['dec_period'] = 'Accelerare la velocità del diaporama';
+$lang['Submit'] = 'Confermare';
+$lang['Yes'] = 'Si';
+$lang['No'] = 'No';
+$lang['%d element']='%d immagine';
+$lang['%d elements']='%d immagini';
+$lang['%d element are also linked to current tags'] = '%d immagine è anche connessa ai tag correnti';
+$lang['%d elements are also linked to current tags'] = '%d immagini sono anche connesse ai tag correnti';
+$lang['See elements linked to this tag only'] = 'Mostrare le immagini connesse solo a questo tag';
+$lang['elements posted during the last %d days'] = 'immagini aggiunte durante gli ultimi %d giorni';
+$lang['Choose an image'] = 'Scegliere un immagine da aggiungere';
+$lang['Piwigo Help'] = 'Help di Piwigo';
+$lang['Rank'] = 'Rang';
+$lang['group by letters'] = 'ragruppare per lettera';
+$lang['letters'] = 'lettere';
+$lang['show tag cloud'] = 'fare salire la nuvola di tags';
+$lang['cloud'] = 'nuvola';
+?>
Index: /tags/2.0.2/language/it_IT/help.html
===================================================================
--- /tags/2.0.2/language/it_IT/help.html	(revision 3278)
+++ /tags/2.0.2/language/it_IT/help.html	(revision 3278)
@@ -0,0 +1,325 @@
+<div class="instructions">
+<h2>Aiuto</h2>
+
+<div id="instructionPLoader" class="instructionBlock">
+  <div
+    id="pLoader_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('pLoader_header', 'pLoader_content')"
+  ><span>
+    Aggiungere delle foto con pLoader
+  </span></div>
+  <div
+    id="pLoader_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+    <p><a href="http://piwigo.org/ext/extension_view.php?eid=270&lang=it">pLoader per Windows</a> o <a href="http://piwigo.org/ext/extension_view.php?eid=269&lang=it">pLoader per Linux</a> : descrizione, download e i dettagli delle nuove versioni.</p>
+    <ol>
+	  <li>Create una directory "upload" a fianco della directory "galleries" della vostra installazione di Piwigo, con dei diritti di scrittura.</li>
+      <li>Installate pLoader sul vostro PC, avviatelo e riempite i parametri di conessione : URL della vostra galleria, il vostro utente e la vostra password	.</li>
+      <li>Aggiungete delle foto con un semplice drag'n drop verso la selezione di pLoader.</li>
+      <li>Create una categoria e selezionatela.</li>
+      <li>Selezionate qualche foto.</li>
+      <li>Cliccare sulla freccia verde per trasferire le foto verso la vostra galleria</li>
+    </ol>
+	<p>Bravo! Avete appena creato la prima categoria della vosrta galleria.</p>
+  </div> <!-- pLoader_content -->
+</div> <!-- instructionPLoader -->
+
+<div id="instructionFTP" class="instructionBlock">
+  <div
+    id="FTP_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('FTP_header', 'FTP_content')"
+  ><span>
+    Aggiungere delle foto con l'FTP
+  </span></div>
+  <div
+    id="FTP_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+
+<h3>Presa in mano rapida</h3>
+
+<ol>
+  <li>Create una directory sul vostro PC.</li>  
+  <li>Copiate qualche foto in questa directory, e ridimenzionatele per la visualizzazione sul web. <em>Attenzione</em>: il nome delle directories e dei files deve contenere solo delle lettre, cifre e i caratteri "-", "_" o ".". Nessuno sazio o caratteri accentuati.</li>
+  <li>Con un cliente FTP, copiate la directory in nella directory "galleries" del vostro Piwigo.</li>
+  <li>Connettetevi alla vostra galleria e andate a <span class="pwgScreen">Amministrazione &raquo; Immagini &raquo; Miniature</span> per creare le miniature mancanti.</li>
+  <li>Andare a <span class="pwgScreen">Amministrazione</span> e cliccare sul grosso pulzante Sincronizzazione.</li>
+</ol>
+
+<p>Bravo! Avete appena creato la prima categoria della vosrta galleria.</p>
+
+<h3>Organizzazione delle directories e dei files</h3>
+
+<ul>
+
+  <li>
+
+    <p>Nella directory "galleries" si trovano le categorie di Piwigo.
+Qui di seguito potete vedere lo schema di un albero di una piccola galleria
+(ma che usa moltissime funzionalità:</p>
+  
+<pre>
+.
+|-- admin
+|-- doc
+|-- galleries
+|   |-- categoria-1
+|   |   |-- categoria-1.1
+|   |   |   |-- categoria-1.1.1
+|   |   |   |   |-- categoria-1.1.1.1
+|   |   |   |   |   |-- pwg_high
+|   |   |   |   |   |   +-- matrimonio.jpg
+|   |   |   |   |   |-- thumbnail
+|   |   |   |   |   |   +-- TN-matrimonio.jpg
+|   |   |   |   |   +-- matrimonio.jpg
+|   |   |   |   +-- categoria-1.1.1.2
+|   |   |   +-- categoria-1.1.2
+|   |   |-- categoria-1.2
+|   |   |   |-- pookie.jpg
+|   |   |   +-- thumbnail
+|   |   |       +-- TN-pookie.jpg
+|   |   +-- categoria-1.3
+|   +-- categoria-2
+|       |-- porcello.gif
+|       |-- pwg_representative
+|       |   +-- video.jpg
+|       |-- thumbnail
+|       |   +-- TN-porcello.jpg
+|       +-- video.avi
+|-- include
+|-- install
+|-- language
+|-- template
++-- tool</pre>
+
+  </li>
+  
+  <li>In linea di massima, una categoria è rappresentata da una directory
+che si trova a qualsiasi livello della directory "galleries" di
+Piwigo. Ogni categoria può contenere altretanti sottolivelli che
+si desidera. Nell'esempio qui sopra, categoria-1.1.1.1 si trova al 4 livello
+di profondità.</li>
+
+  <li>Un elemento è invece rappresentato da un file. Un file può essere un
+elemento di Piwigo se la sua estensione è tra quelle previste tra
+le possibilità previste nel parametro di configuarzione <code>file_ext</code>
+(vedi file <span class="filename">include/config_default.inc.php</span>).
+Un file è considerato come un immagine se la sua estensione si trova tra
+quelle previste nel file <code>picture_ext</code>.</li>
+
+  <li>Ogni elemento di tipo immagine deve essere associato ad una miniatura
+(vedi la sezione più in basso riguardante le miniature)</li>
+
+  <li>Gli elementi di tipo immagine possono avere un'immagine associata
+in alta qualità. Come per il file <span class="filename">matrimonio.jpg</span>
+nell'esempio proposto. Nessun prefisso è necessario prima del nome del
+file.</li>
+
+  <li>Gli elementi che non sono delle immagini (video, suoni, file di testo o
+quant'altro...) sono generalmente rappresentati con un'icona corrispondente
+all'estensione del file. In modo opzionale è possibile associare una miniatura
+e un file rappresentativo (come per il file <span class="filename">video.avi</span>
+nell'esempio proposto).</li>
+
+  <li><em>Attenzione</em>: il nome delle directory o del file deve essere
+composto da lettere, numeri o caratteri come "-", "_" o ".". Nessuno spazio
+ne caratteri con gli accenti.</li>
+
+  <li><em>Consiglio</em>: una categoria può contenere elementi e
+sottocategorie nello stesso tempo. Ad ogni modo è altamente consigliato di
+scegliere per ciascuna categoria quelle che contengono elementi <strong>e</strong>
+quelle che invece contengono sottocategorie.</li>
+
+  <li>Una volta che i file, le miniature e i file rappresentativi sono
+correttamente piazzati nelle directory, andare nello schermo <span
+class="pwgScreen">Amministrazione &raquo; Generale &raquo; Sincronizza</span>.</li>
+
+</ul>
+
+<h3>Miniature</h3>
+
+<ul>
+
+  <li>Come detto prima, ciascun elemento immagine deve essere associato
+ad una miniatura.</li>
+
+  <li>Le miniature si trovano nella sottodirectory "thumbnail" di ogni
+directory che rappresenta una categoria. La miniatura è un file di tipo
+immagine (stesso nome del file) con un prefisso che può essere
+personalizzato dal parametro di configurazione <code>prefix_thumbnail</code>
+(vedi <span class="filename">include/config.inc.php</span>).</li>
+
+  <li>Non è necessario che le miniature abbiano la stessa estensione
+dell'immagine che rappresenta (per esempio, un'immagine ".JPG" può avere
+come miniatura un'immagine ".GIF").</li>
+
+  <li>È altamente consigliato di usare un software esterno per la
+creazione delle miniature.</li>
+
+  <li>È anche possibile usare la creazione delle miniature integrata a
+Piwigo, ma ciò non è raccomandato in quanto la qualità delle miniature
+può essere scadente ed il processo potrebbe utilizzare troppe risorse del
+server (ciò può essere un problema per un servizio di web hosting gratuito.</li>
+
+  <li>Se decidete comunque di usare il server per la creazione
+delle miniature è necessario dare i diritti di scrittura su tutte
+le directory.</li>
+
+</ul>
+  </div> <!-- FTP_content -->
+</div> <!-- instructionFTP -->
+
+<div id="instructionPermissions" class="instructionBlock">
+  <div
+    id="permissions_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('permissions_header', 'permissions_content')"
+  ><span>
+    Permessi
+  </span></div>
+  <div
+    id="permissions_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+
+<ul>
+
+  <li>Potete vietare l'accesso alle categorie. Settate il tipo d'accesso a "privato" se desiderate gestire i permessi</li>
+
+  <li>Potete rendere una categoria privata modificandola da <span
+class="pwgScreen">Amministrazione &raquo; Categorie &raquo; Gestire &raquo; Modificare</span>
+o selezionando l'opzione nell'albero delle categorie <span
+class="pwgScreen">Amministrazione &raquo; Categorie &raquo; Proprietà &raquo; Pubblica/Privata</span>).</li>
+
+  <li>
+    <p>Una volta che certe categorie sono private, potete gestire i
+permessi da 3 schermi:</p>
+    <ul>
+      <li><span class="pwgScreen">Amministrazione &raquo; Identificazione &raquo; Utenti &raquo; azione Permessi</span> (un' link per utente)</li>
+      <li><span class="pwgScreen">Amministrazione &raquo; Identificazione &raquo; Gruppi &raquo; azione Permessi</span> (un' link per gruppo)</li>
+      <li><span class="pwgScreen">Amministrazione &raquo; Categorie &raquo; Gestire &raquo; Modificare i permessi</span> (un' link per categoria)</li>
+    </ul>
+
+  </li>
+
+</ul>
+  </div> <!-- permissions_content --> 
+</div> <!-- instructionPermissions -->
+
+<div id="instructionGroups" class="instructionBlock">
+  <div
+    id="groups_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('groups_header', 'groups_content')"
+  ><span>
+    Utenti e gruppi
+  </span></div>
+  <div
+    id="groups_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+<ul>
+
+  <li>I gruppi d'utenti permettono di dare dei permessi ad una lista di utenti.</li>
+
+  <li>È possibile creare gruppi in
+<span class="pwgScreen">Amministrazione &raquo; Identificazione &raquo; Gruppi</span>.</li>
+
+  <li>Un utente può appartenere a diversi gruppi. L'autorizzazione è prioritaria rispetto
+alla proibizione. Ad esempio se l'utente "pippo" appartiene ai gruppi "famiglia" e "amici"
+e, tra questi gruppi, solo il gruppo "famiglia" può vedere la categoria "Natale 2008",
+ne consegue che l'utente "pippo" sarà abilitato a visionare la categoria "Natale 2008".</li>
+
+</ul>
+  </div> <!-- groups_content --> 
+</div> <!-- instructionGroups -->
+
+<div id="instructionUpload" class="instructionBlock">
+  <div
+    id="upload_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('upload_header', 'upload_content')"
+  ><span>
+    Immagini caricate dagli utenti
+  </span></div>
+  <div
+    id="upload_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+<p>Gli utenti possono anche loro caricare le loro foto.</p>
+
+<ol>
+
+  <li>Autorizare l'upload su una o più categorie fisiche (<span
+class="pwgScreen">Amministrazione &raquo; Categorie &raquo; Gestire &raquo; Modificare</span> o <span
+class="pwgScreen">Amministrazione &raquo; Categorie &raquo; Proprietà &raquo; Caricare</span>). Le categorie virtuali non permettono l'upload.</li>
+
+  <li>dare i diritti di scrittura (per tutti gli utenti) sulle directory
+delle categorie autorizzate a l'aggiunta dei file</li>
+</ol>
+
+  <p>Le foto aggiunte dagli utenti non sono direttamente visibili
+sul sito. Devono essere convalidate da un amministratore. Per ciò,
+un'amministratore deve andare in <span class="pwgScreen">Amministrazione &raquo; Immagini &raquo; In attesa &raquo; Immagini</span> per approvare o scartare le immagini proposte</p>
+
+  </div> <!-- upload_content --> 
+</div> <!-- instructionUpload -->
+
+<div id="instructionCategoryLinks" class="instructionBlock">
+  <div
+    id="categoryLinks_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('categoryLinks_header', 'categoryLinks_content')"
+  ><span>
+    Collegamenti tra elementi e categorie e le categorie virtuali
+  </span></div>
+  <div
+    id="categoryLinks_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+
+<ul>
+  <li>Le foto sono visualizzate nella categoria corrispondente alla directory.</li>
+  <li>Potete anche visualizzare una foto in più di una categoria, senza dupplicare il file. Associate la foto a un'altra o più categorie d'allo schermo di modifica della foto (al quale acedete dalla pagina di visualizzazione della foto della vostra galleria, quando siete connessi come amministratore).</li>
+  <li>Le categorie virtuali nascono da questo principio : non sono associati a nessuna directory fisica. Create delle categorie virtuali in <span class="pwgScreen">Amministrazione &raquo; Categorie &raquo; Gestire</span>.</li>
+</ul>
+  </div> <!-- categoryLinks_content --> 
+</div> <!-- instructionCategoryLinks -->
+
+<div id="instructionMisc" class="instructionBlock">
+  <div
+    id="misc_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('misc_header', 'misc_content')"
+  ><span>
+    Informazioni
+  </span></div>
+  <div
+    id="misc_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+
+<ul>
+
+  <li>Dopo aver creato la Vostra galleria, modificatene le proprietà
+di visualizzazione di default da <span class="pwgScreen">Amministrazione &raquo; Configurazione &raquo; Visualizzazione di default</span>. In questo modo
+ogni nuovo utente visualizzerrà la galleria con queste stesse impostazioni.</li>
+
+   <li>Se avedte delle domande, la comunità di Piwigo sarà lieta di rispondere sul'<a
+  href="http://it.piwigo.org/forum">forum</a>.</li>
+
+</ul>
+  </div> <!-- misc_content --> 
+</div> <!-- instructionMisc -->
+
+</div>
Index: /tags/2.0.2/language/it_IT/help/advanced_feature.html
===================================================================
--- /tags/2.0.2/language/it_IT/help/advanced_feature.html	(revision 3278)
+++ /tags/2.0.2/language/it_IT/help/advanced_feature.html	(revision 3278)
@@ -0,0 +1,16 @@
+<h2>Caratteristiche avanzate</h2>
+
+<p>Lista delle funzionalità speciali per gli amministratori esperti di PWG:</p>
+
+<ul>
+
+  <li>
+    <strong>Elementi non collegati:</strong>
+    Mostrare le immagini che non sono associate a una categoria virtuale.
+  </li>
+  <li>
+    <strong>File con lo stesso nome in più di una categoria fisica:</strong>
+    Mostrare le immagini o qualunque file trovati con lo stesso nome in più categorie.
+  </li>
+
+</ul>
Index: /tags/2.0.2/language/it_IT/help/cat_modify.html
===================================================================
--- /tags/2.0.2/language/it_IT/help/cat_modify.html	(revision 3278)
+++ /tags/2.0.2/language/it_IT/help/cat_modify.html	(revision 3278)
@@ -0,0 +1,145 @@
+<h2>Modificare una categoria</h2>
+
+<h3>Informazioni</h3>
+
+<ul>
+
+  <li><strong>nome</strong>: rinominare la categoria (virtualmente per 
+  una categoria fisica).</li>
+
+  <li><strong>descrizione</strong>: dare un'idea generale del contenuto,
+  questo testo apparirà in fondo della pagina delle miniature.</li>
+
+</ul>
+
+<h3>Muover</h3>
+
+<p>Se la categoria è virtuale, potete spostarla. Muovere una categoria
+significa cambiarne la categoria parente.</p>
+
+<h3>Opzioni</h3>
+
+<ul>
+
+  <li><strong>Tipo di accesso</strong>: Gestione dei permessi. Se rendete 
+una categoria privata, tutte le categorie figlie diventono private. Se rendete 
+una categoria pubblica, tutte le categorie parenti diventono pubbliche.</li>
+
+  <li><strong>Blocco</strong>: Per causa di manutenzione, le categorie e tutte 
+le sottocategorie diventano temporaneamente inaccessibili.</li>
+
+  <li><strong>Commenti</strong>: Autorizzare gli utenti a commentare 
+gli elementi della categoria.</li>
+
+  <li><strong>Autorizzare l'upload</strong>: Autorizzare gli utenti
+a caricare dei file. Questa opzione è disponibile solo se la categoria è 
+una categoria fisica (non virtuale).</li>
+
+</ul>
+
+<p>Potete anche gestire queste opzioni con la gestione delle "Proprietà"
+(schermo <span class="pwgScreen">Upload</span>, <span
+class="pwgScreen">Commenti</span>, <span
+class="pwgScreen">Blocco</span>, <span
+class="pwgScreen">Pubblico/Privato</span>, <span
+class="pwgScreen">Rappresentativa</span> disponibile in <span
+class="pwgScreen">Amministrazione, Categorie, Proprietà</span>).</p>
+
+<h3>Ordine di apparizione</h3>
+
+<p>Scegliere se il tipo di ordinamento predefinito sarà usato.</p>
+
+<p>Indicare se quest'ordinamento sarà applicato alle sottocategorie.</p>
+
+<p>Scegliere le colonne per l'ordinamento da usare su questa categoria.</p>
+<ul>
+<li><strong>Data di creazione</strong>: Data di creazione dell'immagine</li>
+<li><strong>Aggiunto il</strong>: Data di sincronizzazione</li>
+<li><strong>Voto medio (*)</strong>: Voto che potrebbe essere modificato da un utente</li>
+<li><strong>Le più viste (*)</strong>: La visita in corso potrebbe modificare l'ordine delle più viste</li>
+<li><strong>Nome file</strong>: Nome inserito nei campi precedenti</li>
+<li><strong>Id</strong>: Id interno(le categorie le più recenti hanno un "Id" più grande delle precedenti.</li>
+
+</ul>
+<p><strong>(*)</strong>Attenzione: Effettuare qualche test, l'ordinamento scelto potrebbe darvi qualche sorpresa.</p>
+
+
+<h3>Rappresentante</h3>
+
+<p>Il rappresentante di una categoria è la miniatura che appare
+per rappresentare la categoria sulla pagina principale (<span
+class="pwgScreen">category.php</span>) quando la categoria contine solo 
+delle sottocategorie e non direttamente delle immagini(come alla radice).</p>
+
+<p>Esistono quattro modi per scegliere il rappresentante di una categoria:</p>
+
+<ul>
+
+  <li><span class="pwgScreen">Pagina di visualizzazione delle immagini</span>: nella barra delle azioni,
+  uno dei pulsanti permette di scegliere l'elemento visualizzato come rappresentante
+  per la categoria visualizzata. Il pulsante in questione è visibile solo agli
+  amministratori.</li>
+
+  <li><span class="pwgScreen">Modicare le informazioni di un'immagine</span> in
+  amministrazione. Questo schermo può essere raggiunto tramite <span
+  class="pwgScreen">picture.php</span> o <span class="pwgScreen">Gestione per
+  lotti</span> con il <em>modo unitario</em>. Per i dettagli, vedi l'aiuto
+  per questa schermata.</li>
+
+  <li><span class="pwgScreen">Amministrazione, Categorie, Proprietà
+  Rappresentante</span>. Per i dettagli, vedi l'aiuto per questa schermata.</li>
+
+  <li><span class="pwgScreen">Modificare categoria</span> (questa schermata).</li>
+
+</ul>
+
+<p>Il rappresentante dipende dal parametro di configurazione
+<code>allow_random_representative</code> (vedi <span
+class="filename">include/config_default.inc.php</span>).</p>
+
+<p>Di default (<code>allow_random_representative</code> a false) ogni
+categoria, contenente almeno un elemento, è rappresentata da un elemento fisso.
+Una volta fissato (alla creazione della categoria), il rappresentante cambia
+solo se lo decide l'amministratore. Se il rappresentante non vi conviene,
+potete chiedere di <strong>Trovare un rappresentante a caso</strong>.</p>
+
+<p>Se il parametro di configurazione <code>allow_random_representative</code>
+e a vero, una categoria contenente degli elementi può non avere un rappresentante
+fisso. Usare semplicemente il pulsante <strong>Cancellare
+rappresentante</strong>.</p>
+
+<p>Se la categoria non contiene nessun elemento (ma solo sottocategorie)
+può comunque essere rappresentata da un qualsiasi elemento. Per ciò usare
+la schermata <span class="pwgScreen">Modicare le informazioni di
+un'immagine</span>. L'unica opzione di questa schermata è il pulsante
+<strong>Cancellare rappresentante</strong>.</p>
+
+<h3>Associare tutti gli elementi di una categoria ad una nuova categoria</h3>
+
+<ul>
+
+<li><strong>Nome della categoria virtuale</strong>: Nome della nuova categoria da creare, 
+tutti gli elementi dell'attuale categoria verranno associati alla nuova categoria.</li>
+
+<li><strong>Categoria madre</strong>: Là dove deve essere creata la nuova categoria, 
+lasciare vuoto per crearla alla radice del sito (nella "Home page").</li>
+
+</ul>
+
+<h3>Associare tutti gli elementi della categoria attuale a delle categorie esistenti</h3>
+
+<ul>
+
+<li><strong>Categorie</strong>: Scegliere la categoria di destinazione.</li>
+
+</ul>
+
+<h3>Inviare un'email d'informazione ai membri del gruppo</h3>
+
+<ul>
+
+<li><strong>Gruppo</strong>: Gruppo dei destinatari</li>
+
+<li><strong>Contenuto dell'email</strong>: Testo libero da mandare.</li>
+
+</ul>
Index: /tags/2.0.2/language/it_IT/help/cat_move.html
===================================================================
--- /tags/2.0.2/language/it_IT/help/cat_move.html	(revision 3278)
+++ /tags/2.0.2/language/it_IT/help/cat_move.html	(revision 3278)
@@ -0,0 +1,15 @@
+<h2>Spostare le categorie virtuali</h2>
+
+<p>Potete cambiare la categoria madre di una categoria virtuale.</p>
+
+<h3>Categoria virtuale da spostare</h3>
+
+<p>Selezionare una o più categorie virtuali da spostare. 
+Se la lista è vuota, ciò vuole dire che non ne avete ancora creata una.</p>
+
+<h3>Nuova categoria madre</h3>
+
+<p>Selezionare una nuova categoria madre (virtuale o fisica). 
+Se non ne selezionate nessuna, 
+le categorie da spostare verranno inserite alla radice del sito.
+Non potete spostare una categoria verso se stessa o verso una propria sottocategoria.</p>
Index: /tags/2.0.2/language/it_IT/help/cat_options.html
===================================================================
--- /tags/2.0.2/language/it_IT/help/cat_options.html	(revision 3278)
+++ /tags/2.0.2/language/it_IT/help/cat_options.html	(revision 3278)
@@ -0,0 +1,40 @@
+<h2>Opzioni delle categorie</h2>
+
+<p>Gestione delle opzioni di più categorie alla volta.</p>
+
+<dl>
+
+  <dt>Upload</dt>
+
+  <dd>Permettere l'upload sulle categorie. Questa opzione non è disponibile 
+per le categorie virtuali e le categorie con accesso remoto.</dd>
+
+  <dt>Commenti</dt>
+
+  <dd>Permettere agli utenti di aggiungere dei commenti nelle categorie selezionate.
+È possibile aggiungere un commento ad un'immagine se qusta si trova in una categoria
+dove i commenti sono autorizzati.</dd>
+
+  <dt>Bloccare</dt>
+
+  <dd>Le categorie selezionate sono temporaneamente bloccate per lavori di manutenzione. 
+Se una categoria è bloccata per manutenzione, tutte le sottocategorie sono a loro volta 
+bloccate. Se una categoria è sbloccata, tutte le categorie madri vengono sbloccare.</dd>
+
+  <dt>Pubblica / privata</dt>
+
+  <dd>Gestione dello statuto delle categorie. La gestione dei permessi è possibile 
+solo sulle categorie private. Una volta resa una categoria privata, dovete in modo 
+specifico autorizzare gli utenti o i gruppi ad accedervi. Se una categoria è privata, 
+tutte le sottocategorie sono a loro volta private. Se una categoria è pubblica, 
+tutte le categorie madri diventono pubbliche.</dd>
+
+  <dt>Rappresentante</dt>
+
+  <dd>Questa opzione è disponibile solo se il parametro di configurazione
+<code>allow_random_representative</code> (vedi <span
+class="filename">include/config_defaults.inc.php</span>) è a 
+<em>true</em>. Ogni categoria può essere rappresentata da un'unica miniatura
+fissa scelta a caso.</dd>
+
+</dl>
Index: /tags/2.0.2/language/it_IT/help/cat_perm.html
===================================================================
--- /tags/2.0.2/language/it_IT/help/cat_perm.html	(revision 3278)
+++ /tags/2.0.2/language/it_IT/help/cat_perm.html	(revision 3278)
@@ -0,0 +1,15 @@
+<h2>Gestire i permessi per una categoria</h2>
+
+<p>Questo schermo è disponibile soltanto per le categorie private. 
+Qui potete scegliere gli utenti e i gruppi autorizzati per questa 
+categoria.</p>
+
+<h3>Gruppi</h3>
+
+<p>Potete negare o concedere l'accesso ai gruppi. Modificando le 
+autorizzazioni ai gruppi, modificherete probabilmente l'elenco degli 
+utenti autorizzati grazie all'appartenenza ai gruppi. </p>
+
+<h3>Utenti</h3>
+
+<p>Potete negare o concedere l'accesso agli utenti individualmente.</p>
Index: /tags/2.0.2/language/it_IT/help/configuration.html
===================================================================
--- /tags/2.0.2/language/it_IT/help/configuration.html	(revision 3278)
+++ /tags/2.0.2/language/it_IT/help/configuration.html	(revision 3278)
@@ -0,0 +1,126 @@
+<h2>Configurazione</h2>
+
+<p>Questo schermo permette di gestire la configurazione di base. 
+Infatti, questo schermo mostra soltanto i parametri che dovrebbero 
+bastare per la maggiore parte degli amministratori. Se volete 
+vedere gli altri numerosi parametri di configurazione, leggete il file <span
+class="filename">include/config_default.inc.php</span>.</p>
+
+<p>Questo schermo è diviso in diverse sezioni, raggruppando i parametri 
+di configurazione per tema.</p>
+
+<h3>Principale</h3>
+<ul>
+
+  <li><strong>Titolo della galleria</strong>: usato per i flussi RSS e 
+la notifica via email.</li>
+
+  <li><strong>Banner delle pagine</strong>: Codilce HTML presente in alto
+su tutte le pagine.</li>
+
+  <li><strong>URL della galleria</strong>: usato per i flussi RSS.</li>
+
+  <li><strong>Blocco galleria</strong>: Bloccare la galleria per 
+la manutenzione. Solo gli amministratori avranno accesso alla galleria.</li>
+
+  <li><strong>Voto</strong>: Il voto delle immagini è possibile.</li>
+
+  <li><strong>Voto degli utenti</strong>: Anche gli ospiti (utenti non registrati)
+possono dare un voto alle immagini.</li>
+
+  <li><strong>Notificare gli amministratori quando un nuovo utente si iscrive</strong>: Gli amministratori vengono avvisati ad ogni nuovo iscritto.</li>
+
+  <li><strong>Autorizzare l'iscrizione di nuovi utenti</strong>: Iscrizione libera per tutti.</li>
+
+  <li><strong>Notificare agli amministratori quando un'immagine è caricata</strong>: Gli amministratori verranno avvisati della messa a disposizione di una nuova immagine.</li>
+
+</ul>
+
+<h3>Cronologia</h3>
+
+  <p>le visite delle pagine <span
+class="pwgScreen">category.php</span> e <span
+class="pwgScreen">picture.php</span> sono
+registrate nella tabella <code>history</code> table.</p>
+  
+  <p>Le visite sono visualizzate nello schermo <span class="pwgScreen">Amministrazione, Speciale, Cronologia</span>.</p>
+
+<ul>
+  <li><strong>Registrare le pagine visitate dagli ospiti</strong>: le pagini visitate dagli ospiti sono registrate.</li>
+
+  <li><strong>Registrare le pagine visitate dagli utenti</strong>: le pagini visitate dagli utenti sono registrate.</li>
+
+  <li><strong>Registrare le pagine visitate dagli amministratori</strong>: le pagini visitate dagli amministratori sono registrate.</li>
+
+</ul>
+
+<h3>Commenti</h3>
+<ul>
+
+  <li><strong>Commenti utenti per tutti</strong>: anche gli ospiti 
+possono registrare i commenti.</li>
+
+  <li><strong>Numero di commenti utente per pagina</strong>.</li>
+
+  <li><strong>Convalida</strong>: un amministratore deve autorizzare 
+i commenti utenti prima che questi possano essere visibili nella parte pubblica. 
+La convalida dei commenti utente avviene nello schermo <span 
+class="pwgScreen">Amministrazione, Immagini, Commenti</span>.</li>
+
+  <li><strong>Notificare agli amministratori quando un commento è registrato</strong>:
+Invio di un'email agli amministratori quando un utente registra un commento.</li>
+
+  <li><strong>Notificare agli amministratori quando un commento richiede la convalida</strong>:
+Invio di un'email agli amministratori quando un utente registra un commento che necessita la convalida.
+La convalida dei commenti utente ha luogo nello schermo <span class="pwgScreen">Amministrazione, Immagine, Commenti</span>.</li>
+
+</ul>
+
+<h3>Visualizzazione di default</h3>
+<p>Modificare le opzioni di visualizzazione di default per gli utenti non 
+collegati. Una volta effettuato il collegamento, queste opzioni sono personalizzabili 
+(modificabile su <span class="pwgScreen">profilo</span>).</p>
+
+<p>È possibile cambiare le impostazioni per gli utenti esistenti,
+in quest'altro schermo: <span class="pwgScreen">Amministrazion,
+Identificazione, Utenti</span>, dove potete cambiare le impostazioni 
+degli utenti.</p>
+
+<ul>
+
+  <li><strong>Lingua</strong>: Solo per i titoli della galleria.
+Le categorie, nome delle immagini e descrizioni non sono compresi
+nella traduzione.</li>
+
+  <li><strong>Numero d'immagini per riga</strong></li>
+
+  <li><strong>Numero di righe per pagina</strong></li>
+
+  <li><strong>Tema dell'interfaccia</strong></li>
+
+  <li><strong>Periodo recente</strong>: in giorni. Periodo durante il quale
+un'immagine è considerata come recente. Questo periodo deve essere superiore
+a 1 giorno.</li>
+
+  <li><strong>Espandere le categorie</strong>: Espandere di default tutte
+le categorie nel menu? <em>Attenzion</em>: questa opzione è consumatrice
+di risorse se avete molte categorie e sottocategorie.</li>
+
+  <li><strong>Mostrare il numero di commenti</strong>: Mostrare il numero
+di commenti sotto ogni miniatura. Consuma delle risorse.</li>
+
+  <li><strong>Mostrare il numero di visite</strong>: visualizza il numero 
+di visualizzazioni del immagine sotto la miniatura. 
+Valido solo se il parametro è : <br />
+$conf['show_nb_hits'] = true; <br />
+N.B.: Di default il parametro è a false.</li>
+
+  <li><strong>Larghezza massima delle immagini</strong>: di visualizzazione.
+Se l'immagine è più larga, allora quest'ultima verra ridimensionata.
+Se pensate che sia necessario cambiare questo parametro allora sarebbe meglio
+ridimensionare le immagini.</li>
+
+  <li><strong>Altezza massima delle immagini</strong>: stessi consigli che
+la voce precedente.</li>
+
+</ul>
Index: /tags/2.0.2/language/it_IT/help/extend_for_templates.html
===================================================================
--- /tags/2.0.2/language/it_IT/help/extend_for_templates.html	(revision 3278)
+++ /tags/2.0.2/language/it_IT/help/extend_for_templates.html	(revision 3278)
@@ -0,0 +1,100 @@
+<h2>Configurazione per "l'estenzione" dei templates</h2>
+
+<h3>Scopo</h3>
+<p>Definire le condizioni di sostituzione per ogni template (modello) dalla directory template-extension
+(template chiamato il "replacer" (rimpiazzante)).</p>
+
+<p>I "templates originali" da ./template/yoga (o qualunque altra directory che yoga) sarà sostituito 
+da un rimpiazzante se quest'ultimo è collegato al "template originale" (e in modo facoltativo, 
+quando l'URL richiesta contiene un "parametro facoltativo dell'URL").</p>
+
+<p>I "parametri facoltativi dell'URL" sono quelli che potete trovare dopo il nome del modulo nel indirizzo (URL).</p>
+
+<p>Quindi un "parametro facoltativo dell'URL" può essere un "permalink" attivo (per maggiore informazioni 
+vedere i permalinks della nostra documentazione).</p>
+
+<p>Leggere: `<a href="#warnings">Avvertimenti</a> sulle condizioni d'uso.</p>
+
+<h3>Che cosa sono le estensioni dei template?</h3>
+
+<p>Quest'attrezzo di configurazione è potente per i principianti ma anche per gli esperti.
+Trammite FTP, nella directory template-estensione, il Webmaster può duplicare i file .tpl 
+("template originali") con un nome diverso (rimpiazzante).
+
+ "Template originali", attualmente i modelli d'origine sopportati sono:</p>
+<ul>
+  <li><span class="filename">index.tpl</span></li>
+  <li><span class="filename">mainpage_categories.tpl</span> e/o <span class="filename">thumbnails.tpl</span></li>
+  <li><span class="filename">menubar.tpl</span></li>
+  <li><span class="filename">header.tpl</span> e/o <span class="filename">footer.tpl</span></li>
+  <li><span class="filename">picture_content.tpl</span> e/o <span class="filename">picture.tpl</span></li>
+  <!-- <li><span class="filename">slideshow.tpl</span></li> -->
+  <li><span class="filename">profile.tpl</span> e/o <span class="filename">profile_content.tpl</span></li>
+  <li><span class="filename">tags.tpl</span></li>
+  <li><span class="filename">upload.tpl</span></li>
+  <li><span class="filename">about.tpl</span></li>
+  <li><span class="filename">popuphelp.tpl</span>	</li>
+  <li><span class="filename">search.tpl</span> e/o <span class="filename">search_rules.tpl</span></li>
+  <li><span class="filename">nbm.tpl</span> e/o <span class="filename">notification.tpl</span></li>
+  <li><span class="filename">identification.tpl</span> e/o <span class="filename">register.tpl</span></li>
+  <li><span class="filename">redirect.tpl</span></li>
+</ul>
+
+<h3>Dove posso trovare i "templates originali"?</h3>
+
+<p>I templates originali sono in template/yoga/
+(non modificare i templetes originali per evitare problemi durante gli aggiornamenti futuri). Dunque con
+i "templates originali", il webmaster può creare il suo "replacers (modelli personalizzati)".</p>
+
+<h3>Dove posso salvare i "rimpiazzanti"?</h3>
+
+<p><strong>I templates personalizzati</strong> possono essere salvati nella directory 
+template-extension (o sottodirectory).
+I "rimpiazzanti" possono avere qualunque nome con l'estenzione .tpl. Per esempio: <span
+class="filename">template-extension/my-extension/video.tpl</span>.</p>
+
+
+<h3>Come posso attivare i miei "rimpiazzanti"?</h3>
+<p>Un <strong>template originale</strong> dovrebbe essere assegnato a 
+ <strong>un replacer (modello personalizzato)</strong> per potere attivare i rimpiazzanti associati.
+ Attivare i rimpiazzanti è la funzione "Estende i templetes" nel menu di Configurazione del Amministrazione.</p>
+
+<p>Se selezionate un <strong>Parametro facoltativo del URL</strong> i rimpiazzanti saranno utilizzati 
+unicamente sulle pagine con questa parola chiave. Per esempio: <span
+  class="pwgScreen">index.php?/<strong>most_visited</strong></span></p>
+  
+<p>Gli utenti esperti useranno i permalinks come <strong>parametro facoltativo del URL</strong>. </p>
+
+<!-- TODO -->
+<p>Se selezionate un <strong>template legato</strong>, i rimpazzamenti avranno luogo unicamente su questo template.</p>
+
+<h3>Come posso disattivare mio "rimpiazzante"?</h3>
+<ul>
+<li>Deselezzionare il "templete originale".</li>
+<li>Con l'FTP cancellare il "rimpiazzante".</li>
+</ul>
+<a name="warnings"></a>
+<h3>Avvertenze</h3>
+<ul>
+
+  <li>Il <strong>templete d'origine</strong> deve essere il vero templete "originale"
+  altrimenti potrete avere dei risultati innattesi!</li>
+
+  <li>Se diversi <strong>replacers (templetes personalizzati)</strong> hanno lo stesso 
+  <strong>templete originale</strong> e lo stesso <strong>parametro facoltativo del URL</strong> 
+  solo l'ultimo rimpiazzante satà attivo.</li>
+
+  <li>Non selezionare <strong>il parametro facoltativo del URL</strong> 
+  attiverà il rimpiazzante ad ogni uso del templete.
+  Come detto precedente, l'ordine può annullare i rimpiazzanti precedenti.</li>
+
+  <li>Le sottodirectory:
+  Le sottodirectory sono ignorate ma sono utili per cambiare l'ordine dei rimpiazzanti.<br />
+distributed-samples: sono distribuite per le vostre prove! 
+<strong>Non modificateli</strong>, create i vostri! 
+</li>
+
+  <li>Alla cancellazione di un rimpiazzante il <strong>templete originale</strong>
+  è immediatamente riattivato.</li>
+
+</ul>
Index: /tags/2.0.2/language/it_IT/help/group_list.html
===================================================================
--- /tags/2.0.2/language/it_IT/help/group_list.html	(revision 3278)
+++ /tags/2.0.2/language/it_IT/help/group_list.html	(revision 3278)
@@ -0,0 +1,21 @@
+<h2>Elenco dei gruppi</h2>
+
+<p>Gestione delle proprietà dei gruppi.</p>
+
+<h3>Aggiungere un gruppo</h3>
+
+<p>L'amministratore può creare dei gruppi.</p>
+
+<h3>Elenco dei gruppi</h3>
+
+<p>Permette per ogni gruppo di:</p>
+
+<ul>
+  <li>accedere al elenco dei membri</li>
+  <li>accedere ai permessi</li>
+  <li>cancellare il gruppo (necessita una conferma)</li>
+  <li>commutare lo stato "default" (necessita una conferma)</li>
+</ul>
+
+<h3>Gruppo di default</h3>
+<p>Il gruppo di default è associato automaticamente ad ogni nuovo utente.</p>
Index: /tags/2.0.2/language/it_IT/help/history.html
===================================================================
--- /tags/2.0.2/language/it_IT/help/history.html	(revision 3278)
+++ /tags/2.0.2/language/it_IT/help/history.html	(revision 3278)
@@ -0,0 +1,52 @@
+<h2>Cronoligia</h2>
+
+<p>Questi schermi permettono di seguire la cronologia di navigazione del vostro
+ sito a seconda delle optzioni che avete attivatoin - Amministrazione - Generale 
+ - Linguetta "Cronologia".</p>
+	
+<h3>statistiche</h3>
+<ul>
+  <p>Se avete scelto che le visite delle pagine <span
+class="pwgScreen">index.php</span> e <span
+class="pwgScreen">picture.php</span> siano
+registrate nella tabella <code>history</code>,
+Questa linguetta permette di seguire il numero di pagine visitate</p>
+	
+	<li><strong>Statistiche totali</strong> : visualizzate le statistiche
+	annuali</li>
+	
+	<li><strong>Statistiche di un anno</strong> : visualizzate le statistiche
+	dei mesi del anno selezionato.</li>
+	
+	<li><strong>Statistiche di un mese</strong> : visualizzate le statistiche
+	dei giorni del mese selezionato.</li>
+	
+	<li><strong>Statistiche di una giornata</strong> : visualizzate le statistiche
+	delle ore della giornata selezionata.</li>
+	
+</ul>
+
+<h3>Ricercare</h3>
+<ul>
+  <p>Se avete scelto che le visite delle pagine <span
+class="pwgScreen">index.php</span> e <span
+class="pwgScreen">picture.php</span> siano
+registrate nella tabella <code>history</code>.
+Questa linguetta permette di seguire più in dettaglio le pagine visitate
+sul vostro sito con l'aiuto di diversi filtri.</p>
+ 
+	<li><strong>Filtro per data</strong> : selezionare l'intervallo
+d'osservazione di cui volete verificare l’attività.</li>
+	
+	<li><strong>Filtro per tipo di elemento</strong> : selezionare il
+tipo di elemento di cui volete osservare l’attività.</li>
+	
+	<li><strong>Utente</strong> : selezionare l'utente di cui
+volete osservare l'attività.</li>
+	
+	<li><strong>Nome file</strong> : selezionare il nome del file di cui
+volete osservare l'attività.</li>
+	
+	<li><strong>Id immagine</strong> : selezionare l'Id dell'immagine che
+ volete osservare l'attività.</li>
+</ul>
Index: /tags/2.0.2/language/it_IT/help/index.php
===================================================================
--- /tags/2.0.2/language/it_IT/help/index.php	(revision 3278)
+++ /tags/2.0.2/language/it_IT/help/index.php	(revision 3278)
@@ -0,0 +1,33 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | PhpWebGallery - a PHP based picture gallery                           |
+// | Copyright (C) 2002-2003 Pierrick LE GALL - pierrick@phpwebgallery.net |
+// | Copyright (C) 2003-2007 PhpWebGallery Team - http://phpwebgallery.net |
+// +-----------------------------------------------------------------------+
+// | file          : $Id: index.php 1912 2007-03-16 06:30:07Z rub $
+// | last update   : $Date: 2007-03-16 07:30:07 +0100 (ven, 16 mar 2007) $
+// | last modifier : $Author: rub $
+// | revision      : $Revision: 1912 $
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/language/it_IT/help/maintenance.html
===================================================================
--- /tags/2.0.2/language/it_IT/help/maintenance.html	(revision 3278)
+++ /tags/2.0.2/language/it_IT/help/maintenance.html	(revision 3278)
@@ -0,0 +1,51 @@
+<h2>Manutenzione</h2>
+
+<p>Per ottimizzare il tempo di generazione di una pagina, Piwigo usa
+delle informazioni dalla cache. Per esempio, invece di contare il numero
+d'immagini contenute in ogni categoria ad ogni ricarica, queste informazioni
+sono immagazzinate nella base dati. In teoria, questa informazione dovrebbe
+essere sempre corretta, ma a volte si può verificare un errore accadere e l'informazione
+della cache diventa errata. </p>
+
+<p>Alcune informazioni diventano inutili col tempo. Cancellare queste
+informazioni inutili dalla base base permette di liberare spazio sul disco.</p>
+
+<ul>
+
+  <li><strong>Aggiornare le informazioni delle categorie:</strong> Per ogni
+categoria, le informazioni da aggiornare o controllare sono le seguenti:
+elenco delle categorie madri, numero delle immagini, data dell'ultima immagine,
+posizione tra delle categorie di stesso livello, posizione tra categorie madri
+e categorie figlie. Quest'azione controlla anche la coerenza delle immagini
+rappresentative.</li>
+
+  <li><strong>Aggiornare le informazioni delle immagini:</strong> Per ogni
+immagine, le informazioni da aggiornare sono: il percorso completo verso
+il file, il voto medio. <em>Attenzione</em>: da non confondere con i metadati
+sincronizzabili tramite lo schermo <span class="pwgScreen">Amministrazione,
+Categorie, Sincronizare</span> o sullo schermo <span class="pwgScreen">Modificare
+le informazioni dell'immagine</span> (accessibile dalla pagina di visualizzazione
+di un'immagine<span class="pwgScreen">picture.php</span>).</li>
+
+  <li><strong>Riparare e ottimizzare la base dati:</strong>
+Per ogni tabella vengono realizzate le operazioni di riordinamento, riparazione
+ed ottimizzazione.</li>
+
+</ul>
+
+<ul>
+  <li><strong>Ripulire i dettagli della cronologia:</strong> Cancella tutte le righe
+dalla tabella <code>history</code>. Lo schermo <span
+class="pwgScreen">Amministrazione, Speciale, Cronologia</span> non mostra più
+nessuna informazione passata. <em>Attenzione</em>: Tutte le informazioni saranno
+definitivamente perse e non sarà più possibile recuperarle.</li>
+
+  <li><strong>Ripulire il sommario della cronologia:</strong> Cancella tutte le
+informazioni del sommario (ottenute dal dettaglio della cronologia) .</li>
+
+  <li><strong>Ripulire le sessioni:</strong> Cancella tutte le sessioni
+scadute.</li>
+
+  <li><strong>Ripulire i flussi di notifica mai usati</strong></li>
+
+</ul>
Index: /tags/2.0.2/language/it_IT/help/notification_by_mail.html
===================================================================
--- /tags/2.0.2/language/it_IT/help/notification_by_mail.html	(revision 3278)
+++ /tags/2.0.2/language/it_IT/help/notification_by_mail.html	(revision 3278)
@@ -0,0 +1,15 @@
+<h2>Notifiche per email</h2>
+
+<p>Questo schermo consente di configurare e gestire le notifiche via email sulle novità del sito.</p>
+
+<p>Questo schermo è composto di 3 alette:</p>
+
+<h3>Parametri</h3>
+<p>Disponibile soltanto per il webmasters, questa aletta gestisce i parametri della notifica via email.</p>
+
+<h3>Iscrizzione</h3>
+<p>Disponibile soltanto per il webmasters, questa aletta gestisce l'iscrizione/disiscrizione alle notifica via email.</p>
+
+<h3>Invio</h3>
+<p>Disponibile soltanto per il webmasters e per gli amministratori, questa aletta consente l'invio di email per notificare le novità del sito.</p>
+
Index: /tags/2.0.2/language/it_IT/help/permalinks.html
===================================================================
--- /tags/2.0.2/language/it_IT/help/permalinks.html	(revision 3278)
+++ /tags/2.0.2/language/it_IT/help/permalinks.html	(revision 3278)
@@ -0,0 +1,7 @@
+<h2>Permalink</h2>
+
+<p>I Permalinks sono usati per rendere le url delle categorie più piacevoli. Quando una categoria ha un permalink associato, l'id della categoria non è più necessaria nell'url.</p>
+
+<p>Quando un permalink è cancellato, potete salvarlo nello storico dei permalink, in modo che le fonti esterne alle pagine di PWG possano ancora riferirvisi. Nella tabella dalla cronologia dei permalink potete trovare la data di cancellazione del permalink, oltre alla data dell'ultima utilizzazione ed il numero di volte che è stato utilizzato.</p>
+
+<p>Notare che i permalinks devono essere unici. Devono essere unici anche nella cronologgia dei permalink.</p>
Index: /tags/2.0.2/language/it_IT/help/search.html
===================================================================
--- /tags/2.0.2/language/it_IT/help/search.html	(revision 3278)
+++ /tags/2.0.2/language/it_IT/help/search.html	(revision 3278)
@@ -0,0 +1,26 @@
+<h2>Ricerca</h2>
+
+<p>Ricercare delle immagini in tutta la galleria.</p>
+
+<dl>
+
+  <dt>Ricercare una parola</dt>
+
+  <dd>Cercare una o più parole in tutti gli attributi che riguardano le immagini
+mostrate nella galleria. Usare * come Joker per ricerche parziali.</dd>
+
+  <dt>Ricercare per Autore</dt>
+
+  <dd>Usare * come Joker per le ricerche parziali.</dd>
+
+  <dt>Ricercare per data</dt>
+
+  <dd>Selezionare una data e/o data di fine. Lasciare la data vuota se
+volete fare una ricerca "prima di". L'anno deve essere inserito nell'ultimo
+campo come nel formato seguente : 0000 (per esempio 2007)</dd>
+
+  <dt>Ricercare nelle categorie</dt>
+  <dd>Scegliere la categoria o le categorie in cui desiderate lanciare
+la ricerca.</dd>
+
+</dl>
Index: /tags/2.0.2/language/it_IT/help/site_manager.html
===================================================================
--- /tags/2.0.2/language/it_IT/help/site_manager.html	(revision 3278)
+++ /tags/2.0.2/language/it_IT/help/site_manager.html	(revision 3278)
@@ -0,0 +1,51 @@
+<h2>Siti in remoto</h2>
+
+<p>Piwigo offre la possibilità di usare diversi server per
+immagazzinare le immagini della vostra galleria. Ciò può essere utile
+se la vostra galleria è installata su uno spazio limitato e avete
+una grande quantità d'immagini da mostrare.</p>
+
+<ol>
+
+  <li>modificare il file <span
+class="filename">tools/create_listing_file.php</span> agendo
+sui parametri come <code>$conf['prefix_thumbnail']</code> o
+<code>$conf['use_exif']</code>.</li>
+
+  <li>piazzare il file <span
+class="filename">tools/create_listing_file.php</span> modificato sul Vostro sito
+remoto, nella stessa directory che le categorie che compongono la vostra galleria
+(come la directory <span class="filename">galleries</span> di questo sito), per FTP.
+Per esempio, supponiamo che potete accedere a <span
+class="filename">http://esempio.it/galleries/create_listing_file.php</span>.</li>
+
+  <li>andare su <span class="pwgScreen">Amministrazione, Categorie,
+Gestione dei siti</span>. Richiedere la creazione di un nuovo sito, per esempio <span
+class="filename">http://esempio.it/galleries</span>.</li>
+
+  <li>
+
+    <p>Un nuovo sito remoto è registrato. 4 azioni sono ora possibili :</p>
+
+    <ol>
+
+      <li><strong>generare la lista</strong> : lancia una richiesta remota
+per generare il file di listing remoto</li>
+
+      <li><strong>sincronizzare</strong> : legge il file remoto <span
+class="filename">listing.xml</span> e sincronizza con la base dati locale.</li>
+
+      <li><strong>pulire</strong> : cancella il file di listing remoto.</li>
+
+      <li><strong>Cancellare</strong> : cancella il sito remoto (e tutte le 
+relative categorie ed elementi associati) dalla base dati.</li>
+
+    </ol>
+  </li>
+</ol>
+
+<!-- <p>Potete anche effettuare queste operazioni manualmente modificando
+il file <span class="filename">listing.xml</span> e spostandolo alla radice
+di Piwigo. Andare su <span class="pwgScreen">Amministrazion, Categorie,
+Gestione dei siti</span> : Piwigo rileva la presenza del file e propone
+di usarlo.</p>-->
Index: /tags/2.0.2/language/it_IT/help/synchronize.html
===================================================================
--- /tags/2.0.2/language/it_IT/help/synchronize.html	(revision 3278)
+++ /tags/2.0.2/language/it_IT/help/synchronize.html	(revision 3278)
@@ -0,0 +1,14 @@
+<h2>Sincronizzare</h2>
+
+<ul>
+
+  <li>Ci sono 2 sincronizzazioni possibili: struttura e metadati. Sincronizzare
+la struttura significa sincronizzare l'albero delle categorie e dei file con la
+base dati. Sincronizzare i metadati permette di aggiornare delle informazioni
+come le dimensioni, le informazioni EXIF o IPTC.</li>
+
+  <li>La prima sincronizzazione deve essere quella della struttura.</li>
+
+  <li>Il processo di sincronizzazione potrebbe essere più o meno lungo (dipende
+dalla carica del server e della quantità di elementi da gestire). È dunque
+possibile di eseguire la sincronizzazione categoria per categoria.</li>
Index: /tags/2.0.2/language/it_IT/help/thumbnail.html
===================================================================
--- /tags/2.0.2/language/it_IT/help/thumbnail.html	(revision 3278)
+++ /tags/2.0.2/language/it_IT/help/thumbnail.html	(revision 3278)
@@ -0,0 +1,36 @@
+<h2>Creazione delle miniature</h2>
+
+<p>Questa pagina vi permette di creare le miniature che mancano. L'utilizzazione
+di questa funzionalità non è consigliata per i siti che si trovano su dei server
+mutualizzati (risorse condivise)</p>
+
+<dl>
+
+  <dt>Versione GD</dt>
+
+  <dd>GD è una biblioteca grafica per la manipolazione d'immagini per PHP.
+Scegliere la versione installata sul vostro server. Se scegliete quella sbagliata,
+dei messaggi d'errore appariranno, ritornate sulla pagina precedente e scegliete
+l'altra versione. Se nessuna versione funziona ciò significa che GD non è
+disponibile sul server.</dd>
+
+  <dt>Larghezza ed altezza</dt>
+
+  <dd>Sono le dimensioni massime che le miniature possono prendere. Il rapporto
+larghezza/altezza è mantenuto. I valori di default sono modificabili tramite
+i parametri di configurazione <code>tn_width</code> e <code>tn_height</code>
+(vedi file <span class="filename">include/config_default.inc.php</span>).</dd>
+
+  <dt>Numero di miniature da creare</dt>
+
+  <dd>Non tentate di miniaturizzare troppe immagini nello stesso tempo.
+La miniaturizzazione usa molta CPU. Se il sito Piwigo è installato
+su un server condiviso, un carico di CPU troppo alto può condurre alla
+soppressione del sito web.</dd>
+
+  <dt>Formato file</dt>
+
+  <dd>Le miniature sono create nel formato JPEG. Le miniature possono essere
+create soltanto nei formati PNG e JPEG.</dd>
+
+</dl>
Index: /tags/2.0.2/language/it_IT/help/user_list.html
===================================================================
--- /tags/2.0.2/language/it_IT/help/user_list.html	(revision 3278)
+++ /tags/2.0.2/language/it_IT/help/user_list.html	(revision 3278)
@@ -0,0 +1,39 @@
+<h2>Elenco degli utenti</h2>
+
+<p>Gestione dei parametri per gli utenti iscritti. Solo
+i permessi sono gestiti in un schermo diverso.</p>
+
+<h3>Aggiungere un utente</h3>
+
+<p>L'amministratore può aggiungere manualmente gli utenti. </p>
+
+<h3>Elenco degli utenti</h3>
+
+<p>L'elenco può essere filtrato sul nome utente (* = joker), il
+gruppo o lo stato. L'elenco può essere ordinato per data
+d'iscrizione o per nome utente, in ordine cronologico o decrescente.</p>
+
+<p>Su questo schermo si possono modificare più utenti alla volta :</p>
+
+<ul>
+  <li>cancellare degli utenti (necessita una conferma)</li>
+  <li>cambiare lo stato</li>
+  <li>associare o dissociare ai gruppi</li>
+  <li>modificare le propietà di visualizzazione</li>
+  <li>modificare le propietà annesse</li>
+</ul>
+
+<p>Riguarda l'elenco degli utenti selezionati (default) o degli
+utenti del elenco filtrato.</p>
+
+<h3>Consigliere</h3>
+<p>Definizione del utente consigliere:</p>
+<ul>
+  <li>consente l'accesso a tutti gli schermi permessi da questo stato</li>
+  <li>accesso autorizzato unicamente in consultazione o simulazione</li>
+</ul>
+
+<p>È possibile assegnare il modo consigliere attivando il parametro
+$conf['allow_adviser'].</p>
+<p>Se il parametro è a 'true', è possibile definire un utente come
+consigliere</p>
Index: /tags/2.0.2/language/it_IT/index.php
===================================================================
--- /tags/2.0.2/language/it_IT/index.php	(revision 3278)
+++ /tags/2.0.2/language/it_IT/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/language/it_IT/install.lang.php
===================================================================
--- /tags/2.0.2/language/it_IT/install.lang.php	(revision 3278)
+++ /tags/2.0.2/language/it_IT/install.lang.php	(revision 3278)
@@ -0,0 +1,74 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+$lang['Installation'] = 'Installazione';
+$lang['Initial_config'] = 'Configurazione di base';
+$lang['Default_lang'] = 'Linguaggio di default della galleria';
+$lang['step1_title'] = 'Configurazione della base dati';
+$lang['step2_title'] = 'Configurazione del utente "Amministratore"';
+$lang['Start_Install'] = 'Inizia l\'installazione';
+$lang['reg_err_mail_address'] = 'L\'indirizzo email deve essere del tipo xxx@yyy.eee (ad esempio: cippalippa@libero.rio)';
+
+$lang['install_webmaster'] = 'Amministratore';
+$lang['install_webmaster_info'] = 'verrà mostrato ai visitatori. È necessario per l\'amministrazione del sito';
+
+$lang['step1_confirmation'] = 'I parametri sono corretti';
+$lang['step1_err_db'] = 'Connessione al server riuscita. Non è stato però possibile connettersi alla base dati';
+$lang['step1_err_server'] = 'Non è stato possibile connettersi al server';
+
+$lang['step1_host'] = 'MySQL host';
+$lang['step1_host_info'] = 'localhost, sql.multimania.com, pluto.libero.it';
+$lang['step1_user'] = 'Utente';
+$lang['step1_user_info'] = 'nome utente di login alla base dati fornito dal tuo provider';
+$lang['step1_pass'] = 'Password';
+$lang['step1_pass_info'] = 'La password d\'accesso alla base dati fornita dal tuo provider';
+$lang['step1_database'] = 'Nome della base dati';
+$lang['step1_database_info'] = 'fornitovi dal provider';
+$lang['step1_prefix'] = 'Prefisso delle tabelle della base dati';
+$lang['step1_prefix_info'] = 'Le tabelle della base dati lo avranno come prefisso (permette di gestire meglio le tabelle)';
+$lang['step2_err_login1'] = 'Inserire un nome utente per il webmaster';
+$lang['step2_err_login3'] = 'Il nome utente del webmaster non può contenere caratteri come \' o "';
+$lang['step2_err_pass'] = 'Reinserire la password';
+$lang['install_end_title'] = 'Installazione completata';
+$lang['step2_pwd'] = 'Password';
+$lang['step2_pwd_info'] = 'da conservare con cura. Permette l\'accesso al pannello di amministrazione';
+$lang['step2_pwd_conf'] = 'Password [confermare]';
+$lang['step2_pwd_conf_info'] = 'verifica';
+$lang['step1_err_copy'] = 'Copiate il testo in rosa trà i trattini e mettetelo nel file mysql.inc.php che si trova nella directory "include" alla base del vostro sito dove aveto installato Piwigo (il file mysql.inc.php non deve contenere altro che ciò che è in rosa tra i trattini, nessun ritorno a capo o spazio è autorizzato)';
+$lang['install_help'] = 'Bisogno di un aiuto? Visitate il <a href="%s">forum di Piwigo</a>.';
+$lang['install_end_message'] = 'La configurazione di Piwigo è conclusa. Procedete al prossimo step<br /><br />
+* collegatevi alla pagina d\'accesso e usare come nome d\'utente e password quello del Webmaster<br />
+* a questo punto sarete abilitati all\'accesso al pannello di amministrazione in cui troverete le istruzioni per l\'inserimento delle immagini nelle vostre directory';
+$lang['conf_mail_webmaster'] = 'Indirizzo email del Amministratore';
+$lang['conf_mail_webmaster_info'] = 'i visitatori potranno contattarvi utilizzando questo indirizzo email';
+
+$lang['PHP 5 is required'] = 'È necessario PHP 5';
+$lang['It appears your webhost is currently running PHP %s.'] = 'Sembrerebbe che la versione del vostro server è PHP %s.';
+$lang['Piwigo may try to switch your configuration to PHP 5 by creating or modifying a .htaccess file.'] = 'Piwigo cerchrà di passare in PHP 5 creando o modificando il file .htaccess.';
+$lang['Note you can change your configuration by yourself and restart Piwigo after that.'] = 'Notate che potete cambiare manualmente la configurazione e rilanciare Piwigo.';
+$lang['Try to configure PHP 5'] = 'Provate a configuratre PHP 5';
+$lang['Sorry!'] = 'Spiacente!';
+$lang['Piwigo was not able to configure PHP 5.'] = 'Piwigo non a potuto configurare PHP 5.';
+$lang["You may referer to your hosting provider's support and see how you could switch to PHP 5 by yourself."] = 'Dovete contattare il votro provider per chiedere come configurare PHP 5.';
+$lang['Hope to see you back soon.'] = 'Sperando di rivedervi prossimamente ...';
+?>
Index: /tags/2.0.2/language/it_IT/iso.txt
===================================================================
--- /tags/2.0.2/language/it_IT/iso.txt	(revision 3278)
+++ /tags/2.0.2/language/it_IT/iso.txt	(revision 3278)
@@ -0,0 +1,1 @@
+Italiano [IT]
Index: /tags/2.0.2/language/it_IT/upgrade.lang.php
===================================================================
--- /tags/2.0.2/language/it_IT/upgrade.lang.php	(revision 3278)
+++ /tags/2.0.2/language/it_IT/upgrade.lang.php	(revision 3278)
@@ -0,0 +1,44 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+$lang['Upgrade'] = 'Aggiornamento';
+$lang['introduction message'] = 'Questa pagina vi propone di aggiornare la vostra base dati corrispondente alla vecchia versione verso la nuova versione.
+L\'assistente all\'aggiornamento ha identificato il vostro prodotto come essendo una <strong>versione %s</strong> (o equivalente).';
+$lang['Upgrade from %s to %s'] = 'Aggiornamento dalla versione %s alla %s';
+$lang['Statistics'] = 'Statistiche';
+$lang['total upgrade time'] = 'tempo totale per aggiornamento';
+$lang['total SQL time'] = 'tempo totale delle esecuzioni SQL';
+$lang['SQL queries'] = 'numero delle esecuzioni SQL';
+$lang['Upgrade informations'] = 'Informazioni sul\'aggiornamento';
+$lang['perform a maintenance check'] = 'Se riscontrate dei problemi, effettuare una manutezione in [Amministrazione>Speciale>Manutenzione].';
+$lang['deactivated plugins'] = 'Per precauzione, i plugins sono stati disattivati. Verificate se non esistono degli aggiornamenti prima di riattivarli:';
+$lang['upgrade login message'] = 'Solo un\'amministratore può eseguire l\'aggiornamento: identificatevi.';
+$lang['You do not have access rights to run upgrade'] = 'Non avete le autorizzazioni necessarie per effettuare l\'aggiornamento';
+$lang['in include/mysql.inc.php, before ?>, insert:'] = 'Nel file <i>include/mysql.inc.php</i>, prima di <b>?></b>, inserire:';
+
+// Upgrade informations from upgrade_1.3.1.php
+$lang['all sub-categories of private categories become private'] = 'Tutte le sottocategorie delle categorie private diventono private';
+$lang['user permissions and group permissions have been erased'] = 'I permessi degli utenti e dei gruppi sono stati cancellati';
+$lang['only thumbnails prefix and webmaster mail saved'] = 'Solo il prefisso delle miniature e l\'email del webmaster sono stati salvati dalla precedente configurazione';
+
+?>
Index: /tags/2.0.2/language/ja_JP/README.txt
===================================================================
--- /tags/2.0.2/language/ja_JP/README.txt	(revision 3278)
+++ /tags/2.0.2/language/ja_JP/README.txt	(revision 3278)
@@ -0,0 +1,4 @@
+Piwigo Japanese language files
+Translator Mitsuhiro Yoshida (http://mitstek.com/)
+Started 2008-12-21
+Updated 2009-05-02
Index: /tags/2.0.2/language/ja_JP/about.html
===================================================================
--- /tags/2.0.2/language/ja_JP/about.html	(revision 3278)
+++ /tags/2.0.2/language/ja_JP/about.html	(revision 3278)
@@ -0,0 +1,7 @@
+<li>Piwigoは、あなたがオンラインイメージギャラリーを作成することのできるアプリケーションです。</li>
+
+<li>技術的には、PiwigoはPHP (elePHPant) およびMySQLデータベース (SQuirreL) を使用して開発されています。</li>
+
+<li>あなたが提案またはコメントを投稿したい場合、 <a  href="http://piwigo.org">Piwigo</a>オフィシャルサイトにアクセスした後、
+<a href="http://forum.Piwigo.net">フォーラム</a>に投稿してください。</li>
+
Index: /tags/2.0.2/language/ja_JP/admin.lang.php
===================================================================
--- /tags/2.0.2/language/ja_JP/admin.lang.php	(revision 3278)
+++ /tags/2.0.2/language/ja_JP/admin.lang.php	(revision 3278)
@@ -0,0 +1,647 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008      Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+$lang['%d association'] = '関連:%d';
+$lang['%d associations'] = '関連:%d';
+$lang['cat_inclu_part1_S'] = 'カテゴリ:%d  - ';
+$lang['cat_inclu_part1_P'] = 'カテゴリ:%d  - ';
+$lang['cat_inclu_part2_S'] = '物理ディレクトリ:%d ';
+$lang['cat_inclu_part2_P'] = '物理ディレクトリ:%d ';
+$lang['cat_inclu_part3_S'] = 'バーチャルディレクトリ:%d ';
+$lang['cat_inclu_part3_P'] = 'バーチャルディレクトリ:%d ';
+$lang['%d category moved'] = '%d 件のカテゴリが移動されました。';
+$lang['%d categories moved'] = '%d 件のカテゴリが移動されました。';
+$lang['%d group'] = 'グループ:%d';
+$lang['%d groups'] = 'グループ:%d';
+$lang['%d member'] = 'メンバー:%d';
+$lang['%d members'] = 'メンバー:%d';
+$lang['%d tag'] = 'タグ:%d';
+$lang['%d tags'] = 'タグ:%d';
+$lang['%d user comment rejected'] = '%d 件のユーザコメントが拒否されました。';
+$lang['%d user comments rejected'] = '%d 件のユーザコメントが拒否されました。';
+$lang['%d user comment validated'] = '%d 件のユーザコメントが承認されました。';
+$lang['%d user comments validated'] = '%d 件のユーザコメントが承認されました。';
+$lang['%d user deleted'] = '%d ユーザが削除されました。';
+$lang['%d users deleted'] = '%d ユーザが削除されました。';
+$lang['%d user'] = 'ユーザ:%d';
+$lang['%d users'] = 'ユーザ:%d';
+$lang['%d waiting for validation'] = '承認待ち: %d 件';
+$lang['%d waiting pictures rejected'] = '拒否待ちの写真: %d 件';
+$lang['%d waiting pictures validated'] = '承認待ちの写真: %d 件';
+$lang['Actions'] = '操作';
+$lang['Activate'] = '有効化';
+$lang['Add/delete a permalink'] = 'パーマリンクを追加/削除する';
+$lang['Add a tag'] = 'タグを追加する';
+$lang['Add a user'] = 'ユーザを追加する';
+$lang['Add group'] = 'グループを追加する';
+$lang['Add selected elements to caddie'] = '選択したエレメントをキャディに追加する';
+$lang['Add'] = '追加';
+$lang['Allow user registration'] = 'ユーザ登録を許可する';
+$lang['Apply to subcategories'] = 'サブカテゴリに適用する';
+$lang['Are you sure?'] = '本当によろしいですか?';
+$lang['Associated'] = '関連';
+$lang['Association to categories'] = 'カテゴリの関連';
+$lang['Batch management'] = 'バッチ管理';
+$lang['Caddie management'] = 'キャディ管理';
+$lang['Caddie'] = 'キャディ';
+$lang['Categories authorized thanks to group associations'] = 'グループの関連付けによりカテゴリが許可されました。';
+$lang['Categories manual order was saved'] = 'カテゴリの手動順が保存されました。';
+$lang['Categories ordered alphanumerically'] = 'カテゴリが英数字順に並び替えられました';
+$lang['Category elements associated to the following categories: %s'] = '以下のカテゴリに関連するカテゴリエレメント: %s';
+$lang['Check for upgrade failed for unknown reasons.'] = '不明な理由により、アップグレードのチェックが失敗しました。';
+$lang['Check for upgrade'] = 'アップグレードをチェックする';
+$lang['Comments for all'] = 'すべてのユーザにコメントを許可する';
+$lang['Controversy'] = '論争';
+$lang['Current name'] = '現在の名称';
+$lang['Database'] = 'データベース';
+$lang['Deactivate'] = '無効化';
+$lang['Delete Representant'] = '見本を削除する';
+$lang['Delete selected tags'] = '選択したタグを削除する';
+$lang['Delete selected users'] = '選択したユーザを削除する';
+$lang['Deletions'] = '削除';
+$lang['Deny selected groups'] = '選択したグループを拒否する';
+$lang['Deny selected users'] = '選択したユーザを拒否する';
+$lang['Description'] = '説明';
+$lang['Display options'] = '表示オプション';
+$lang['Dissociated'] = '関連なし';
+$lang['Does not represent'] = '非表示';
+$lang['Edit all picture informations'] = 'すべての写真情報を編集する';
+$lang['Edit selected tags'] = '選択したタグを編集する';
+$lang['Edit tags'] = 'タグを編集する';
+$lang['Elements'] = 'エレメント';
+$lang['Email administrators when a new user registers'] = '新しいユーザ登録時、管理者にメールする';
+$lang['Email administrators when a valid comment is entered'] = '有効なコメントが入力された場合、管理者にメールする';
+$lang['Email administrators when a comment requires validation'] = 'コメントの承認が必要な場合、管理者にメールする';
+$lang['Email administrators when a picture is uploaded'] = '写真がアップロードされた場合、管理者にメールする';
+$lang['Empty caddie'] = 'キャディーを空にする';
+$lang['Environment'] = '環境';
+$lang['Form'] = 'フォーム';
+$lang['Gallery URL'] = 'ギャラリーURI';
+$lang['Gallery description'] = 'ギャラリー説明';
+$lang['Gallery title'] = 'ギャラリータイトル';
+$lang['Grant selected groups'] = '選択したグループに付与する';
+$lang['Grant selected users'] = '選択したユーザに付与する';
+$lang['Group name'] = 'グループ名';
+$lang['Groups'] = 'グループ';
+$lang['Guests'] = 'ゲスト';
+$lang['History'] = '履歴';
+$lang['Informations'] = '情報';
+$lang['Install'] = 'インストール';
+$lang['Link all category elements to a new category'] = 'すべてのカテゴリエレメントを新しいカテゴリにリンクする';
+$lang['Link all category elements to some existing categories'] = 'すべてのカテゴリエレメントを既存のカテゴリにリンクする';
+$lang['Linked categories'] = 'リンクカテゴリ';
+$lang['Lock gallery'] = 'ギャラリーをロックする';
+$lang['Maintenance'] = 'メンテナンス';
+$lang['Manage permissions for a category'] = 'カテゴリのパーミッションを管理する';
+$lang['Manage permissions for group "%s"'] = 'グループ「 %s 」のパーミッションを管理する';
+$lang['Manage permissions for user "%s"'] = 'ユーザ「 %s 」のパーミッションを管理する';
+$lang['Manage tags'] = 'タグを管理する';
+$lang['Members'] = 'メンバー';
+$lang['Metadata synchronized from file'] = 'ファイルからメタデータを同期化する';
+$lang['Move categories'] = 'カテゴリを移動する';
+$lang['Move'] = '移動';
+$lang['Name'] = '名称';
+$lang['New name'] = '新しい名称';
+$lang['New parent category'] = '新しい親カテゴリ';
+$lang['New tag'] = '新しいタグ';
+$lang['No tag defined. Use Administration>Pictures>Tags'] = 'タグが定義されていません。「管理 > 写真 > タグ」を使用して、タグを定義してください。';
+$lang['Number of comments per page'] = '1ページあたりのコメント数';
+$lang['Number of rates'] = '評価数';
+$lang['Number of thumbnails to create'] = '作成サムネイル数';
+$lang['Only private categories are listed'] = 'プライベートカテゴリのみ表示されています。';
+$lang['Operating system'] = 'オペレーティングシステム';
+$lang['Options'] = 'オプション';
+$lang['Order alphanumerically'] = '英数字順に並び替える';
+$lang['Other private categories'] = '他のプライベートカテゴリ';
+$lang['Page banner'] = 'ページバナー';
+$lang['Parent category'] = '親カテゴリ';
+$lang['Path'] = 'パス';
+$lang['Permalink'] = 'パーマリンク';
+$lang['Permalink_%s_histo_used_by_%s'] = 'パーマリンク %s は、すでにカテゴリ %s で使用されています。最初にパーマリンク履歴を削除してください。';
+$lang['Permalink_name_rule'] = 'パーマリンク名は、a-z、A-Z、0-9、「-」、「_」、「/」で構成される必要があります。数字または「-」が続く数字を使用することはできません。';
+$lang['Permalink %s is already used by category %s'] = 'パーマリンク %s は、すでにカテゴリ %s で使用されています。';
+$lang['Permalink history'] = 'パーマリンク履歴';
+$lang['Permalinks'] = 'パーマリンク';
+$lang['Permission denied'] = 'パーミッション拒否';
+$lang['Permission granted thanks to a group'] = 'グループにパーミッションが付与されました。';
+$lang['Permission granted'] = 'パーミッション付与';
+$lang['Picture informations updated'] = '写真情報が更新されました。';
+$lang['Plugins'] = 'プラグイン';
+$lang['Position'] = 'ポジション';
+$lang['Preferences'] = 'プリファレンス';
+$lang['Properties'] = 'プロパティ';
+$lang['Random picture'] = 'ランダム写真';
+$lang['Rate date'] = '評価日';
+$lang['Rating by guests'] = 'ゲストによる評価';
+$lang['Rating'] = '評価';
+$lang['Reject All'] = 'すべてを拒否する';
+$lang['Reject'] = '拒否';
+$lang['Representant'] = '見本';
+$lang['Representation of categories'] = 'カテゴリ見本';
+$lang['Representative'] = '見本';
+$lang['Represents'] = '表示';
+$lang['Save order'] = '表示順を保存する';
+$lang['Save to permalink history'] = 'パーマネントリンク履歴に保存する';
+$lang['Select at least one category'] = '少なくとも1つのカテゴリを選択してください。';
+$lang['Select at least one picture'] = '少なくとも1つの写真を選択してください。';
+$lang['Select at least one user'] = '少なくとも1名のユーザを選択してください。';
+$lang['Show info'] = '情報を表示する';
+$lang['Site manager'] = 'サイトマネージャ';
+$lang['Status'] = 'ステータス';
+$lang['Statistics'] = '統計';
+$lang['Storage category'] = '保存カテゴリ';
+$lang['Sum of rates'] = '評価の合計';
+$lang['Tag "%s" already exists'] = 'タグ "%s" は、すでに登録されています。';
+$lang['Tag "%s" was added'] = 'タグ "%s" が追加されました。';
+$lang['Tag selection'] = 'タグ選択';
+$lang['Take selected elements out of caddie'] = '選択したエレメントをキャディから取り出す';
+$lang['The %d following tag were deleted'] = '次のタグが削除されました。';
+$lang['The %d following tags were deleted'] = '次の %d 件のタグが削除されました。';
+$lang['Unable to check for upgrade since allow_url_fopen is disabled.'] = 'allow_url_fopenが無効にされているため、アップグレードをチェックできません。';
+$lang['Uninstall'] = 'アンインストール';
+$lang['Use default sort order']='デフォルトの (設定ファイルで定義された) イメージ並び順を使用する';
+$lang['User comments validation'] = 'ユーザコメント承認';
+$lang['Users'] = 'ユーザ';
+$lang['Validate All'] = 'すべてを承認する';
+$lang['Validate'] = '承認';
+$lang['Validation'] = '承認';
+$lang['Version'] = 'バージョン';
+$lang['Virtual categories movement'] = 'バーチャルカテゴリの移動';
+$lang['Virtual categories to move'] = '移動するバーチャルカテゴリ';
+$lang['Virtual category name'] = 'バーチャルカテゴリ名';
+$lang['Webmaster cannot be deleted'] = 'ウェブマスタは削除できません。';
+$lang['You are running on development sources, no check possible.'] = 'あなたは開発版を使用しているため、チェックすることはできません。';
+$lang['You cannot delete your account'] = "あなた自身のアカウントを削除できません。";
+$lang['You cannot move a category in its own sub category'] = 'あなたは、カテゴリをサブカテゴリに移動できません。';
+$lang['You need to confirm deletion'] = 'あなたは、削除を確認する必要があります。';
+$lang['add tags'] = 'タグを追加する';
+$lang['adviser'] = 'アドバイザ';
+$lang['associate to category'] = 'カテゴリに関連付ける';
+$lang['associate to group'] = 'グループに関連付ける';
+$lang['authorized'] = 'Authorized';
+$lang['cat_add'] = 'バーチャルカテゴリを追加する';
+$lang['cat_comments_title'] = '選択されたカテゴリにユーザのコメント追加を許可する';
+$lang['cat_error_name'] = 'カテゴリ名は空白にしないでください。';
+$lang['cat_lock_title'] = 'カテゴリをロックする';
+$lang['cat_private'] = 'プライベートカテゴリ';
+$lang['cat_public'] = 'パブリックカテゴリ';
+$lang['cat_representant'] = '新しい見本をランダムに探す';
+$lang['cat_security'] = 'パブリック / プライベート';
+$lang['cat_status_title'] = '選択したカテゴリの権限を管理する';
+$lang['cat_upload_title'] = 'アップロード可能なカテゴリを選択する';
+$lang['cat_virtual_added'] = 'バーチャルカテゴリが追加されました。';
+$lang['cat_virtual_deleted'] = 'バーチャルカテゴリが削除されました。';
+$lang['category'] = 'カテゴリ';
+$lang['conf_access'] = 'アクセスタイプ';
+$lang['conf_comments_title'] = 'コメント';
+$lang['conf_confirmation'] = 'データベースに登録された情報データ';
+$lang['conf_display'] = 'デフォルト表示';
+$lang['conf_history_title'] = '履歴';
+$lang['conf_gallery_url_error'] = 'ギャラリーURIが有効ではありません。';
+$lang['conf_main_title'] = 'メイン';
+$lang['conf_nb_comment_page_error'] = '1ページあたりのコメント数は、5から50の間にしてください。';
+$lang['config'] = '設定';
+$lang['confirm'] = '確認';
+$lang['Date'] = '日付';
+$lang['delete category'] = 'カテゴリを削除する';
+$lang['dissociate from category'] = 'カテゴリから関連付けを解除する';
+$lang['dissociate from group'] = 'グループから関連付けを解除する';
+$lang['edit category permissions'] = 'カテゴリパーミッションを編集する';
+$lang['editcat_confirm'] = 'カテゴリ情報が正常に更新されました。';
+$lang['editcat_uploadable'] = 'アップロードを許可する';
+$lang['elements per page'] = '1ページあたりのエレメント';
+$lang['elements'] = 'エレメント';
+$lang['enabled_high'] = '高解像度を有効にする';
+$lang['file'] = 'ファイル';
+$lang['filesize'] = 'ファイルサイズ';
+$lang['first element added on %s'] = '最初のエレメント追加日時 %s';
+$lang['forbidden'] = '禁止';
+$lang['conf_general'] = '一般';
+$lang['global mode'] = 'グローバルモード';
+$lang['group "%s" added'] = 'グループ "%s" が追加されました。';
+$lang['group "%s" deleted'] = 'グループ "%s" が削除されました。';
+$lang['group "%s" updated'] = 'グループ "%s" が更新されました。';
+$lang['group'] = 'グループ';
+$lang['group_add_error1'] = 'グループ名には「"」または「\'」を含んだり、空白にしないでください。';
+$lang['group_add_error2'] = 'このグループ名は、すでに別のグループで使用されています。';
+$lang['groups'] = 'グループ';
+$lang['instructions'] = 'インストラクション';
+$lang['is_high_disabled'] = '';
+$lang['is_high_enabled'] = '高解像度';
+$lang['jump to category'] = 'カテゴリにジャンプする';
+$lang['jump to image'] = 'イメージにジャンプする';
+$lang['leave'] = '変更なし';
+$lang['lock'] = 'ロック';
+$lang['locked'] = 'ロック済み';
+$lang['manage category elements'] = 'カテゴリエレメントを管理する';
+$lang['manage sub-categories'] = 'サブカテゴリを管理する';
+$lang['manage'] = '管理';
+$lang['maximum height'] = '最大高';
+$lang['maximum width'] = '最大幅';
+$lang['nbm_background_treatment_redirect_second'] = '実行時間が終了しました。処理を継続します [予想時間: %d 秒]。';
+$lang['nbm_background_treatment_redirect_seconds'] = '実行時間が終了しました。処理を継続します  [予想時間: %d 秒].';
+$lang['nbm_break_timeout_list_user'] = 'メール送信するユーザリストのユーザ数が制限されています。他のユーザは、リストに含まれていません。';
+$lang['nbm_break_timeout_send_mail'] = 'メール送信時間が制限されています。他のメールはスキップされます。';
+$lang['nbm_col_check_user_send_mail'] = '送信?';
+$lang['nbm_col_last_send'] = '最終送信';
+$lang['nbm_col_mail'] = 'メール';
+$lang['nbm_col_user'] = 'ユーザ';
+$lang['nbm_complementary_mail_content'] = '補足的なメールコンテンツ';
+$lang['nbm_content_byebye'] = 'それでは ';
+$lang['nbm_content_goto_1'] = '移動 ';
+$lang['nbm_content_goto_2'] = '.';
+$lang['nbm_content_hello_1'] = 'こんにちは ';
+$lang['nbm_content_hello_2'] = ',';
+$lang['nbm_content_new_elements'] = '新しいエレメントが追加されました:';
+$lang['nbm_content_new_elements_single'] = ' ';
+$lang['nbm_content_new_elements_between_1'] = ' ';
+$lang['nbm_content_new_elements_between_2'] = ' - ';
+$lang['nbm_content_subscribe_by_admin'] = 'あなたが通知メールを受信するよう、ウェブマスタが購読登録しました。';
+$lang['nbm_content_subscribe_by_himself'] = 'あなたは、通知メールを購読登録しました。';
+$lang['nbm_content_subscribe_link'] = '購読登録するには、';
+$lang['nbm_content_problem_contact'] = 'あなたが問題に遭遇した場合、質問がある場合、次の宛先にメール送信してください:';
+$lang['nbm_content_pb_contact_object'] = '[NBM] 問題または質問';
+$lang['nbm_content_unsubscribe_by_admin'] = 'あなたの通知メール購読をウェブマスタが解除しました。';
+$lang['nbm_content_unsubscribe_by_himself'] = 'あなたは、通知メールを購読解除しました。';
+$lang['nbm_content_click_on'] = '次のリンクをクリックしてください:';
+$lang['nbm_content_unsubscribe_link'] = '受講解除するには、';
+$lang['nbm_info_send_mail_as'] = '空白の場合、ギャラリータイトルが使用されます。';
+$lang['nbm_item_notification'] = '通知';
+$lang['nbm_msg_error_sending_email_to'] = '%s [%s] にメール送信中、エラーが発生しました。';
+$lang['nbm_msg_mail_sent_to'] = 'メールが %s [%s] に送信されました。';
+$lang['nbm_msg_n_mail_sent'] = '%d メールが送信されました。';
+$lang['nbm_msg_n_mails_sent'] = '%d メールが送信されました。';
+$lang['nbm_msg_n_mail_not_send'] = '%d メールは送信されませんでした。';
+$lang['nbm_msg_n_mails_not_send'] = '%d メールは送信されませんでした。';
+$lang['nbm_no_mail_to_send'] = '送信されたメールはありません。';
+$lang['nbm_no_user_available_to_send_L1'] = 'メールを送信できるユーザは存在しません。';
+$lang['nbm_no_user_available_to_send_L2'] = '通知する新しいエレメントがある場合、ユーザが利用できます。';
+$lang['nbm_no_user_available_to_send_L3'] = 'ユーザはメール購読できません (このタブは、ウェブマスタにのみ表示されます)。';
+$lang['nbm_no_user_to send_notifications_by_mail'] = '通知メールを送信できるユーザは存在しません。';
+$lang['nbm_object_news'] = '新しいエレメントが追加されました。';
+$lang['nbm_object_subscribe'] = '通知メールを購読する';
+$lang['nbm_object_unsubscribe'] = '通知メールを購読解除する';
+$lang['nbm_param_mode'] = 'パラメータ';
+$lang['nbm_redirect_msg'] = '処理中.'."\n\n".'お待ちください ...';
+$lang['nbm_repost_submit'] = '処理を続ける';
+$lang['nbm_send_complementary_mail_content'] = '補足メールコンテンツ';
+$lang['nbm_send_detailed_content'] = '詳細コンテンツを追加する';
+$lang['nbm_send_mail_as'] = '送信者名';
+$lang['nbm_send_mail_to_users'] = 'ユーザにメールを送信する';
+$lang['nbm_send_mode'] = '送信';
+$lang['nbm_send_options'] = 'オプション';
+$lang['nbm_send_submit'] = '送信';
+$lang['nbm_subscribe_col'] = '購読中';
+$lang['nbm_subscribe_mode'] = '購読';
+$lang['nbm_title_param'] = 'パラメータ';
+$lang['nbm_title_send'] = '受信者の選択';
+$lang['nbm_title_subscribe'] = 'ユーザの購読登録/購読解除';
+$lang['nbm_unsubscribe_col'] = '購読なし';
+$lang['nbm_updated_param_count'] = '%d 件のパラメータが更新されました。';
+$lang['nbm_updated_params_count'] = '%d 件のパラメータが更新されました。';
+$lang['nbm_user_change_enabled_error_on_updated_data_count'] = '%d 名のユーザが更新されませんでした。';
+$lang['nbm_users_change_enabled_error_on_updated_data_count'] = '%d 名のユーザが更新されませんでした。';
+$lang['nbm_user_change_enabled_false'] = 'ユーザ %s [%s] は、購読リストから削除されました。';
+$lang['nbm_user_change_enabled_true'] = 'ユーザ %s [%s] は、購読リストに追加されました。';
+$lang['nbm_user_change_enabled_updated_data_count'] = '%d 名のユーザが更新されました。';
+$lang['nbm_users_change_enabled_updated_data_count'] = '%d 名のユーザが更新されました。';
+$lang['nbm_user_not_change_enabled_false'] = 'ユーザ %s [%s] は、購読リストから削除されませんでした。';
+$lang['nbm_user_not_change_enabled_true'] = 'ユーザ %s [%s] は、購読リストに追加されませんでした。';
+$lang['nbm_user_x_added'] = 'ユーザ %s [%s] が追加されました。';
+$lang['nbm_warning_subscribe_unsubscribe'] = '注意: 購読登録または購読解除の設定は、ユーザ宛にメール通知されます。';
+$lang['nbm_send_html_mail'] = 'HTMLフォーマットでメールを送信する';
+$lang['nbm_send_recent_post_dates'] = '最近の写真グループの日付ごとの表示を含む';
+$lang['nbm_info_send_recent_post_dates'] = 'HTMLフォーマットのみ利用可';
+$lang['no_write_access'] = 'アクセス権なし';
+$lang['path'] = 'パス';
+$lang['permissions'] = 'パーミッション';
+$lang['private'] = 'プライベート';
+$lang['properties'] = 'プロパティ';
+$lang['public'] = 'パブリック';
+$lang['purge never used notification feeds'] = '未使用の通知フィードを削除する';
+$lang['purge sessions'] = 'セッションを削除する';
+$lang['randomly represented'] = 'ランダム表示';
+$lang['registration_date'] = '登録日';
+$lang['remote_site'] = 'リモートサイト';
+$lang['remote_site_clean'] = 'クリーン';
+$lang['remote_site_clean_hint'] = 'リモートlisting.xmlファイルを削除します。';
+$lang['remote_site_generate'] = 'リスティングを生成する';
+$lang['remote_site_generate_hint'] = 'リモートサイトにlisting.xmlファイルを生成します。';
+$lang['remote_site_local_create'] = 'このサイトを作成する';
+$lang['remote_site_local_found'] = 'ローカルlisting.xmlファイルが見つかりました: ';
+$lang['remote_site_local_update'] = 'ローカルlisting.xmlの読み込みおよびアップグレード';
+$lang['remote_site_test'] = 'テスト';
+$lang['remote_site_test_hint'] = 'このリモートサイトをテストします。';
+$lang['remote_site_uncorrect_url'] = 'リモートサイトのURIは、httpまたはhttpsで開始してください。また、「/」「a-zA-Z0-9」「-」「_」の文字のみ含むことができます。';
+$lang['remove tags'] = 'タグを削除する';
+$lang['repair and optimize database'] = 'データベースを修復および最適化する';
+$lang['selection'] = '選択';
+$lang['set to'] = '設定';
+$lang['singly represented'] = '単独表示';
+$lang['site_already_exists'] = 'このサイトは、すでに登録されています。';
+$lang['site_create'] = '新しいサイトを作成する : (create_listing_file.phpにURIを渡します)';
+$lang['site_created'] = 'が作成されました。';
+$lang['site_delete'] = '削除';
+$lang['site_delete_hint'] = 'このサイトおよびすべてに添付ファイルを削除します。';
+$lang['site_deleted'] = 'が削除されました。';
+$lang['site_err'] = 'エラーが発生しました。';
+$lang['site_err_remote_file_not_found'] = 'リモートサイトのfile create_listing_file.phpが見つかりませんでした。';
+$lang['site_local'] = 'ローカル';
+$lang['site_remote'] = 'リモート';
+$lang['site_synchronize'] = '同期化';
+$lang['site_synchronize_hint'] = 'ファイルからデータベースを更新します。';
+$lang['status'] = 'ステータス';
+$lang['storage'] = 'ディレクトリ';
+$lang['sub-categories'] = 'サブカテゴリ';
+$lang['synchronize metadata'] = 'メタデータを同期化する';
+$lang['synchronize'] = '同期化';
+$lang['target'] = 'ターゲット';
+$lang['thumbnail'] = 'サムネイル';
+$lang['title'] = 'タイトル';
+$lang['title_categories'] = 'カテゴリ管理';
+$lang['title_configuration'] = 'Piwigo設定';
+$lang['title_default'] = 'Piwigo管理';
+$lang['title_edit_cat'] = 'カテゴリを編集する';
+$lang['title_groups'] = 'グループ管理';
+$lang['title_liste_users'] = 'ユーザリスト';
+$lang['title_picmod'] = '写真情報を修正する';
+$lang['title_thumbnails'] = 'サムネイル作成';
+$lang['title_update'] = 'ファイルおよびデータベースの同期化';
+$lang['title_upload'] = '承認待ちの写真';
+$lang['tn_all'] = 'すべて';
+$lang['tn_alone_title'] = 'サムネイルなしの写真 (jpegおよびpngのみ)';
+$lang['tn_err_height'] = '高さは、次の値より大きくしてください:';
+$lang['tn_err_width'] = '幅は、次の値より大きくしてください:';
+$lang['tn_format'] = 'ファイルフォーマット';
+$lang['tn_no_missing'] = '不明なサムネイルはありません。';
+$lang['tn_no_support'] = '写真にアクセスできないか、次の内容がサポートされていません:';
+$lang['tn_params_GD'] = 'GDバージョン';
+$lang['tn_params_title'] = '縮小化パラメータ';
+$lang['tn_results_gen_time'] = '生成時間';
+$lang['tn_results_title'] = '縮小化の結果';
+$lang['tn_stats'] = '一般統計';
+$lang['tn_stats_max'] = '最大時間';
+$lang['tn_stats_mean'] = '平均時間';
+$lang['tn_stats_min'] = '最小時間';
+$lang['tn_stats_nb'] = '縮小化された写真数';
+$lang['tn_stats_total'] = '合計時間';
+$lang['tn_thisformat'] = 'このファイルフォーマット';
+$lang['unit mode'] = 'ユニットモード';
+$lang['unlocked'] = '未ロック';
+$lang['unset'] = '設定解除';
+$lang['up'] = 'Move up';
+$lang['update categories informations'] = 'カテゴリ情報を更新する';
+$lang['update images informations'] = 'イメージ情報を更新する';
+$lang['update'] = '同期化';
+$lang['update_cats_subset'] = '既存の単一カテゴリに減らす';
+$lang['update_default_title'] = 'オプションの選択';
+$lang['update_display_info'] = '最大限の情報を表示する (追加されたカテゴリおよびエレメント、削除されたカテゴリおよびエレメント)';
+$lang['update_err_pwg_version_differs'] = 'リモートサイトのPiwigoバージョンと異なります。';
+$lang['update_err_pwg_version_differs_info'] = 'リモートサイトのcreate_listing_file.phpおよびPiwigoは、同一である必要があります。';
+$lang['update_err_remote_listing_not_found'] = 'listing.xmlファイルが見つかりませんでした。';
+$lang['update_err_remote_listing_not_found_info'] = 'リモートサイトにlisting.xmlファイルが見つかりませんでした。このファイルは、サイトマネージャの「リスティングを生成する」コマンドを選択することで生成されます。';
+$lang['update_error_list_title'] = 'エラーリスト';
+$lang['update_errors_caption'] = 'エラーキャプション';
+$lang['update_infos_title'] = '詳細情報';
+$lang['update_missing_file_or_dir'] = 'ファイル/ディレクトリ読み込みエラー';
+$lang['update_missing_file_or_dir_info'] = 'ファイルまたはディレクトリにアクセスできません (存在していないか、アクセスが拒否されています)。';
+$lang['update_missing_tn_info'] = '写真ファイルタイプでは、サムネイルを必要とします。サムネイルは、カテゴリディレクトリのサブディレクトリ「thumbnail」に入れる必要があります。サムネイルのファイル名は、設定したサムネイル接頭辞で始まる必要があります。また、拡張子は次のリストにある拡張子を使用してください:';
+$lang['update_missing_tn_short'] = 'サムネイルがありません。';
+$lang['update_nb_del_categories'] = 'カテゴリがデータベースから削除されました。';
+$lang['update_nb_del_elements'] = 'エレメントがデータベースから削除されました。';
+$lang['update_nb_elements_metadata_available'] = 'メタデータ同期化候補のイメージ';
+$lang['update_nb_elements_metadata_sync'] = 'ファイルメタデータに同期化されたエレメント情報';
+$lang['update_nb_errors'] = '同期化中にエラーが発生しました。';
+$lang['update_nb_new_categories'] = 'カテゴリがデータベースに追加されました。';
+$lang['update_nb_new_elements'] = 'データベースにエレメントが追加されました。';
+$lang['update_nb_upd_elements'] = 'データベースのエレメントが更新されました。';
+$lang['update_part_research'] = 'ディレクトリ内の新しいイメージを検索する';
+$lang['update_research_added'] = '追加済み';
+$lang['update_research_deleted'] = '削除済み';
+$lang['update_result_metadata'] = 'メタデータ同期化結果';
+$lang['update_simulate'] = 'シミュレーションのみ実行する (データベースは更新されません)';
+$lang['update_simulation_title'] = '[シミュレーション]';
+$lang['update_sync_all'] = 'ディレクトリ + ファイル';
+$lang['update_sync_dirs'] = 'ディレクトリのみ';
+$lang['update_sync_files'] = 'ファイル構造とデータベースを同期化する';
+$lang['update_sync_metadata'] = 'ファイルメタデータとデータベースエレメント情報を同期化する';
+$lang['update_sync_metadata_all'] = 'すでに同期化されているエレメントも同期化する';
+$lang['update_used_metadata'] = '使用済みメタデータ';
+$lang['update_wrong_dirname_info'] = 'ディレクトリ名およびファイル名は、文字および記号「-」「_」「.」で構成される必要があります。';
+$lang['update_wrong_dirname_short'] = 'ファイル名が正しくありません。';
+$lang['upload'] = 'アップロード';
+$lang['user "%s" added'] = 'ユーザ "%s" が追加されました。';
+$lang['user_status'] = 'ユーザステータス';
+$lang['user_status_admin'] = '管理者';
+$lang['user_status_generic'] = '一般';
+$lang['user_status_guest'] = 'ゲスト';
+$lang['user_status_normal'] = 'ユーザ';
+$lang['user_status_webmaster'] = 'ウェブマスタ';
+$lang['username'] = 'ユーザ名';
+$lang['users'] = 'ユーザ';
+$lang['virtual_category'] = 'バーチャルカテゴリ';
+$lang['waiting'] = '承認待ち';
+$lang['is_default_group'] = 'デフォルト';
+$lang['toggle_is_default_group'] = '「デフォルトグループ」属性に切り替える';
+$lang['Advanced_features'] = '高度な機能';
+$lang['Elements_not_linked'] = '未リンクのエレメント';
+$lang['special_admin_menu'] = '特別';
+$lang['Duplicates'] = '1つ以上の物理カテゴリに存在する同一名ファイル';
+
+$lang['Overall'] = '全体';
+$lang['Year'] = '年';
+$lang['Month'] = '月';
+$lang['Day'] = '日';
+$lang['Pages seen'] = 'ページ閲覧回数';
+$lang['Pictures'] = '写真';
+$lang['time'] = '時間';
+$lang['user'] = 'ユーザ';
+$lang['IP'] = 'IP';
+$lang['image'] = '';
+$lang['section'] = 'セクション';
+$lang['tags'] = 'タグ';
+$lang['conf_history_guest'] = 'ゲストによるページアクセスを記録する';
+$lang['conf_history_user'] = 'ユーザによるページアクセスを記録する';
+$lang['conf_history_admin'] = '管理者によるページアクセスを記録する';
+$lang['cat_options_title'] = 'プロパティ';
+$lang['An information email was sent to group "%s"'] = 'グループ %s に情報メールが送信されました。';
+$lang['Send an information email to group members'] = 'グループメンバーに情報メールを送信する';
+$lang['Group'] = 'グループ';
+$lang['[%s] Come to visit the category %s'] = '[%s]  %s を訪問してください。';
+$lang['Hello,'] = 'こんにちは。';
+$lang['See you soon.'] = 'さようなら。';
+$lang['Come to discover the category:'] = 'カテゴリを見つけてください:';
+$lang['mail_content'] = 'メールコンテンツ';
+$lang['none'] = 'なし';
+$lang['high'] = '高';
+$lang['other'] = 'その他';
+$lang['Element type'] = 'エレメントタイプ';
+$lang['User'] = 'ユーザ';
+$lang['Image id'] = 'イメージID';
+$lang['Summary'] = 'サマリー';
+$lang['%d line filtered'] = '%d 行がフィルタされました。';
+$lang['%d lines filtered'] = '%d 行がフィルタされました。';
+$lang['%d guest'] = '%d ゲスト';
+$lang['%d guests'] = '%d ゲスト';
+$lang['Hour'] = '時間';
+$lang['is_the_guest'] = 'ゲスト';
+$lang['is_the_default'] = 'デフォルト値';
+$lang['High filesize'] = '最大ファイルサイズ';
+// --------- Starting below: New or revised $lang ---- from version 1.7.1
+$lang['Guest cannot be deleted'] = 'ゲストは削除できません。';
+$lang['Default user cannot be deleted'] = 'デフォルトユーザは削除できません。';
+$lang['purge history detail'] = '履歴詳細を消去する';
+$lang['purge history summary'] = '履歴サマリーを消去する';
+$lang['c13y_title'] = 'インテグリティの確認';
+$lang['c13y_Anomaly'] = '例外';
+$lang['c13y_Correction'] = '修正';
+$lang['c13y_Automatic_correction'] = '自動修正';
+$lang['c13y_Impossible_automatic_correction'] = '自動修正できません。';
+$lang['c13y_Correction_applied_success'] = '正常に修正が適用されました。';
+$lang['c13y_Correction_applied_error'] = '修正の適用にエラーが発生しました。';
+$lang['c13y_anomaly_count'] = '%d 件の例外が検出されました。';
+$lang['c13y_anomalies_count'] = '%d 件の例外が検出されました。';
+$lang['c13y_anomaly_corrected_count'] = '%d 件の例外が訂正されました。';
+$lang['c13y_anomalies_corrected_count'] = '%d 件の例外が訂正されました。';
+$lang['c13y_anomaly_not_corrected_count'] = '%d 件の例外が訂正されませんでした。';
+$lang['c13y_anomalies_not_corrected_count'] = '%d 件の例外が訂正されませんでした。';
+$lang['c13y_more_info'] = '%s へアクセスするか、%s で詳細情報をご覧ください。';
+$lang['c13y_more_info_forum'] = 'フォーラム';
+$lang['c13y_more_info_wiki'] = 'Wiki';
+$lang['c13y_exif_anomaly'] = 'exifがサポートされていないため、%s の値は正しいファイルではありません。';
+$lang['c13y_exif_correction'] = 'あなたのconfig_local.inc.phpファイルで %s は、falseに設定してください。';
+$lang['c13y_guest_non_existent'] = 'メイン「ゲスト」ユーザは存在しません。';
+$lang['c13y_bad_guest_status'] = 'メイン「ゲスト」ユーザステータスが正しくありません。';
+$lang['c13y_default_non_existent'] = 'デフォルトユーザが設定されていません。';
+$lang['c13y_webmaster_non_existent'] = 'メイン「ウェブマスタ」ユーザは存在しません。';
+$lang['c13y_bad_webmaster_status'] = 'メイン「ウェブマスタ」ユーザステータスが正しくありません。';
+$lang['c13y_user_created'] = 'ユーザ「 %s 」がパスワード「 %s 」で作成されました。';
+$lang['c13y_user_status_updated'] = 'ユーザ "%s" のステータスが更新されました。';
+$lang['add new elements to caddie'] = 'キャディに新しいエレメントを追加する';
+// --------- Starting below: New or revised $lang ---- from Butterfly
+$lang['no_display_thumbnail'] = '表示なし';
+$lang['display_thumbnail_classic'] = 'クラシック表示';
+$lang['display_thumbnail_hoverbox'] = 'ハーバーボックス表示';
+$lang['Thumbnails'] = 'サムネイル';
+$lang['obligatory_user_mail_address'] = 'すべてのユーザにメールアドレスを必須とする';
+$lang['Minimum privacy level'] = '最小プライバシーレベル';
+$lang['Privacy level'] = 'プライバシーレベル';
+$lang['Level 0'] = '---';
+$lang['Level 1'] = '連絡先';
+$lang['Level 2'] = 'フレンド';
+$lang['Level 4'] = 'ファミリー';
+$lang['Level 8'] = '管理者';
+$lang['c13y_maintenance'] = '整合性の再初期化チェック';
+$lang['Check all'] = 'すべてをチェックする';
+$lang['Uncheck all'] = 'すべてを選択解除する';
+$lang['c13y_check_auto'] = '自動修正をチェックする';
+$lang['c13y_submit_correction'] = '選択した修正を適用する';
+$lang['c13y_submit_ignore'] = '選択した例外を無視する';
+$lang['c13y_submit_refresh'] = 'リフレッシュ';
+$lang['c13y_ignore_msg1'] = '次のバージョンまで、例外は無視されます。';
+$lang['c13y_ignore_msg2'] = '無視されるため、例外の修正はキャンセルされました。';
+$lang['c13y_anomaly_ignored_count'] = '%d 件の例外が無視されました。';
+$lang['c13y_anomalies_ignored_count'] = '%d 件の例外が無視されました。';
+$lang['plugins_need_update'] = 'アップグレードが必要なプラグイン';
+$lang['plugins_dontneed_update'] = 'プラグインは最新版です。';
+$lang['plugins_cant_check'] = 'プラグインバージョンをチェックできませんでした。';
+$lang['plugins_actual_version'] = '現在の<br />バージョン';
+$lang['plugins_new_version'] = '利用可能な<br />バージョン';
+$lang['plugins_auto_update'] = '自動アップブレード';
+$lang['plugins_auto_install'] = '自動インストール';
+$lang['plugins_download'] = 'ファイルをダウンロードする';
+$lang['plugins_description'] = '<b>バージョン:</b> %s<br /><br /><b>更新日:</b> %s<br /><br />%s';
+$lang['plugins_tab_list'] = 'プラグインリスト';
+$lang['plugins_tab_update'] = 'アップデートをチェックする';
+$lang['plugins_tab_new'] = '他のプラグイン';
+$lang['plugins_revisions'] = '最新の修正';
+$lang['plugins_delete'] = '削除';
+$lang['plugins_confirm_delete'] = '本当にこのプラグインを削除してもよろしいですか?';
+$lang['plugins_confirm_install'] = '本当にこのプラグインをインストールしてもよろしいですか?';
+$lang['plugins_confirm_upgrade'] = '本当にアップグレードを実行してもよろしいですか? このバージョンをアンインストールする必要があるかどうか確認してください。';
+$lang['plugins_upgrade_ok'] = '%s が正常にアップグレードされました。';
+$lang['plugins_install_ok'] = 'プラグインが正常にコピーされました。';
+$lang['plugins_install_need_activate'] = 'プラグインをインストールおよび解凍するため、あなたはプラグイン一覧にアクセスすることができます。';
+$lang['plugins_temp_path_error'] = '一時ファイルを作成できません。';
+$lang['plugins_dl_archive_error'] = 'アーカイブをダウンロードできません。';
+$lang['plugins_archive_error'] = 'アーカイブを読めないか、解凍できません。';
+$lang['plugins_extract_error'] = '解凍中にエラーが発生しました (%s)。';
+$lang['plugins_check_chmod'] = '「プラグイン」フォルダおよびサブフォルダのパーミッションをチェック (CHMOD) してください。';
+$lang['plugins_server_error'] = 'サーバに接続できません。';
+$lang['Purge compiled templates'] = 'コンパイル済みテンプレートを削除する';
+$lang['Caddie is currently empty'] = '現在、キャディは空です。';
+$lang['conf_upload_title'] = 'アップロード';
+$lang['Show upload link every time'] = '毎回アップロードリンクを表示する';
+$lang['User access level to upload'] = 'アップロードに関するユーザアクセスレベル';
+$lang['ACCESS_0'] = 'フリーアクセス';
+$lang['ACCESS_1'] = 'すべてのユーザがアクセスできる';
+$lang['ACCESS_2'] = '登録ユーザのみアクセスできる';
+$lang['ACCESS_3'] = '管理者にアクセスする';
+$lang['ACCESS_4'] = 'ウェブマスタにアクセスする';
+$lang['ACCESS_5'] = 'アクセスなし';
+$lang['DEMO'] = 'デモ';
+$lang['HOME'] = 'Piwigoホーム';
+$lang['FORUM'] = 'サポート';
+$lang['BUGS'] = 'バグ';
+$lang['EXTENSIONS'] = '拡張モジュール';
+$lang['WIKI / DOC'] = 'ドキュメンテーション';
+$lang['A new version of Piwigo is available.'] = '新しいバージョンのPiwigoが利用可能です。';
+$lang['Piwigo Administration'] = 'Piwigo管理';
+$lang['Piwigo version'] = 'Piwigoバージョン';
+$lang['You are running the latest version of Piwigo.'] = 'あなたは最新バージョンのPiwigoを使用しています。';
+$lang['c13y_version_anomaly'] = 'インストールされている %s [%s] のバージョンは、必須バージョン [%s] に互換性がありません。';
+$lang['c13y_version_correction'] = 'アプリケーションを十分に活用するには、あなたのシステムをアップグレードする必要があります。そうでない場合、アプリケーションは正常に動作しません。';
+$lang['Deleted on'] = '削除日時';
+$lang['Last hit'] =  '最新ヒット数';
+$lang['Hits'] = 'ヒット数';
+$lang['GD library is missing'] = 'GDライブラリがありません。';
+$lang['conf_extents'] = 'テンプレート';
+$lang['extend_for_templates'] = 'テンプレートの拡張';
+$lang['Replacement of original templates'] =
+ 'template-extensionサブフォルダのテンプレートをカスタマイズして、オリジナルのテンプレートと置換します。';
+$lang['Replacers'] = '置換テンプレート (カスタマイズ済みテンプレート)';
+$lang['Original templates'] = 'オリジナルテンプレート';
+$lang['Optional URL keyword'] = '任意のURIキーワード';
+$lang['Templates recorded.'] = 'テンプレート設定が保存されました。';
+$lang['Optimizations completed'] = 'すべての最適化が正常に完了しました。';
+$lang['Optimizations errors'] = 'いくつかのエラーを含んで最適化が完了しました。';
+$lang['delete this comment'] = 'このコメントを削除する';
+$lang['link_info_image'] = '情報を修正する';
+$lang['edit category informations'] = 'カテゴリ情報を編集する';
+$lang['nothing'] = 'なし';
+$lang['overrides existing values with empty ones'] = '既存の値を空白にする';
+$lang['manage image ranks'] = 'イメージランクを管理する';
+$lang['Manage image ranks'] = 'イメージランクを管理する';
+$lang['Edit ranks'] = 'ランクを編集する';
+$lang['No element in this category'] = 'このカテゴリには、エレメントがありません。';
+$lang['Images manual order was saved'] = 'イメージ手動並び替えが保存されました。';
+$lang['ranks'] = 'ランク';
+$lang['Drag to re-order'] = 'ドラッグして並び替え';
+$lang['Unable to retrieve server informations since allow_url_fopen is disabled.'] = 'allow_url_fopenが無効にされているため、サーバ情報を取得できません。';
+$lang['Quick Local Synchronization'] = 'クイックローカル同期';
+$lang['No photo can be deleted'] = '写真は削除されませんでした。';
+$lang['Note: Only deletes photos added with pLoader'] = '注意: pLoaderに追加された写真のみ削除します。';
+$lang['Delete selected photos'] = '選択した写真を削除する';
+$lang['%d photo was deleted'] = '%d 写真が削除されました。';
+$lang['%d photos were deleted'] = '%d 写真が削除されました。';
+?>
Index: /tags/2.0.2/language/ja_JP/common.lang.php
===================================================================
--- /tags/2.0.2/language/ja_JP/common.lang.php	(revision 3278)
+++ /tags/2.0.2/language/ja_JP/common.lang.php	(revision 3278)
@@ -0,0 +1,368 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008      Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Langage informations
+$lang_info['language_name'] = 'Japanese';
+$lang_info['country'] = 'Japan';
+$lang_info['direction'] = 'ltr';
+$lang_info['code'] = 'ja';
+$lang_info['zero_plural'] = true;
+
+$lang['%.2f (rated %d times, standard deviation = %.2f)'] = '%.2f (評価 %d 回、標準偏差 = %.2f)';
+$lang['%d Kb'] = '%d Kb';
+$lang['%d category updated'] = '%d 件のカテゴリが更新されました。';
+$lang['%d categories updated'] = '%d 件のカテゴリが更新されました。';
+$lang['%d comment to validate'] = '%d 件のコメントが承認されました。';
+$lang['%d comments to validate'] = '%d 件のコメントが承認されました。';
+$lang['%d new comment'] = '新しいコメント: %d';
+$lang['%d new comments'] = '新しいコメント: %d';
+$lang['%d comment'] = 'コメント: %d';
+$lang['%d comments'] = 'コメント: %d';
+$lang['%d hit'] = 'ヒット: %d';
+$lang['%d hits'] = 'ヒット: %d';
+$lang['%d new element'] = '新しいイメージ: %d';
+$lang['%d new elements'] = '新しいイメージ: %d';
+$lang['%d new user'] = '新しいユーザ: %d';
+$lang['%d new users'] = '新しいユーザ: %d';
+$lang['%d waiting element'] = '待ちエレメント: %d';
+$lang['%d waiting elements'] = '待ちエレメント: %d';
+$lang['About'] = 'About';
+$lang['All tags must match'] = 'すべてのタグは合致する必要があります。';
+$lang['All tags'] = 'すべてのタグ';
+$lang['Any tag'] = 'すべてのtag';
+$lang['At least one listed rule must be satisfied.'] = '少なくともリスト記載ルール1つを満たす必要があります。';
+$lang['At least one tag must match'] = '少なくとも1つのタグが合致する必要があります。';
+$lang['Author'] = '撮影者';
+$lang['Average rate'] = '平均評価';
+$lang['Categories'] = 'カテゴリ';
+$lang['Category'] = 'カテゴリ';
+$lang['Close this window'] = 'このウィンドウを閉じる';
+$lang['Complete RSS feed'] = '完全なRSSフィード (イメージ、コメント)';
+$lang['Confirm Password'] = 'パスワードをもう一度';
+$lang['Connection settings'] = '接続設定';
+$lang['Connection'] = 'ログイン';
+$lang['Contact webmaster'] = 'ウェブマスタに連絡する';
+$lang['Create a new account'] = '新しいアカウントを作成する';
+$lang['Created on'] = '作成日時';
+$lang['Creation date'] = '作成日';
+$lang['Current password is wrong'] = '現在のパスワードが正しくありません。';
+$lang['Dimensions'] = 'サイズ';
+$lang['Display'] = '表示';
+$lang['Each listed rule must be satisfied.'] = 'それぞれのリスト記載ルールを満たす必要があります。';
+$lang['Email address is missing'] = 'メールアドレスがありません。';
+$lang['Email address'] = 'メールアドレス';
+$lang['Enter your personnal informations'] = 'あなたの個人情報を入力してください。';
+$lang['Error sending email'] = 'メールの送信にエラーが発生しました。';
+$lang['File name'] = 'ファイル名';
+$lang['File'] = 'ファイル';
+$lang['Filesize'] = 'ファイルサイズ';
+$lang['Filter and display'] = 'フィルタおよび表示';
+$lang['Filter'] = 'フィルタ';
+$lang['Forgot your password?'] = 'パスワードを忘れましたか?';
+$lang['Go through the gallery as a visitor'] = 'ビジターとしてギャラリーにアクセスする';
+$lang['Help'] = 'ヘルプ';
+$lang['Identification'] = 'アイデンティフィケーション';
+$lang['Image only RSS feed'] = 'イメージ限定RSSフィード';
+$lang['Keyword'] = 'キーワード';
+$lang['Links'] = 'リンク';
+$lang['Mail address'] = 'メールアドレス';
+$lang['N/A'] = 'N/A';
+$lang['New on %s'] = '最新投稿 - %s';
+$lang['New password confirmation does not correspond'] = '新しいパスワードの承認が合致しません。';
+$lang['New password sent by email'] = '新しいパスワードがメール送信しました。';
+$lang['No email address'] = 'メールアドレスがありません。';
+$lang['No user matches this email address'] = 'このメールアドレスに合致するユーザは存在しません。';
+$lang['Notification'] = '通知';
+$lang['Number of items'] = 'アイテム数';
+$lang['Original dimensions'] = 'オリジナルサイズ';
+$lang['Password forgotten'] = 'パスワードを忘れました。';
+$lang['Password'] = 'パスワード';
+$lang['Post date'] = '投稿日';
+$lang['Posted on'] = '投稿日時';
+$lang['Profile'] = 'プロファイル';
+$lang['Quick connect'] = 'クイック接続';
+$lang['RSS feed'] = 'RSSフィード';
+$lang['Rate'] = '評価';
+$lang['Register'] = '登録';
+$lang['Registration'] = '登録';
+$lang['Related tags'] = '関連タグ';
+$lang['Reset'] = 'リセット';
+$lang['Retrieve password'] = 'パスワード取得';
+$lang['Search rules'] = '検索ルール';
+$lang['Search tags'] = '検索タグ';
+$lang['Search'] = '検索';
+$lang['See available tags'] = '利用可能なタグを表示する';
+$lang['Send new password'] = '新しいパスワードを送信する';
+$lang['Since'] = 'Since';
+$lang['Sort by'] = '並び替え';
+$lang['Sort order'] = '並び順';
+$lang['Tag'] = 'タグ';
+$lang['Tags'] = 'タグ';
+$lang['The RSS notification feed provides notification on news from this website : new pictures, updated categories, new comments. Use a RSS feed reader.'] = 'RSS通知フィードでは、このウェブサイトからニュースを通知します : 新しい写真、更新カテゴリ、新しいコメント。RSSフィードリーダーをお使いください。';
+$lang['Unknown feed identifier'] = '不明なフィードIDです。';
+$lang['User comments'] = 'ユーザコメント';
+$lang['Username'] = 'ユーザ名';
+$lang['Visits'] = '訪問';
+$lang['Webmaster'] = 'ウェブマスタ';
+$lang['Week %d'] = '週 %d';
+$lang['about_page_title'] = 'About Piwigo';
+$lang['access_forbiden'] = 'あなたは、リクエストしたページへのアクセスを許可されていません。';
+$lang['add to caddie'] = 'キャディに追加する';
+$lang['add_favorites_hint'] = 'このイメージをあなたのお気に入りに追加する';
+$lang['admin'] = '管理';
+$lang['adviser_mode_enabled'] = 'アドバイザーモードが有効にされました。';
+$lang['all'] = 'すべて';
+$lang['ascending'] = '昇順';
+$lang['author(s) : %s'] = '作者 : %s';
+$lang['auto_expand'] = 'すべてのカテゴリを拡げる';
+$lang['became available after %s (%s)'] = '%s (%s) 以降に投稿';
+$lang['became available before %s (%s)'] = '%s (%s) 以前に投稿';
+$lang['became available between %s (%s) and %s (%s)'] = '%s (%s) から %s (%s) の間に投稿';
+$lang['became available on %s'] = '%s に投稿';
+$lang['best_rated_cat'] = '最高評価';
+$lang['best_rated_cat_hint'] = '最高評価アイテムを表示する';
+$lang['caddie'] = 'キャディー';
+$lang['calendar'] = 'カレンダー';
+$lang['calendar_any'] = 'すべて';
+$lang['calendar_hint'] = '月ごとに写真の投稿日を表示します。';
+$lang['calendar_picture_hint'] = '写真の追加日を表示します。';
+$lang['calendar_view'] = '表示';
+$lang['chronology_monthly_calendar'] = '月カレンダー';
+$lang['chronology_monthly_list'] = '月リスト';
+$lang['chronology_weekly_list'] = '週リスト';
+$lang['click_to_redirect'] = '自動的にリダイレクトされない場合、ここをクリックしてください。';
+$lang['comment date'] = 'コメント投稿日';
+$lang['comment'] = 'コメント';
+$lang['comment_added'] = 'あなたのコメントが登録されました。';
+$lang['comment_anti-flood'] = 'アンチフラッドシステム : 新たに投稿するまで、しばらくお待ちください。';
+$lang['comment_not_added'] = '承認ルールにパスしなかったため、あなたのコメントは登録されませんでした。';
+$lang['comment_to_validate'] = '表示される前に管理者があなたのコメントを承認する必要があります。';
+$lang['comment_user_exists'] = 'このユーザIDは、すでに別のユーザに使用されています。';
+$lang['comments'] = 'コメント';
+$lang['comments_add'] = 'コメントを追加する';
+$lang['created after %s (%s)'] = '%s (%s) 以降に作成';
+$lang['created before %s (%s)'] = '%s (%s) 以前に作成';
+$lang['created between %s (%s) and %s (%s)'] = '%s (%s) から %s (%s) の間に作成';
+$lang['created on %s'] = '%s に作成';
+$lang['customize'] = 'カスタマイズ';
+$lang['customize_page_title'] = 'あなたのギャラリーカスタマイズ ';
+$lang['day'][0] = '日曜日';
+$lang['day'][1] = '月曜日';
+$lang['day'][2] = '火曜日';
+$lang['day'][3] = '水曜日';
+$lang['day'][4] = '木曜日';
+$lang['day'][5] = '金曜日';
+$lang['day'][6] = '土曜日';
+$lang['default_sort'] = 'デフォルト';
+$lang['del_favorites_hint'] = 'あなたのお気に入りから、このイメージを削除する';
+$lang['delete'] = '削除';
+$lang['descending'] = '降順';
+$lang['download'] = 'ダウンロード';
+$lang['download_hint'] = 'このファイルをダウンロードする';
+$lang['edit'] = '編集';
+$lang['err_date'] = '日付が正しくありません。';
+$lang['excluded'] = '除外';
+$lang['favorite_cat'] = 'お気に入り';
+$lang['favorite_cat_hint'] = '私のお気に入りの写真を表示する';
+$lang['favorites'] = 'お気に入り';
+$lang['first_page'] = '最初へ';
+$lang['gallery_locked_message'] = 'このカテゴリは、メンテナンスのためロックされています。後ほどアクセスしてください。';
+$lang['generation_time'] = 'ページ作成:';
+$lang['guest'] = 'ゲスト';
+$lang['hello'] = 'こんにちは';
+$lang['hint_admin'] = '管理者のみ利用可能です。';
+$lang['hint_category'] = 'このカテゴリのルートのイメージを表示する';
+$lang['hint_comments'] = '最新のユーザコメントを表示する';
+$lang['hint_customize'] = 'ギャラリーのアピアランスをカスタマイズする';
+$lang['hint_search'] = '検索';
+$lang['home'] = 'ホーム';
+$lang['identification'] = 'アイデンティフィケーション';
+$lang['images_available_cpl'] = '- このカテゴリ';
+$lang['images_available_cat'] = '- %d サブカテゴリ';
+$lang['images_available_cats'] = '- %d サブカテゴリ';
+$lang['included'] = '含む';
+$lang['invalid_pwd'] = 'パスワードが正しくありません!';
+$lang['language']='言語';
+$lang['last %d days'] = '直近 %d 日';
+$lang['last_page'] = '最後へ';
+$lang['logout'] = 'ログアウト';
+$lang['mail_address'] = 'メールアドレス';
+$lang['mandatory'] = '必須';
+$lang['maxheight'] = '写真の最大高';
+$lang['maxheight_error'] = '最大高は、50以上に設定してください。';
+$lang['maxwidth'] = '写真の最大幅';
+$lang['maxwidth_error'] = '最大幅は、50以上に設定してください。';
+$lang['mode_created_hint'] = '作成日のカレンダーを表示する';
+$lang['mode_flat_hint'] = 'すべてのサブカテゴリのエレメント表示する';
+$lang['mode_normal_hint'] = 'ノーマルビューモードに戻る';
+$lang['mode_posted_hint'] = '投稿日のカレンダーを表示する';
+$lang['month'][10] = '10月';
+$lang['month'][11] = '11月';
+$lang['month'][12] = '12月';
+$lang['month'][1] = '1月';
+$lang['month'][2] = '2月';
+$lang['month'][3] = '3月';
+$lang['month'][4] = '4月';
+$lang['month'][5] = '5月';
+$lang['month'][6] = '6月';
+$lang['month'][7] = '7月';
+$lang['month'][8] = '8月';
+$lang['month'][9] = '9月';
+$lang['most_visited_cat'] = '最多アクセス';
+$lang['most_visited_cat_hint'] = '最もアクセスされた写真を表示します。';
+$lang['nb_image_line_error'] = '1行あたりのイメージ数には、空白以外の値を設定してください。';
+$lang['nb_image_per_row'] = '1行あたりのイメージ数';
+$lang['nb_line_page_error'] = '1ページあたりの行数には、空白以外の値を設定してください。';
+$lang['nb_row_per_page'] = '1ページあたりの行数';
+$lang['nbm_unknown_identifier'] = '不明なID';
+$lang['new_password'] = '新しいパスワード';
+$lang['new_rate'] = 'この写真を評する';
+$lang['next_page'] = '次へ';
+$lang['no_category'] = 'ホーム';
+$lang['no_rate'] = '評価なし';
+$lang['note_filter_day'] = '直近 %d 日に投稿されたエレメントのみ表示します。';
+$lang['note_filter_days'] = '直近 %d 日に投稿されたエレメントのみ表示します。';
+$lang['password updated'] = 'パスワードが更新されました。';
+$lang['periods_error'] = '最近の期間には正の整数を設定してください。';
+/* DEPRECATED USED IN comments.php FOR image_id ? */ $lang['picture'] = 'picture';
+$lang['picture_high'] = '高解像度の写真を表示するには、写真をクリックしてください。';
+$lang['picture_show_metadata'] = 'ファイルメタデータを表示する';
+$lang['powered_by'] = 'Powered by';
+$lang['preferences'] = 'プリファレンス';
+$lang['previous_page'] = '前へ';
+$lang['random_cat'] = 'ランダム写真';
+$lang['random_cat_hint'] = '一連のランダム写真を表示します。';
+$lang['recent_cats_cat'] = '最近のカテゴリ';
+$lang['recent_cats_cat_hint'] = '最近更新されたカテゴリを表示します。';
+$lang['recent_period'] = '最近の期間';
+$lang['recent_pics_cat'] = '最近の写真';
+$lang['recent_pics_cat_hint'] = '最近の写真を表示します。';
+$lang['redirect_msg'] = 'リダイレクト ...';
+$lang['reg_err_login1'] = 'ユーザIDを入力してください。';
+$lang['reg_err_login2'] = 'ユーザIDの末尾にスペースを使用しないでください。';
+$lang['reg_err_login3'] = 'ユーザIDの最初にスペースを使用しないでください。';
+$lang['reg_err_login5'] = 'このユーザIDは、すでに使用されています。';
+$lang['reg_err_mail_address'] = 'メールアドレスは、xxx@yyy.eee のようなフォーマットを使用してください (例 : jack@altern.org)。';
+$lang['reg_err_pass'] = 'あなたのパスワードを再度入力してください。';
+$lang['remember_me'] = '自動ログイン';
+$lang['remove this tag'] = 'このタグをリストから削除する';
+$lang['representative'] = '見本';
+$lang['return to homepage'] = 'ホームページに戻る';
+$lang['search_author'] = '作者で探す';
+$lang['search_categories'] = 'カテゴリを探す';
+$lang['search_date'] = '日付で探す';
+$lang['search_date_from'] = '日付';
+$lang['search_date_to'] = '終了日';
+$lang['search_date_type'] = '日付タイプ';
+$lang['search_keywords'] = '言葉で探す';
+$lang['search_mode_and'] = 'すべてを含む';
+$lang['search_mode_or'] = '少なくとも一つを含む';
+$lang['search_one_clause_at_least'] = '空のクエリーです。検索キーワードが入力されていません。';
+$lang['search_options'] = '検索オプション';
+$lang['search_result'] = '検索結果';
+$lang['search_subcats_included'] = 'サブカテゴリを探す';
+$lang['search_title'] = '検索';
+$lang['searched words : %s'] = '検索キーワード : %s';
+$lang['send_mail'] = '連絡:';
+$lang['set as category representative'] = 'カテゴリ見本を設定する';
+$lang['show_nb_comments'] = 'コメント数を表示する';
+$lang['show_nb_hits'] = 'ヒット数を表示する';
+$lang['slideshow'] = 'スライドショー';
+$lang['slideshow_stop'] = 'スライドショーを停止する';
+$lang['special_categories'] = '特別';
+$lang['sql_queries_in'] = 'SQLクエリー:';
+$lang['start_filter_hint'] = '最近投稿されたイメージのみ表示する';
+$lang['stop_filter_hint'] = 'すべてのイメージ表示に戻る';
+$lang['the beginning'] = '最初';
+$lang['theme'] = 'インターフェーステーマ';
+$lang['thumbnails'] = 'サムネイル';
+$lang['title_menu'] = 'メニュー';
+$lang['title_send_mail'] = 'あなたのサイトのコメント';
+$lang['today'] = '今日';
+$lang['update_rate'] = 'あなたの評価を更新する';
+$lang['update_wrong_dirname'] = 'ファイル名が正しくありません。';
+$lang['upload_advise_filesize'] = '許可された写真のファイルサイズを超えないでください : ';
+$lang['upload_advise_filetype'] = '写真のフォーマットは、jpg、gif、pngを使用してください。';
+$lang['upload_advise_height'] = '許可された写真の高さを超えないでください : ';
+$lang['upload_advise_thumbnail'] = '任意ですが推奨します : 関連付けるサムネイルを選択してください。 ';
+$lang['upload_advise_width'] = '許可された写真の幅を超えないでください : ';
+$lang['upload_author'] = '作者';
+$lang['upload_cannot_upload'] = 'サーバに写真をアップロードできません。';
+$lang['upload_err_username'] = 'ユーザ名を入力してください。';
+$lang['upload_file_exists'] = 'すでに同じ写真名が使用されています。';
+$lang['upload_filenotfound'] = 'イメージの写真ファイルフォーマットを選択してください。';
+$lang['upload_forbidden'] = 'あなたは、このカテゴリに写真をアップロードできません。';
+$lang['upload_name'] = '写真名';
+$lang['upload_picture'] = '写真をアップロードする';
+$lang['upload_successful'] = '写真が正常にアップロードされました。管理者が早急に写真を承認します。';
+$lang['upload_title'] = '写真をアップロードする';
+$lang['useful when password forgotten'] = 'パスワードを忘れたときに便利です。';
+$lang['qsearch'] = 'クイックサーチ';
+$lang['Connected user: %s'] = '接続ユーザ: %s';
+$lang['IP: %s'] = 'IP: %s';
+$lang['Browser: %s'] = 'ブラウザ: %s';
+$lang['Author: %s'] = '撮影者: %s';
+$lang['Comment: %s'] = 'コメント: %s';
+$lang['Delete: %s'] = '削除: %s';
+$lang['Validate: %s'] = '承認: %s';
+$lang['Comment by %s'] = 'コメント by %s';
+$lang['User: %s'] = 'ユーザ: %s';
+$lang['Email: %s'] = 'メールアドレス: %s';
+$lang['Admin: %s'] = '管理者: %s';
+$lang['Registration of %s'] = '%s の登録';
+$lang['Category: %s'] = 'カテゴリ: %s';
+$lang['Picture name: %s'] = '写真名: %s';
+$lang['Creation date: %s'] = '作成日: %s';
+$lang['Waiting page: %s'] = '待ちページ: %s';
+$lang['Picture uploaded by %s'] = '%s によりアップロードされた写真';
+// --------- Starting below: New or revised $lang ---- from version 1.7.1
+$lang['guest_must_be_guest'] = 'デフォルトステータスの使用に関して、ユーザ「ゲスト」は正しくないステータスです。ウェブマスタにご連絡ください。';
+// --------- Starting below: New or revised $lang ---- from Butterfly (2.0)
+$lang['Administrator, webmaster and special user cannot use this method'] = '管理者、ウェブマスタおよび特別ユーザは、この方法を使用できません。';
+$lang['reg_err_mail_address_dbl'] = 'このメールアドレスは、すでに他のユーザに使用されています。';
+$lang['Category results for'] = 'カテゴリ検索結果:';
+$lang['Tag results for'] = 'タグ検索結果:';
+$lang['from %s to %s'] = '%s - %s';
+$lang['start_play'] = 'スライドショーを実行する';
+$lang['stop_play'] = 'スライドショーを一時停止する';
+$lang['start_repeat'] = 'スライドショーを繰り返す';
+$lang['stop_repeat'] = 'スライドショーを繰り返さない';
+$lang['inc_period'] = 'スライドショーのスピードを減らす';
+$lang['dec_period'] = 'スライドショーのスピードを増やす';
+$lang['Submit'] = '送信';
+$lang['Yes'] = 'Yes';
+$lang['No'] = 'No';
+$lang['%d element']='イメージ: %d';
+$lang['%d elements']='イメージ: %d';
+$lang['%d element are also linked to current tags'] = '%d イメージも現在のタグにリンクされました。';
+$lang['%d elements are also linked to current tags'] = '%d イメージも現在のタグにリンクされました。';
+$lang['See elements linked to this tag only'] = 'このタグのみにリンクされているイメージを表示する';
+$lang['elements posted during the last %d days'] = '直近 %d 日に投稿されたイメージ';
+$lang['Choose an image'] = 'イメージを選択する';
+$lang['Piwigo Help'] = 'Piwigoヘルプ';
+$lang['Rank'] = 'ランク';
+$lang['group by letters'] = '文字でグループ化する';
+$lang['letters'] = '文字';
+$lang['show tag cloud'] = 'タグクラウドを表示する';
+$lang['cloud'] = 'クラウド';
+?>
Index: /tags/2.0.2/language/ja_JP/help.html
===================================================================
--- /tags/2.0.2/language/ja_JP/help.html	(revision 3278)
+++ /tags/2.0.2/language/ja_JP/help.html	(revision 3278)
@@ -0,0 +1,233 @@
+<div class="instructions">
+<h2>ヘルプ</h2>
+
+<div id="instructionPLoader" class="instructionBlock">
+  <div 
+	id="pLoader_header" 
+	class="instructionBlockHeaderCollapsed"
+	onclick="blockToggleDisplay('pLoader_header', 'pLoader_content')"
+  ><span>
+    ApLoaderで写真を追加する方法
+  </span></div>
+  <div id="pLoader_content" class="instructionBlockContent" style="display: none;">
+    <ol>
+      <li>あなたのPiwigoインストレーション内のディレクトリ「galleries」配下に書込み権のあるディレクトリ「upload」を作成してください。</li>
+      <li>あなたのコンピュータにpLoaderをインストールした後、起動してください。そして、接続情報を設定してください: あなたのギャラリーURI、ユーザ名およびパスワード</li>
+      <li>あなたのディレクトリブラウザからpLoaderの写真セクションに写真をドラッグ&ドロップしてください。</li>
+      <li>カテゴリを作成して、そのカテゴリを選択してください。</li>
+      <li>写真を選択してください。</li>
+      <li>あなたのギャラリーに写真を転送するには、緑の矢印をクリックしてください。</li>
+    </ol>
+おめでとうございます! あなたは、フォトギャラリーの最初のカテゴリの作成に成功しました。
+  </div> <!-- pLoader_content -->
+</div> <!-- instructionPLoader -->
+
+<div id="instructionFTP" class="instructionBlock">
+  <div id="FTP_header" class="instructionBlockHeaderCollapsed" onclick="blockToggleDisplay('FTP_header', 'FTP_content')"><span>
+    FTPで写真を追加する方法
+  </span></div>
+  <div id="FTP_content" class="instructionBlockContent" style="display: none;">
+
+<h3>クイックスタート</h3>
+
+<ol>
+  <li>あなたのコンピュータにディレクトリを作成してください。</li>  
+
+  <li>このディレクトリ内に写真をコピーした後、ウェブ表示のため、写真をリサイズしてください。
+  <em>警告</em>: ディレクトリおよびファイル名には、文字、「-」「_」「.」の記号のみ含んでください。空白、アクセント符号は含まないでください。</li>
+
+  <li>FTPクライアントを使って、あなたのPiwigoインストレーションの「galleries」ディレクトリにディレクトリをコピーしてください。</li>
+
+  <li>あなたのギャラリーにログインして、未作成のサムネイルを作成するため、「<span class="pwgScreen">管理 > 写真 > サムネイル</span>」に移動してください。</li>
+
+  <li>「<span class="pwgScreen">管理</span>」に移動して、大きな「クイックローカル同期」ボタンをクリックしてください。</li>
+</ol>
+
+おめでとうございます! あなたは、フォトギャラリーの最初のカテゴリの作成に成功しました。 
+
+<h3>ディレクトリおよびファイル構造</h3>
+<ul>
+
+  <li>
+
+    <p>ギャラリーディレクトリは、Piwigoディレクトリ「galleries」にあります。以下、非常に小さな (しかし、多くの特長を持つ) ギャラリーのディレクトリツリーの例です:</p>
+
+    <pre>.
+|-- admin
+|-- doc
+|-- galleries
+|   |-- category-1
+|   |   |-- category-1.1
+|   |   |   |-- category-1.1.1
+|   |   |   |   |-- category-1.1.1.1
+|   |   |   |   |   |-- pwg_high
+|   |   |   |   |   |   +-- wedding.jpg
+|   |   |   |   |   |-- thumbnail
+|   |   |   |   |   |   +-- TN-wedding.jpg
+|   |   |   |   |   +-- wedding.jpg
+|   |   |   |   +-- category-1.1.1.2
+|   |   |   +-- category-1.1.2
+|   |   |-- category-1.2
+|   |   |   |-- pookie.jpg
+|   |   |   +-- thumbnail
+|   |   |       +-- TN-pookie.jpg
+|   |   +-- category-1.3
+|   +-- category-2
+|       |-- piglet.gif
+|       |-- pwg_representative
+|       |   +-- video.jpg
+|       |-- thumbnail
+|       |   +-- TN-piglet.jpg
+|       +-- video.avi
+|-- include
+|-- install
+|-- language
+|-- template
++-- tool</pre>
+
+  </li>
+  
+  <li>「galleries」配下の各ディレクトリは、カテゴリを表します。カテゴリの深さに制限はありません。</li>
+
+  <li>基本的に、エレメントはファイルによって表されます。
+  ファイル拡張子が設定パラメータの<code>file_ext</code>内にある場合、ファイルはPiwigoのエレメントになることができます (詳細は、<span class="filename">include/config_default.inc.php</span>ファイルをご覧ください)。</li>
+
+  <li>写真エレメントは、サムネイルと関連付ける必要があります (詳細は、下記サムネイルの項目をご覧ください)。</li>
+
+  <li>写真エレメントは、高品質のファイルを関連付けることができます。上記例では、wedding.jpgです。高品質の写真には、接頭辞がありません。</li>
+
+  <li>デフォルトでは、写真エレメント (ビデオ、サウンド、テキスト等) に関して、ファイル名の拡張子に関連付けられるアイコンはありません。
+  任意で、あなたはサムネイルおよび見本ファイルを関連付けることができます (上記例のvideo.aviをご覧ください)。</li>
+
+  <li><em>警告</em>: ディレクトリおよびファイル名には、文字、「-」「_」「.」の記号のみ含んでください。空白、アクセント符号は含まないでください。</li>
+
+  <li>ファイル、サムネイルおよび見本が正しくディレクトリに配置された場合、「<span class="pwgScreen">管理 > カテゴリ > 同期化</span>」に移動してください。</li>
+
+</ul>
+
+<h3>サムネイル</h3>
+<ul>
+
+  <li>それぞれの写真は、サムネイルを持つ必要があります。</li>
+
+  <li>サムネイルは、カテゴリディレクトリ内のサブディレクトリ「thumbnail」に保存されます。
+  サムネイルは、関連する写真のファイル名に接頭辞「<em>TN-</em>」を付けたファイル名となります。</li>
+
+  <li><em>アドバイス</em>: サムネイルの作成には、外部モジュールをお使いください。</li>
+
+  <li>(イメージクオリティ、ウェブサーバリソースのロードに関して) 推奨はできませんが、あなたはサムネイルの作成に「<span class="pwgScreen">管理 > 写真 > サムネイル</span>」ページを使用することができます。</li>
+
+  <li>すべてのカテゴリディレクトリに書込み権を与えてください。</li>
+
+</ul>
+
+  </div> <!-- FTP_content -->
+</div> <!-- instructionFTP -->
+
+<div id="instructionPermissions" class="instructionBlock">
+  <div id="permissions_header" class="instructionBlockHeaderCollapsed" onclick="blockToggleDisplay('permissions_header', 'permissions_content')"><span>
+    パーミッション
+  </span></div>
+  <div id="permissions_content" class="instructionBlockContent" style="display: none;">
+<ul>
+
+  <li>あなたは、カテゴリへのアクセスを禁止することができます。あなたがパーミッションを管理したい場合、カテゴリアクセスタイプを「プライベート」に変更してください。</li>
+
+  <li>あなたは、単一のカテゴリを編集 (<span class="pwgScreen">管理 > カテゴリ > 管理 > 編集</span>) または、
+  すべてのカテゴリツリーを設定 (<span class="pwgScreen">管理 > カテゴリ > プロパティ> パブリック/プライベート</span>) することで、カテゴリをプライベートにすることができます。</li>
+
+  <li>
+
+    <p>カテゴリがプライベートにされた場合、あなたはグループおよびユーザのパーミッションを3つの画面で管理することができます:</p>
+
+    <ul>
+
+      <li><span class="pwgScreen">管理 > アイデンティフィケーション > ユーザ > パーミッション</span> (1ユーザにつき1リンク)</li>
+
+      <li><span class="pwgScreen">管理 > アイデンティフィケーション > グループ > パーミッション</span> (1グループにつき1リンク)</li>
+
+      <li><span class="pwgScreen">管理 > カテゴリ > カテゴリパーミッションの編集</span> (1カテゴリにつき1リンク)</li>
+
+    </ul>
+
+  </li>
+
+</ul>
+  </div> <!-- permissions_content --> 
+</div> <!-- instructionPermissions -->
+
+<div id="instructionGroups" class="instructionBlock">
+  <div id="groups_header" class="instructionBlockHeaderCollapsed" onclick="blockToggleDisplay('groups_header', 'groups_content')"><span>
+    グループ
+  </span></div>
+  <div id="groups_content" class="instructionBlockContent" style="display: none;">
+<ul>
+
+  <li>一連のユーザにパーミッションを設定することに関して、グループは便利な方法です。</li>
+
+  <li>「<span class="pwgScreen">管理 > アイデンティフィケーション > グループ</span>」でグループを作成した後、「<span class="pwgScreen">管理 > アイデンティフィケーション > ユーザ</span>」で、ユーザをグループに関連付けてください。</li>
+
+  <li>ユーザは、いくつかのグループに属することができます。
+  許可は、禁止より強くなります: ユーザ「jack」がグループ「family」に属して、グループ「family」のみカテゴリ「Christmas 2003」を閲覧できるとすると、
+  「jack」はカテゴリ「Christmas 2003」を閲覧することができます。</li>
+
+</ul>
+  </div> <!-- groups_content --> 
+</div> <!-- instructionGroups -->
+
+<div id="instructionUpload" class="instructionBlock">
+  <div id="upload_header" class="instructionBlockHeaderCollapsed" onclick="blockToggleDisplay('upload_header', 'upload_content')"><span>
+    ユーザによるアップロード
+  </span></div>
+  <div id="upload_content" class="instructionBlockContent" style="display: none;">
+<p>ユーザは自分の写真をアップロードすることもできます。</p>
+
+<ol>
+
+  <li>物理カテゴリにアップロードを許可します (「<span class="pwgScreen">管理 > カテゴリ > 管理 > 編集</span>」または「<span class="pwgScreen">管理 > カテゴリ > プロパティ > アップロード</span>」)。バーチャルカテゴリには、アップロードすることができません。</li>
+
+  <li>対応するディレクトリに書込み権を与えてください。</li>
+
+</ol>
+
+<p>ユーザがアップロードした写真は、ウェブサイトから直接閲覧できるということではありません。
+管理者は、アップロードされた写真を「<span class="pwgScreen">管理 > 写真 > 承認待ち</span>」で承認する必要があります。</p>
+  </div> <!-- upload_content --> 
+</div> <!-- instructionUpload -->
+
+<div id="instructionCategoryLinks" class="instructionBlock">
+  <div id="categoryLinks_header" class="instructionBlockHeaderCollapsed" onclick="blockToggleDisplay('categoryLinks_header', 'categoryLinks_content')"><span>
+    写真、カテゴリおよびバーチャルカテゴリ間のリンク
+  </span></div>
+  <div id="categoryLinks_content" class="instructionBlockContent" style="display: none;">
+<ul>
+
+  <li>写真は、ファイルディレクトリに関連するカテゴリ内に表示されます。</li>
+
+  <li>ウェブサーバ内で複製せず、あなたは複数のカテゴリで写真を表示することができます。
+  (管理者がギャラリーの写真ページからアクセスできる) 写真編集画面でカテゴリと写真を関連付けてください。</li>
+
+  <li>バーチャルディレクトリは、このコンセプトに基づいています: バーチャルディレクトリには、対応するカテゴリが存在しません。
+  バーチャルカテゴリを「<span class="pwgScreen">管理 > カテゴリ > 管理</span>」にて作成してください。</li>
+
+</ul>
+  </div> <!-- categoryLinks_content --> 
+</div> <!-- instructionCategoryLinks -->
+
+<div id="instructionMisc" class="instructionBlock">
+  <div id="misc_header" class="instructionBlockHeaderCollapsed" onclick="blockToggleDisplay('misc_header', 'misc_content')"><span>
+    その他の情報
+  </span></div>
+  <div id="misc_content" class="instructionBlockContent" style="display: none;">
+<ul>
+
+  <li>あなたのギャラリーを作成したらすぐに、「<span class="pwgScreen">管理 > 設定 > デフォルト</span>」にて、デフォルト表示プロパティを変更してください。 
+  すべての新規登録ユーザは、これらのデフォルト設定を使用することになります。</li>
+
+  <li>あなたに質問がある場合、Piwigoコミュニティは、あなたを<a href="http://forum.phpwebgallery.net/">フォーラム</a>で歓迎します。</li>
+
+</ul>
+  </div> <!-- misc_content --> 
+</div> <!-- instructionMisc -->
+
+</div>
Index: /tags/2.0.2/language/ja_JP/help/advanced_feature.html
===================================================================
--- /tags/2.0.2/language/ja_JP/help/advanced_feature.html	(revision 3278)
+++ /tags/2.0.2/language/ja_JP/help/advanced_feature.html	(revision 3278)
@@ -0,0 +1,16 @@
+<h2>高度な機能</h2>
+
+<p>PWG管理エキスパート用の特別機能一覧です:</p>
+
+<ul>
+
+  <li>
+    <strong>未リンクのエレメント:</strong>
+    どのバーチャルカテゴリにも関連付けられていないイメージを表示します。
+  </li>
+  <li>
+    <strong>1つ以上の物理カテゴリに存在する同一名ファイル:</strong>
+    複数カテゴリで見つかった同一ファイル名のイメージまたはファイルを表示します。
+  </li>
+
+</ul>
Index: /tags/2.0.2/language/ja_JP/help/cat_modify.html
===================================================================
--- /tags/2.0.2/language/ja_JP/help/cat_modify.html	(revision 3278)
+++ /tags/2.0.2/language/ja_JP/help/cat_modify.html	(revision 3278)
@@ -0,0 +1,127 @@
+<h2>カテゴリを編集する</h2>
+
+<h3>情報</h3>
+
+<ul>
+
+  <li><strong>名称</strong>: カテゴリをリネームします (物理カテゴリの場合、バーチャルリネームとなります)。</li>
+
+  <li><strong>説明</strong>: コンテンツに一般的なアイディアを与えます。このテキストは、サムネイルの下に表示されます。</li>
+
+</ul>
+
+<h3>移動</h3>
+
+<p>カテゴリがバーチャルカテゴリの場合、あなたはカテゴリを移動することができます。
+カテゴリを移動することは、そのカテゴリの親カテゴリを変更することを意味します。</p>
+
+<h3>オプション</h3>
+
+<ul>
+
+  <li><strong>アクセスタイプ</strong>: パーミッション管理。あなたがカテゴリをプライベートにした場合、
+  すべての子カテゴリもプライベートになります。あなたがカテゴリをパブリックにした場合、
+  すべての親カテゴリもパブリックになります。</li>
+
+  <li><strong>ロック</strong>: メンテナンスのため、カテゴリおよびサブカテゴリが一時的に無効にされます。</li>
+
+  <li><strong>コメント</strong>: このカテゴリのコンテンツに関して、認証ユーザのコメント投稿を許可します。</li>
+
+  <li><strong>アップロードを許可する</strong>: ユーザのファイルアップロードを許可します。
+  このオプションは、(バーチャルカテゴリではなく) 物理カテゴリでのみ使用できます。</li>
+
+</ul>
+
+<p>あなたは、これらのオプションを「プロパティ」管理画面 (<span class="pwgScreen">管理 > カテゴリ > プロパティ</span> > <span class="pwgScreen">アップロード</span>、<span
+class="pwgScreen">コメント</span>、<span class="pwgScreen">ロック</span>,
+<span class="pwgScreen">パブリック/プライベート</span>, <span
+class="pwgScreen">見本</span>) で管理することもできます。</p>
+
+<h3>並び順</h3>
+
+<p>デフォルトの並び順を使用する場合、選択してください。</p>
+
+<p>この並び順がサブカテゴリに適用される場合、指定してください。</p>
+
+<p>このカテゴリで使用するカラムの並び順を選択してください。</p>
+<ul>
+<li><strong>作成日</strong>: 写真の作成日</li>
+<li><strong>投稿日</strong>: 同期化日</li>
+<li><strong>平均評価 (*)</strong>: 平均評価は、ビジターによって変わります。</li>
+<li><strong>最多アクセス (*)</strong>: 現在の訪問件数を最多アクセス順に変更します。</li>
+<li><strong>ファイル名</strong>: 情報フィールドに入力された名称です。</li>
+<li><strong>ID</strong>: 内部ID (新しいカテゴリは、前のカテゴリより高いIDを持ちます。</li>
+
+</ul>
+<p><strong>(*)</strong>予測できない結果となる場合がありますので、実行前に十分なテストを実施してください。</p>
+
+
+<h3>見本</h3>
+
+<p>カテゴリの見本は、カテゴリが (ルートカテゴリのように) サブカテゴリのみ含む場合、
+メインページ (<span class="pwgScreen">category.php</span>) に表示されるサムネイルです。</p>
+
+<p>カテゴリの見本を設定するには、4つの方法があります。 :</p>
+
+<ul>
+
+  <li><span class="pwgScreen">写真ページ</span>: アクションボタンの1つをクリックすることで、
+  あなたは表示されている写真を表示カテゴリの見本に設定することができます。
+  このボタンは、管理者のみ利用することができます。</li>
+
+  <li>管理ページで<span class="pwgScreen">写真情報を修正する</span>。
+  この画面には、<span class="pwgScreen">picture.php</span>またはユニットモードの<span class="pwgScreen">バッチ管理</span>からアクセスすることができます。
+  詳細は、このページのヘルプをご覧ください。</li>
+
+  <li><span class="pwgScreen">「管理 > カテゴリ > プロパティ > 見本」。
+  詳細は、このページのヘルプをご覧ください。</li>
+
+  <li><span class="pwgScreen">カテゴリを編集する</span> (この画面)。</li>
+
+</ul>
+
+<p>見本は、設定パラメータ「<code>allow_random_representative</code>」の設定に依存します
+ (詳細は、<span class="filename">include/config_default.inc.php</span>をご覧ください)。</p>
+
+<p>デフォルトモード (<code>allow_random_representative</code> = false) の場合、
+それぞれのカテゴリには、少なくとも1つの固定されたエレメントが見本にされます。
+(カテゴリ作成時に) 設定した場合、見本は、管理者が求める場合のみ変更することができます。
+見本が適切ではない場合、あなたは<strong>新しい見本をランダムに探す</strong>を使って、新しい見本を探すことができます。</p>
+
+<p>設定パラメータ「<code>allow_random_representative</code>」にtrueが設定された場合、
+エレメントを含んだカテゴリは、固定の見本を持つことができません。
+<strong>見本を削除する</strong>ボタンを使用してください。</p>
+
+<p>カテゴリに (サブカテゴリのみで) エレメントが含まれていない場合、<span class="pwgScreen">写真情報を修整する</span>画面を使って、
+どのような写真でも見本にすることができます。現在の画面で使用できるオプションは、<strong>見本を削除する</strong>ボタンのみです。
+このボタンを使用した場合、見本は設定されないようになります。</p>
+
+<h3すべてのカテゴリエレメントを新しいカテゴリにリンクする</h3>
+
+<ul>
+
+<li><strong>バーチャルカテゴリ名</strong>: 作成される新しいカテゴリ名です。
+現在のカテゴリ内にある、すべての写真は新しいカテゴリにリンクされます。</li>
+
+<li><strong>親カテゴリ</strong>: 新しいカテゴリがどこに作成されるか選択してください。
+未選択の場合、ホームカテゴリとして作成されます。</li>
+
+</ul>
+
+<h3>すべてのカテゴリエレメントを既存のカテゴリにリンクする</h3>
+
+<ul>
+
+<li><strong>カテゴリ</strong>: リンク先のカテゴリを選択してください。</li>
+
+</ul>
+
+<h3>グループメンバーに情報メールを送信する</h3>
+
+<ul>
+
+<li><strong>グループ</strong>: 受信グループ</li>
+
+<li><strong>メールコンテンツ</strong>: グループに送信するテキストです。</li>
+
+</ul>
Index: /tags/2.0.2/language/ja_JP/help/cat_move.html
===================================================================
--- /tags/2.0.2/language/ja_JP/help/cat_move.html	(revision 3278)
+++ /tags/2.0.2/language/ja_JP/help/cat_move.html	(revision 3278)
@@ -0,0 +1,14 @@
+<h2>バーチャルカテゴリを移動する</h2>
+
+<p>バーチャルカテゴリのみ新しい親カテゴリを持つことができます。</p>
+
+<h3>移動するバーチャルカテゴリ</h3>
+
+<p>あなたが移動したいバーチャルカテゴリを選択してください。 
+リストが空の場合、あなたがカテゴリを作成していないことを意味します。</p>
+
+<h3>新しい親カテゴリ</h3>
+
+<p>新しい親カテゴリ (バーチャルまたはフィジカル) を選択してください。
+あなたが選択しない場合、選択されたバーチャルカテゴリは、ルートに移動されます。
+あなたは、カテゴリをカテゴリ自身、または子カテゴリに移動することはできません。</p>
Index: /tags/2.0.2/language/ja_JP/help/cat_options.html
===================================================================
--- /tags/2.0.2/language/ja_JP/help/cat_options.html	(revision 3278)
+++ /tags/2.0.2/language/ja_JP/help/cat_options.html	(revision 3278)
@@ -0,0 +1,31 @@
+<h2>カテゴリオプション</h2>
+
+<p>このページでは、管理者が一度に多くのカテゴリのオプションを管理することができます。</p>
+
+<dl>
+
+  <dt>アップロード</dt>
+  <dd>カテゴリに対して、ギャラリーのビジターが写真をアップロードできるようにします。
+   非バーチャルおよび非リモートカテゴリのみ表示されます。</dd>
+
+  <dt>コメント</dt>
+  <dd>選択したカテゴリで、ユーザによるコメントの追加を許可します。
+  コメントを追加できるカテゴリを選択してください。
+  少なくとも1つのコメント可能なカテゴリに属しているイメージには、コメントを追加することができます。</dd>
+
+  <dt>ロック</dt>
+  <dd>選択されたカテゴリは、メンテナンスのため、一時的に無効にされます。
+  あなたがカテゴリをロックした場合、すべての子カテゴリもロックされます。
+  あなたがカテゴリのロックを解除した場合、すべての親カテゴリもロック解除されます。</dd>
+
+  <dt>パブリック/プライベート</dt>
+  <dd>選択されたカテゴリの権限を管理します。選択されたカテゴリがプライベートの場合、
+  あなたは、ユーザまたはグループにアクセスの許可を与える必要があります。
+  あなたがカテゴリをプライベートにした場合、すべての子カテゴリもプライベートになります。
+  あなたがカテゴリをパブリックにした場合、すべての親カテゴリもパブリックになります。</dd>
+
+  <dt>見本</dt>
+  <dd>あなたが<code>allow_random_representative</code> (詳細は、<span class="filename">include/config_defaults.inc.php</span>をご覧ください) 
+  の設定パラメータを「true」にした場合、このオプションを管理することができます。
+  それぞれのカテゴリを (独自の写真として) ランダムに表示、または単独に表示することができます。</dd>
+</dl>
Index: /tags/2.0.2/language/ja_JP/help/cat_perm.html
===================================================================
--- /tags/2.0.2/language/ja_JP/help/cat_perm.html	(revision 3278)
+++ /tags/2.0.2/language/ja_JP/help/cat_perm.html	(revision 3278)
@@ -0,0 +1,14 @@
+<h2>カテゴリパーミッションを管理する</h2>
+
+<p>このページでは、プライベートカテゴリのみ利用できます。
+あなたは、このカテゴリへの権限を与えるユーザおよびグループを選択することができます。</p>
+
+<h3>グループ</h3>
+
+<p>現在のカテゴリに関して、あなたはグループに拒否または許可を与えることができます。
+あなたはカテゴリに許可されているグループのリストを修正することができます。</p>
+
+<h3>ユーザ</h3>
+
+<p>あなたは、個別のユーザに対して拒否または許可することができます。
+グループに属しているユーザに対して、拒否または許可を与えることができます。</p>
Index: /tags/2.0.2/language/ja_JP/help/configuration.html
===================================================================
--- /tags/2.0.2/language/ja_JP/help/configuration.html	(revision 3278)
+++ /tags/2.0.2/language/ja_JP/help/configuration.html	(revision 3278)
@@ -0,0 +1,111 @@
+<h2>設定</h2>
+
+<p>このページでは、管理者が基本的な設定を実行することができます。
+実際、このページでは、多くの管理者が必要とする最小設定のみ表示しています。
+あなたが他の多くの (そして高度な) 設定を閲覧したい場合、<span class="filename">include/config_default.inc.php</span>ファイルを参照してください。</p>
+
+<p>このページは、テーマにより設定パラメータを再編成するため、いくつかのセクションに分けられています。</p>
+
+
+<h3>メイン</h3>
+<ul>
+  <li><strong>ギャラリータイトル</strong>: RSSフィードおよびメール通知に使用されます。</li>
+
+  <li><strong>ページバナー</strong>: それぞれのページのトップに表示されます。</li>
+
+  <li><strong>ギャラリーURI</strong>: RSSフィードに使用されます。</li>
+
+  <li><strong>ギャラリーをロックする</strong>: メンテナンスのため、ギャラリー全体をロックします。
+  管理者のみギャラリーにアクセスすることができます。</li>
+
+  <li><strong>評価</strong>: 写真の評価機能を有効にします。</li>
+
+  <li><strong>ゲストによる評価</strong>: 未登録のユーザでも写真を評価できます。</li>
+
+  <li><strong>ユーザ登録を許可する</strong>: すべての人が自由にユーザ登録できます。</li>
+
+  <li><strong>すべてのユーザにメールアドレスを必須とする</strong>: 管理者による処理を除き、ユーザ登録およびプロファイル更新時にメールアドレスがチェックされます。</li>
+
+  <li><strong>新しいユーザ登録時、管理者にメールする</strong>: すべてのユーザ登録に関して、管理者がメール受信します。</li>
+
+</ul>
+
+<h3>履歴</h3>
+
+  <p>ページにアクセスすることで、<span
+  class="pwgScreen">category.php</span>および<span
+  class="pwgScreen">picture.php</span>が<code>history</code>テーブルに記録されます。</p>
+  
+  <p>アクセスは、「<span class="pwgScreen">管理 > 特別 > 履歴</span>」に表示されます。</p>
+
+<ul>
+  <li><strong>ゲストによるページアクセスを記録する</strong>: ゲストによるページアクセスが記録されます。</li>
+
+  <li><strong>ユーザによるページアクセスを記録する</strong>: ユーザによるページアクセスが記録されます。</li>
+
+  <li><strong>管理者によるページアクセスを記録する</strong>: 管理者によるページアクセスが記録されます。</li>
+
+</ul>
+
+<h3>コメント</h3>
+<ul>
+
+  <li><strong>すべてのユーザにコメントを許可する</strong>: ユーザ登録されていないゲストでもコメントを投稿することができます。</li>
+
+  <li><strong>1ページあたりのコメント数</strong>.</li>
+
+  <li><strong>承認</strong>: サイトで閲覧可能な状態になる前に、管理者がユーザによるコメントを承認します。
+  ユーザコメントの承認は、「<span class="pwgScreen">管理 > 写真 > コメント</span>」にて実施されます。</li>
+
+  <li><strong>有効なコメントが投稿された場合、管理者にメールする</strong>:
+ユーザがコメントを登録して、コメントが承認された場合、管理者にメール送信します。</li>
+
+  <li><strong>コメントの承認が必要な場合、管理者にメールする</strong>:
+管理者による承認が必要なコメントをユーザが投稿した場合、管理者にメール送信します。
+ユーザコメントの承認は、「<span class="pwgScreen">管理 > 写真 > コメント</span>」にて実施されます。</li>
+
+</ul>
+
+<!--TODO --><h3>アップロード</h3>
+<ul>
+<!--TODO -->  <li><strong>毎回アップロードリンクを表示する</strong>: アップロード可能なカテゴリが存在する場合、それぞれのカテゴリに追加リンクが表示されます。</li>
+<!--TODO -->  <li><strong>アップロードに関するユーザアクセスレベル</strong>: ユーザによるアップロードの制限を許可します。</li>
+  <li><strong>写真がアップロードされた場合、管理者にメールする</strong>: ユーザにより写真がアップロードされた場合、管理者にメール通知します。</li>
+</ul>
+
+<h3>デフォルト表示</h3>
+
+<p>ここであなたは、ログインしていないユーザに対する、デフォルト表示オプションを変更することができます。
+ユーザがログインした場合、これらのオプションは、ユーザ独自のオプション (<span class="pwgScreen">プロファイル</span>で変更可) により上書きされます。</p>
+
+<p>すべてのユーザは、表示オプションを変更することができますが、あなたは「<span class="pwgScreen">管理 > アイデンティフィケーション > ユーザ</span>」にて、
+選択したユーザの表示オプションを変更することもできます。</p>
+
+<ul>
+
+  <li><strong>言語</strong>: Piwigoラベルのみに関係します。カテゴリ名、写真名およびすべての説明はローカライズされません。</li>
+
+  <li><strong>1行あたりのイメージ数</strong></li>
+
+  <li><strong>1ページあたりの行数</strong></li>
+
+  <li><strong>インターフェーステーマ</strong></li>
+
+  <li><strong>最近の期間</strong>: 日数。写真が新しい写真として表示される期間です。1日より多い日数を指定してください。</li>
+
+  <li><strong>すべてのカテゴリを拡げる</strong>: デフォルトで、すべてのカテゴリをメニューに広げますか?
+  <em>警告</em>: このオプションは、多くのりソースを消費して、あなたのカテゴリツリーが多くのカテゴリを含む場合、巨大なメニューを作成してしまいます。</li>
+
+  <li><strong>コメント数を表示する</strong>: サムネイルページで、それぞれの写真のコメント数を表示します。多くのリソースを消費します。</li>
+
+  <li><strong>ヒット数を表示する</strong>: サムネイルページで、写真のヒット数をサムネイル下に表示します。
+  特別設定パラメータが次の場合のみ表示されます: <br />
+  $conf['show_nb_hits'] = true; <br />
+  注意: デフォルトでは、falseが設定されています。</li>
+
+  <li><strong>写真の最大幅</strong>: 写真の最大表示幅です。この設定より写真が大きい場合、表示時にリサイズされます。
+  この設定に値を入力したい場合、あなたの写真の幅に変更することをお勧めします。</li>
+
+  <li><strong>写真の最大高</strong>: 前の設定と同じです。</li>
+
+</ul>
Index: /tags/2.0.2/language/ja_JP/help/extend_for_templates.html
===================================================================
--- /tags/2.0.2/language/ja_JP/help/extend_for_templates.html	(revision 3278)
+++ /tags/2.0.2/language/ja_JP/help/extend_for_templates.html	(revision 3278)
@@ -0,0 +1,85 @@
+<h2>テンプレートの拡張設定</h2>
+
+<h3>ゴール</h3>
+<p>それぞれのテンプレートに関して、テンプレート拡張より、テンプレートの置換 (「replacer」と呼びます) を定義します。</p>
+
+<p>replacerがオリジナルテンプレートにリンクされた場合 (または任意で、要求されたURIに「任意のURIキーワード」が含まれている場合)、
+./template/yoga (または他のyoga) は「replacer」と置換されます。</p>
+
+<p>「任意のURIキーワード」は、URIのモジュール名の後にあります。</p>
+
+<p>従って、「任意のURIキーワード」は、「パーマリンク」になり得ます (パーマリンクに関する詳細は、私たちのドキュメントをご覧ください)。</p>
+
+<p>使用用法に関して、「<a href="#warnings">注意</a>」をご覧ください。</p>
+
+<h3>テンプレート拡張とは?</h3>
+
+<p>この設定ツールは、ビギナーおよびアドバンストユーザにとって、パワフルなツールです。
+FTPを使用して、ウェブマスタは、多くの配布 .tplファイル (「オリジナルテンプレート」) を異なる名称 (「replacer」) で複製することができます。
+ 
+ 現在サポートされている「オリジナルテンプレート」は、以下のとおりです:</p>
+<ul>
+  <li><span class="filename">index.tpl</span></li>
+  <li><span class="filename">mainpage_categories.tpl</span> および/または <span class="filename">thumbnails.tpl</span></li>
+  <li><span class="filename">menubar.tpl</span></li>
+  <li><span class="filename">header.tpl</span> および/または <span class="filename">footer.tpl</span></li>
+  <li><span class="filename">picture_content.tpl</span> および/または<span class="filename">picture.tpl</span></li>
+  <!-- <li><span class="filename">slideshow.tpl</span></li> -->
+  <li><span class="filename">profile.tpl</span> および/または <span class="filename">profile_content.tpl</span></li>
+  <li><span class="filename">tags.tpl</span></li>
+  <li><span class="filename">upload.tpl</span></li>
+  <li><span class="filename">about.tpl</span></li>
+  <li><span class="filename">popuphelp.tpl</span></li>
+  <li><span class="filename">search.tpl</span> および/または <span class="filename">search_rules.tpl</span></li>
+  <li><span class="filename">nbm.tpl</span> および/または <span class="filename">notification.tpl</span></li>
+  <li><span class="filename">identification.tpl</span> および/または <span class="filename">register.tpl</span></li>
+  <li><span class="filename">redirect.tpl</span></li>
+</ul>
+
+<h3>オリジナルテンプレートは、どこにありますか?</h3>
+
+<p>配布されているオリジナルテンプレートは、template/yoga/ にあります (アップグレードの観点から、編集しないでください)。
+そのため、ウェブマスタは、「オリジナルテンプレート」から独自の「replacers (カスタマイズテンプレート)」を作成することができます。
+
+<h3>replacerは、どこに保存すべきですか?</h3>
+
+<p><strong>replacer (カスタマイズテンプレート)</strong> は、template-extensionフォルダ (または、そのサブフォルダ) に配置する必要があります。
+Replacers can have any filename with the .tpl extension. For example: <span
+class="filename">template-extension/my-extension/video.tpl</span>.</p>
+
+
+<h3>replacerは、どこで有効にできますか?</h3>
+<p>関連する置換テンプレートを有効にするため、<strong>オリジナルテンプレート</strong>は、
+<strong>replacer (カスタマイズテンプレート)</strong> に割り当てられる必要があります。
+これは、設定管理ページの「テンプレートの拡張」にて、割り当てることができます。</p>
+
+<p>あなたが<strong>任意のURIキーワード</strong>を選択した場合、このキーワードを使ったページのみ、
+置換が実行されます。例えば次のようになります: <span class="pwgScreen">index.php?/<strong>most_visited</strong></span></p>
+  
+<p>アドバンストユーザは、<strong>任意URIキーワード</strong>をパーマリンクとして使用します。</p>
+<h3>replacerを無効にするには?</h3>
+<ul>
+<li>関連する「オリジナルテンプレート」の選択を解除してください。</li>
+<li>FTPでreplacerを削除してください。</li>
+</ul>
+<a name="warnings"></a>
+<h3>注意</h3>
+<ul>
+
+<li><strong>オリジナルテンプレート</strong>は、「オリジナル」テンプレートであるべきです。そうでない場合、あなたの予想できない結果となってしまいます!</li>
+
+<li>同じ<strong>オリジナルテンプレート</strong>を使って、いくつかの<strong>replacer (カスタマイズテンプレート)</strong> を作成して、
+同じ<strong>任意のURIキーワード</strong>を使用する場合、最後のreplacerのみ有効となります。</li>
+
+<li>未選択の<strong>任意のURIキーワード</strong>は、すべてのテンプレート使用に関して、replacerを有効にします。
+前の時点と同じように、順番は、前に選択されたreplacerをオーバーライドすることができます。</li>
+
+<li>サブフォルダ:
+サブフォルダは無視されますが、現在の順番を変更するのに有用です。<br />
+distributed-samples: テスト目的のため提供されます! 
+<strong>編集せずに</strong>、あなた自身のテンプレートを作成してください。
+</li>
+
+<li>replacerを削除すると、すぐに<strong>オリジナルテンプレート</strong>が再度有効にされます。</li>
+
+</ul>
Index: /tags/2.0.2/language/ja_JP/help/group_list.html
===================================================================
--- /tags/2.0.2/language/ja_JP/help/group_list.html	(revision 3278)
+++ /tags/2.0.2/language/ja_JP/help/group_list.html	(revision 3278)
@@ -0,0 +1,22 @@
+<h2>グループリスト</h2>
+
+<p>ここでは、あなたが定義したグループを管理することができます。</p>
+
+<h3>グループを追加する</h3>
+
+<p>管理者は、グループを追加することができます。</p>
+
+<h3>グループリスト</h3>
+
+<p>グループリストでは、それぞれの要素に関して:</p>
+
+
+<ul>
+  <li>メンバーリストに移動できます。</li>
+  <li>パーミッションに移動できます。</li>
+  <li>グループを削除できます (要チェックボックスの確認)。</li>
+  <li>ステータスを「デフォルト」に切り替えることができます (要チェックボックスの確認)。</li>
+</ul>
+
+<h3>デフォルトグループ</h3>
+<p>デフォルトグループは、新しいユーザが自動的に関連付けられるグループです。</p>
Index: /tags/2.0.2/language/ja_JP/help/history.html
===================================================================
--- /tags/2.0.2/language/ja_JP/help/history.html	(revision 3278)
+++ /tags/2.0.2/language/ja_JP/help/history.html	(revision 3278)
@@ -0,0 +1,32 @@
+<h2>履歴</h2>
+
+<p>これらのページでは、あなたが「管理 > 一般 > 履歴」で選択したオプションに従って、Piwigoの履歴ナビゲーションにアクセスすることができます。</p>
+	
+<h3>統計</h3>
+<ul>
+<p>あなたが、<code>history</code>テーブルにページアクセス (<span class="pwgScreen">index.php</span>および<span class="pwgScreen">picture.php</span>) を保存している場合、ここではサイトのページアクセスに関する情報を閲覧することができます。</p>
+
+	<li><strong>全体の統計</strong> : あなたは、年毎の統計を閲覧することができます。</li>
+	
+	<li><strong>年毎の統計</strong> : あなたが選択した年に関して、月毎の統計を閲覧することができます。</li>
+	
+	<li><strong>月毎の統計</strong> : あなたが選択した月に関して、日毎の統計を閲覧することができます。</li>
+	
+	<li><strong>日毎の統計</strong> : あなたが選択した日付に関して、時間毎の統計を閲覧することができます。</li>
+	
+</ul>
+
+<h3>検索</h3>
+<ul>
+<p>あなたが、<code>history</code>テーブルにページアクセス (<span class="pwgScreen">index.php</span>および<span class="pwgScreen">picture.php</span>) を保存している場合、ここでは異なるフィルタにより、サイトのページアクセス詳細に関する情報を閲覧することができます。</p>
+
+	<li><strong>日付に関するフィルタ</strong> : あなたが活動を閲覧したい期間を選択してください。</li>
+	
+	<li><strong>エレメントタイプに関するフィルタ</strong> : あなたが活動を閲覧したいエレメントタイプを選択してください。</li>
+	
+	<li><strong>ユーザに関するフィルタ</strong> : あなたが活動を閲覧したいユーザを選択してください。</li>
+	
+	<li><strong>ファイル名に関するフィルタ</strong> : あなたが活動を閲覧したいファイル名を選択してください。</li>
+	
+	<li><strong>イメージIDに関するフィルタ</strong> : あなたが活動を閲覧したいイメージIDを選択してください。</li>
+</ul>
Index: /tags/2.0.2/language/ja_JP/help/index.php
===================================================================
--- /tags/2.0.2/language/ja_JP/help/index.php	(revision 3278)
+++ /tags/2.0.2/language/ja_JP/help/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008      Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/language/ja_JP/help/maintenance.html
===================================================================
--- /tags/2.0.2/language/ja_JP/help/maintenance.html	(revision 3278)
+++ /tags/2.0.2/language/ja_JP/help/maintenance.html	(revision 3278)
@@ -0,0 +1,39 @@
+<h2>メンテナンス</h2>
+
+<p>ページ作成時間を最適化するため、Piwigoはキャッシュ情報を使用します。
+例えば、それぞれのカテゴリに含まれている写真数を、ページがリロードされるたびにカウントするのではなく、
+データベースに保存します。理論的には、この情報は常に更新されますが、時々エラーが発生して、キャッシュ情報が
+正しく表示されない場合もあります。</p>
+
+<p>時間に関して、いくつかの情報が無用になる場合もあります。この無用な情報をデータベースから削除することで、
+あなたはディスクスペースを減らすことができます。</p>
+
+<ul>
+
+  <li><strong>カテゴリ情報を更新する:</strong> それぞれのカテゴリに関して、次の情報が更新または管理されます:
+  親カテゴリのリスト、写真数、最近の写真の日付、子カテゴリのポジション、すべてのカテゴリのポジション。
+  この処理では、サムネイルの一致もチェックされます。</li>
+
+  <li><strong>イメージ情報を更新する:</strong> それぞれの写真に関して、次の情報が更新されます:
+  ファイルのフルパス、平均評点。
+  <em>警告</em>: 「<span class="pwgScreen">管理 > カテゴリ > 同期化</span>」または
+  写真の修正ページ (例えば、<span class="pwgScreen">写真</span>を経由) で同期化できる、
+  メタデータ情報に混乱しないでください。</li>
+
+  <li><strong>データベースを修復および最適化する:</strong>
+  それぞれのテーブルに関して、並び替え、修復および最適化処理が実行されます。
+  </li>
+</ul>
+
+<ul>
+  <li><strong>履歴詳細を消去する:</strong> <code>履歴</code>テーブルから、すべてのレコードが削除されます。
+  「<span class="pwgScreen">管理 > 特別 > 履歴</span>」ページでは、過去の履歴に関する情報が表示されなくなります。
+  <em>警告</em>: すべてのデータが削除されて、元に戻すことはできませんので留意してください。</li>
+
+  <li><strong>履歴サマリーを消去する:</strong> 履歴に関して、すべてのサマリー情報を削除します。このサマリーは、履歴詳細から計算されます。</li>
+
+  <li><strong>セッションを削除する:</strong> 期限切れのユーザセッションを削除します。</li>
+
+  <li><strong>未使用の通知フィードを削除する</strong></li>
+
+</ul>
Index: /tags/2.0.2/language/ja_JP/help/notification_by_mail.html
===================================================================
--- /tags/2.0.2/language/ja_JP/help/notification_by_mail.html	(revision 3278)
+++ /tags/2.0.2/language/ja_JP/help/notification_by_mail.html	(revision 3278)
@@ -0,0 +1,14 @@
+<h2>メール通知</h2>
+
+<p>この画面では、あなたのサイトニュースに関する、ユーザのメール購読を設定および管理します。</p>
+
+<p>この画面は、3つのタブで構成されます:</p>
+
+<h3>パラメータ</h3>
+<p>ウェブマスタのみ利用できます。このタブでは、メール通知のパラメータを設定します。</p>
+
+<h3>購読</h3>
+<p>ウェブマスタのみ利用できます。このタブでは、ユーザに関する、メール通知の購読/購読解除を管理します。</p>
+
+<h3>送信</h3>
+<p>ウェブマスタおよび管理者のみ利用できます。このタブでは、ニュースをメール通知することができます。</p>
Index: /tags/2.0.2/language/ja_JP/help/permalinks.html
===================================================================
--- /tags/2.0.2/language/ja_JP/help/permalinks.html	(revision 3278)
+++ /tags/2.0.2/language/ja_JP/help/permalinks.html	(revision 3278)
@@ -0,0 +1,7 @@
+<h2>パーマリンク</h2>
+
+<p>パーマリンクは、カテゴリURIを素晴らしく変更します。カテゴリにパーマリンクが設定された場合、URIにカテゴリのIDが不要となります。</p>
+
+<p>パーマリンクが削除された場合、今後もPWGページにアクセスできるよう、あなたはパーマリンク履歴に保存することができます。パーマリンク履歴テーブルでは、あなたは最新利用日時、このパーマリンクの利用回数およびパーマリンクの削除日時を閲覧することができます。</p>
+
+<p>パーマリンクは、カテゴリごとにユニークである必要がありますので留意してください。また、パーマリンク履歴では、あなたは同じパーマリンクを2回以上定義することはできません。</p>
Index: /tags/2.0.2/language/ja_JP/help/search.html
===================================================================
--- /tags/2.0.2/language/ja_JP/help/search.html	(revision 3278)
+++ /tags/2.0.2/language/ja_JP/help/search.html	(revision 3278)
@@ -0,0 +1,22 @@
+<h2>検索</h2>
+
+<p>このページでは、あなたはギャラリー全体から写真を検索することができます。</p>
+
+<dl>
+
+  <dt>言葉で探す</dt>
+  <dd>入力された言葉を使用して、ギャラリーで表示される写真に関連した属性すべてを検索します。
+  部分的な合致には、* をワイルドカードとして使用してください。</dd>
+
+  <dt>作者で探すdt>
+  <dd>部分的な合致には、* をワイルドカードとして使用してください。</dd>
+
+  <dt>日付で探す</dt>
+  <dd>あなたの検索に関して、日付および終了日を選択してください。あなたが「以前」を検索したい場合、
+  日付を空白のままにしてください。年は最後のフィールドに次のようなフォーマットで入力してください : 0000 (例 2009)</dd>
+
+  <dt>カテゴリを探す</dt>
+  <dd>あなたが探したいカテゴリを選択してください。親カテゴリを選択した後、
+  「サブカテゴリを探す」オプションを選択した場合、すべてのサブカテゴリも検索されます。</dd>
+
+</dl>
Index: /tags/2.0.2/language/ja_JP/help/site_manager.html
===================================================================
--- /tags/2.0.2/language/ja_JP/help/site_manager.html	(revision 3278)
+++ /tags/2.0.2/language/ja_JP/help/site_manager.html	(revision 3278)
@@ -0,0 +1,41 @@
+<h2>リモートサイト</h2>
+
+<p>Piwigoでは、イメージを保存して、あなたのギャラリーを構成するため、
+複数のサーバを使用することができます。 これは、ギャラリーがインストールされているサーバのディスクスペースが限られていて、
+あなたが大量のイメージを表示したい場合、有用です。</p>
+
+<ol>
+
+  <li><code>$conf['prefix_thumbnail']</code> または <code>$conf['use_exif']</code></li>のようなパラメータセクションを変更することで、
+  ファイル<span class="filename">tools/create_listing_file.php</span>を編集してください。
+
+  <li>修正済みファイル<span class="filename">tools/create_listing_file.php</span>を
+  あなたのカテゴリのディレクトリ (このウェブサイトのディレクトリ<span class="filename">galleries</span> )と
+  同じ遠隔サーバのディレクトリにFTPでアップロードしてください。
+  例えば、あなたが<span class="filename">http://example.com/galleries/create_listing_file.php</span>にアクセスできるようにします。</li>
+
+  <li>「<span class="pwgScreen">管理パネル > カテゴリ > サイトマネージャ</span>」に移動してください。
+  例えば、<span class="filename">http://example.com/galleries</span>のようなサイトを作成してください。</li>
+
+  <li>新しいリモートサイトが作成されます。あなたは、次の4つの処理を実行できます :
+
+    <ol>
+
+      <li><strong>一覧の作成</strong> : 遠隔ファイル一覧を作成するリクエストを送信できます。</li>
+
+      <li><strong>同期化</strong> : 遠隔サイトの<span class="filename">listing.xml</span>ファイルを読んで、
+      データベース情報と同期化できます。</li>
+
+      <li><strong>クリーン</strong> : 遠隔サイトの<span class="filename">listing.xml</span>ファイルを削除できます。</li>
+
+      <li><strong>削除</strong> : データベース内のサイト (および、すべての関連カテゴリおよびエレメント) をデータベースから削除できます。</li>
+
+    </ol>
+  </li>
+</ol>
+
+<!-- <p>You can do all this by hand by generating yourself the <span
+class="filename">listing.xml</span> file, moving it from your distant server
+to you local Piwigo root directory and opening the remote site
+management screen : Piwigo will propose you to use the found
+listing.xml file.</p>-->
Index: /tags/2.0.2/language/ja_JP/help/synchronize.html
===================================================================
--- /tags/2.0.2/language/ja_JP/help/synchronize.html	(revision 3278)
+++ /tags/2.0.2/language/ja_JP/help/synchronize.html	(revision 3278)
@@ -0,0 +1,10 @@
+<h2>同期化</h2>
+
+<p>同期化には、2つの方法があります: ディレクトリ/ファイルおよびファイルメタデータです。
+ディレクトリ/ファイルでは、データベース内のカテゴリツリーを含んだディレクトリを同期化します。
+メタデータでは、ファイルサイズ、ピクセルのサイズ、EXIFまたはIPTC情報等のエレメント情報を更新します。</p>
+
+<p>最初の同期化は、ディレクトリ/ファイルを実行してください。</p>
+
+<p>同期化処理には長時間を要します (あなたのサーバロードおよび管理するエレメント量に依存します)。
+そのため、カテゴリごとに処理することも可能です。</p>
Index: /tags/2.0.2/language/ja_JP/help/thumbnail.html
===================================================================
--- /tags/2.0.2/language/ja_JP/help/thumbnail.html	(revision 3278)
+++ /tags/2.0.2/language/ja_JP/help/thumbnail.html	(revision 3278)
@@ -0,0 +1,28 @@
+<h2>サムネイル作成</h2>
+
+<p>このページでは、欠けているサムネイルを作成することができます。</p>
+
+<dl>
+
+  <dt>GDバージョン</dt>
+
+  <dd>GDは、写真をコントロールするためのPHPライブラリです。あなたのサーバにインストールされている
+  バージョンを選択してください。あなたが正しくないバージョンを選択した場合、エラーメッセージが表示されます。
+  エラーメッセージが表示された場合、このページに戻って、他のバージョンを選択してください。どのバージョンを選択しても
+  動作しない場合、あなたのサーバがGDをサポートしていないことを意味します。</dd>
+
+  <dt>幅および高さ</dt>
+
+  <dd>サムネイルが使用することのできる最大サイズです。縦横比は保持されます。  </dd>
+
+  <dt>作成するサムネイル数</dt>
+
+  <dd>同時に多くの写真をサムネイル化しないでください。実際、サムネイル化では多くのCPUを使用します。あなたがPiwigoを
+  フリープロバイダにインストールしている場合、高すぎるCPUロードを理由として、あなたのウェブサイトが削除される場合があります。</dd>
+
+  <dt>ファイルフォーマット</dt>
+
+  <dd>サムネイルの作成には、JPEGファイルフォーマットのみサポートされています。
+  サムネイルは、PNGおよびJPEG写真からのみ作成することができます。</dd>
+
+</dl>
Index: /tags/2.0.2/language/ja_JP/help/user_list.html
===================================================================
--- /tags/2.0.2/language/ja_JP/help/user_list.html	(revision 3278)
+++ /tags/2.0.2/language/ja_JP/help/user_list.html	(revision 3278)
@@ -0,0 +1,39 @@
+<h2>ユーザリスト</h2>
+
+<p>このページでは、あなたは登録済みユーザを管理することができます。
+パーミッションのみ異なるページで管理します。</p>
+
+<h3>ユーザを追加する</h3>
+
+<p>管理者は、手動でユーザを追加することができます。</p>
+
+<h3>ユーザリスト</h3>
+
+<p>リストは、ユーザ名 (ワイルドカードは、* を使用)、グループまたはステータスでフィルタすることができます。
+また、リストは登録日またはユーザ名の昇順または降順に並び替えることもできます。</p>
+
+<p>このページでは、複数のユーザに対して、同時に異なる処理を実施することができます:</p>
+
+<ul>
+
+  <li>ユーザの削除 (要確認チェックボックスのチェック)</li>
+
+  <li>ステータスの変更</li>
+
+  <li>グループの関連付け、または関連付けの解除</li>
+
+  <li>表示プロパティの変更</li>
+
+  <li>追加的なプロパティの変更</li>
+
+</ul>
+<p>ターゲットは「選択」されたユーザ (デフォルト) です。または、「すべて」のユーザを選択することができます。</p>
+<h3>アドバイザ</h3>
+<p>アドバイザユーザの定義:</p>
+<ul>
+  <li>このステータスに許可された、すべての画面へアクセスすることができます。</li>
+  <li>リードオンリーまたはシミュレートオンリーのアクセスです。</li>
+</ul>
+
+<p>アドバイザモードは変数「$conf['allow_adviser']」で有効にすることができます。</p>
+<p>この変数を「true」にした場合、ユーザをアドバイザとして割り当てることができます。</p>
Index: /tags/2.0.2/language/ja_JP/index.php
===================================================================
--- /tags/2.0.2/language/ja_JP/index.php	(revision 3278)
+++ /tags/2.0.2/language/ja_JP/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008      Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/language/ja_JP/install.lang.php
===================================================================
--- /tags/2.0.2/language/ja_JP/install.lang.php	(revision 3278)
+++ /tags/2.0.2/language/ja_JP/install.lang.php	(revision 3278)
@@ -0,0 +1,66 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008      Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+$lang['Installation'] = 'インストレーション';
+$lang['Initial_config'] = '基本設定';
+$lang['Default_lang'] = 'ギャラリーのデフォルト言語';
+$lang['step1_title'] = 'データベース設定';
+$lang['step2_title'] = '管理設定';
+$lang['Start_Install'] = 'インストールを開始する';
+$lang['reg_err_mail_address'] = 'メールアドレスは、 xxx@yyy.eee のような形式にしてください (例: jack@altern.org)。';
+
+$lang['install_webmaster'] = 'ウェブマスタログイン';
+$lang['install_webmaster_info'] = 'ウェブマスタは、ビジターに表示されます。ウェブサイト管理に必要です。';
+
+$lang['step1_confirmation'] = 'パラメータに問題はありません。';
+$lang['step1_err_db'] = 'サーバへ接続することができましたが、データベースに接続できません。';
+$lang['step1_err_server'] = 'サーバに接続できません。';
+$lang['step1_err_copy_2'] = 'インストールの次のステップへ進むことができます。';
+$lang['step1_err_copy_next'] = '次のステップ';
+$lang['step1_err_copy'] = 'ハイフンの間のピンクのテキストをコピーして、ファイル「include/mysql.inc.php」の中に貼り付けてください (警告 : mysql.inc.phpには、ピンクのテキストのみ貼り付けてください。改行またはスペースを含まないでください)。';
+
+$lang['step1_host'] = 'MySQLホスト';
+$lang['step1_host_info'] = '例) localhost、sql.multimania.com、toto.freesurf.fr';
+$lang['step1_user'] = 'ユーザ';
+$lang['step1_user_info'] = 'あなたのホストプロバイダから提供されたデータベースユーザ名です。';
+$lang['step1_pass'] = 'パスワード';
+$lang['step1_pass_info'] = 'あなたのホストプロバイダから提供されたデータベースパスワードです。';
+$lang['step1_database'] = 'データベース名';
+$lang['step1_database_info'] = 'こちらも、あなたのホストプロバイダから提供されたデータベース名です。';
+$lang['step1_prefix'] = 'データベーステーブル接頭辞';
+$lang['step1_prefix_info'] = 'データベーステーブルに接頭辞として付けられます (あなたのテーブルを管理しやすくします)。';
+$lang['step2_err_login1'] = 'ウェブマスタのユーザIDを入力してください。';
+$lang['step2_err_login3'] = 'ウェブマスタのユーザIDには、「\'」または「"」を含まないでください。';
+$lang['step2_err_pass'] = 'もう一度あなたのパスワードを入力してください。';
+$lang['install_end_title'] = 'インストールが終了しました。';
+$lang['step2_pwd'] = 'ウェブマスタパスワード';
+$lang['step2_pwd_info'] = 'ウェブマスタパスワードは、内密にしてください。ウェブマスタパスワードを使用して、あなたは管理パネルにアクセスすることができます。';
+$lang['step2_pwd_conf'] = 'パスワード [もう一度]';
+$lang['step2_pwd_conf_info'] = '確認';
+$lang['install_help'] = 'ヘルプが必要ですか? <a href="%s">Piwigoメッセージボード</a>にて、あなたの質問を投稿してください。';
+$lang['install_end_message'] = 'Piwigoの設定が完了しました。次のステップへ移動します。<br /><br />
+* アイデンティフィケーションページにアクセスします : [ <a href="identification.php">アイデンティフィケーション</a> ] ウェブマスタに設定したユーザIDおよびパスワードを使用してください。<br />
+* このログインにより、あなたは管理パネルにアクセスすることができます。また、あなたのディレクトリに写真をアップロードするためのインストラクションにもアクセスすることができます。';
+$lang['conf_mail_webmaster'] = 'ウェブマスタメールアドレス';
+$lang['conf_mail_webmaster_info'] = 'ビジターは、このメールアドレスでサイト管理者に連絡することができます。';
+?>
Index: /tags/2.0.2/language/ja_JP/iso.txt
===================================================================
--- /tags/2.0.2/language/ja_JP/iso.txt	(revision 3278)
+++ /tags/2.0.2/language/ja_JP/iso.txt	(revision 3278)
@@ -0,0 +1,1 @@
+日本語 [JP]
Index: /tags/2.0.2/language/ja_JP/upgrade.lang.php
===================================================================
--- /tags/2.0.2/language/ja_JP/upgrade.lang.php	(revision 3278)
+++ /tags/2.0.2/language/ja_JP/upgrade.lang.php	(revision 3278)
@@ -0,0 +1,44 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008      Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+$lang['Upgrade'] = 'アップグレード';
+$lang['introduction message'] = 'あなたの古いバージョンのPiwigoから最新バージョンへアップグレードします。
+あなたは、現在 <strong>リリース %s</strong> (または同等のバージョン) を使用しています。';
+$lang['Upgrade from %s to %s'] = 'バージョン %s から %s にアップグレードする';
+$lang['Statistics'] = '統計';
+$lang['total upgrade time'] = '合計アップグレード時間';
+$lang['total SQL time'] = '合計SQL時間';
+$lang['SQL queries'] = 'SQLクエリー';
+$lang['Upgrade informations'] = '更新情報';
+$lang['perform a maintenance check'] = '問題がある場合、[管理 > 特別 > メンテナンス] でメンテナンスチェックを実行してください。';
+$lang['deactivated plugins'] = '事前チェックで以下のプラグインが検出されました。再度有効にする前にプラグインのアップグレードを確認してください:';
+$lang['upgrade login message'] = '管理者のみアップグレードを実行できます: 以下でログインしてください。';
+$lang['You do not have access rights to run upgrade'] = 'あなたには、アップグレードを実行する権限がありません。';
+$lang['in include/mysql.inc.php, before ?>, insert:'] = '<i>include/mysql.inc.php</i>内にある<b>?></b>の前に次の行を挿入してください:';
+
+// Upgrade informations from upgrade_1.3.1.php
+$lang['all sub-categories of private categories become private'] = 'プライベートカテゴリのすべてのサブカテゴリがプライベートにされました。';
+$lang['user permissions and group permissions have been erased'] = 'ユーザパーミッションおよびグループパーミッションが削除されました。';
+$lang['only thumbnails prefix and webmaster mail saved'] = '以前の設定より、サムネイル接頭辞およびウェブマスターのメールアドレスのみ保存されました。';
+
+?>
Index: /tags/2.0.2/language/nl_NL/about.html
===================================================================
--- /tags/2.0.2/language/nl_NL/about.html	(revision 3278)
+++ /tags/2.0.2/language/nl_NL/about.html	(revision 3278)
@@ -0,0 +1,10 @@
+  <li>Piwigo is een web applicatie die je de mogelijkheid geeft
+  om makkelijk een online foto gallerie te maken.</li>
+
+  <li>Technisch, Piwigo is volledig ontwikkeld in PHP (the elePHPant)
+  met een MySQL database (the SQuirreL).</li>
+
+  <li>Heb je suggesties of commentaar, bezoek dan de  <a
+  href="http://piwigo.org">Piwigo</a> officiele site, en
+  zijn <a href="http://piwigo.org/forum">forum</a>.</li>
+
Index: /tags/2.0.2/language/nl_NL/admin.lang.php
===================================================================
--- /tags/2.0.2/language/nl_NL/admin.lang.php	(revision 3278)
+++ /tags/2.0.2/language/nl_NL/admin.lang.php	(revision 3278)
@@ -0,0 +1,650 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+$lang['%d association'] = '%d associatie';
+$lang['%d associations'] = '%d associaties';
+$lang['cat_inclu_part1_S'] = '%d categorie inclusief ';
+$lang['cat_inclu_part1_P'] = '%d categories inclusief ';
+$lang['cat_inclu_part2_S'] = '%d physiek';
+$lang['cat_inclu_part2_P'] = '%d physieke';
+$lang['cat_inclu_part3_S'] = ' en %d virtueel';
+$lang['cat_inclu_part3_P'] = ' en %d virtueel';
+$lang['%d category moved'] = '%d categorie verplaatst';
+$lang['%d categories moved'] = '%d categorieën verplaatst';
+$lang['%d group'] = '%d groep';
+$lang['%d groups'] = '%d groepen';
+$lang['%d member'] = '%d lid';
+$lang['%d members'] = '%d leden';
+$lang['%d tag'] = '%d tag';
+$lang['%d tags'] = '%d tags';
+$lang['%d user comment rejected'] = '%d gebruikers commentaar afgewezen';
+$lang['%d user comments rejected'] = '%d gebruikers commentaren afgewezen';
+$lang['%d user comment validated'] = '%d gebruikers commentaar bevestigd';
+$lang['%d user comments validated'] = '%d gebruikers commentaren bevestigd';
+$lang['%d user deleted'] = '%d gebruiker verwijderd';
+$lang['%d users deleted'] = '%d gebruikers verwijderd';
+$lang['%d user'] = '%d gebruiker';
+$lang['%d users'] = '%d gebruikers';
+$lang['%d waiting for validation'] = '%d wachten op bevestiging';
+$lang['%d waiting pictures rejected'] = '%d plaatje\'s afgewezen';
+$lang['%d waiting pictures validated'] = '%d plaatje\'s toegestaan';
+$lang['Actions'] = 'Acties';
+$lang['Activate'] = 'Activatie';
+$lang['Add/delete a permalink'] = 'toevoegen/verwijderen van een permalink';
+$lang['Add a tag'] = 'Voeg een tag toe';
+$lang['Add a user'] = 'Voeg een gebruiker toe';
+$lang['Add group'] = 'Voeg een groep toe';
+$lang['Add selected elements to caddie'] = 'Voeg geselecteerde elementen toe aan caddie';
+$lang['Add'] = 'Toevoegen';
+$lang['Allow user registration'] = 'Sta gebruikersregistratie toe';
+$lang['Apply to subcategories'] = 'Toestaan op subcategorieen';
+$lang['Are you sure?'] = 'Weet je het zeker?';
+$lang['Associated'] = 'Gelinkt';
+$lang['Association to categories'] = 'Gelinkt aan categorie';
+$lang['Batch management'] = 'Batch management';
+$lang['Caddie management'] = 'Caddie management';
+$lang['Caddie'] = 'Caddie';
+$lang['Categories authorized thanks to group associations'] = 'Categories authorized thanks to group associations';
+$lang['Categories manual order was saved'] = 'Categorieën handmatig gesorteerd is opgeslagen';
+$lang['Categories ordered alphanumerically'] = 'Categorieën alphanumeriek gesorteerd';
+$lang['Category elements associated to the following categories: %s'] = 'Categorie elementen gelinkt aan de volgende categorieen: %s';
+$lang['Check for upgrade failed for unknown reasons.'] = 'Controle voor upgrade is niet geslaagt door onbekende reden.';
+$lang['Check for upgrade'] = 'Controleer voor een upgrade';
+$lang['Comments for all'] = 'Commentaar voor alles';
+$lang['Controversy'] = 'Controversieel';
+$lang['Current name'] = 'Huidige naam';
+$lang['Database'] = 'Database';
+$lang['Deactivate'] = 'Deactiveer';
+$lang['Delete Representant'] = 'Verwijder Representant';
+$lang['Delete selected tags'] = 'Verwijder geselecteerde tags';
+$lang['Delete selected users'] = 'Verwijder geselecteerde gebruikers';
+$lang['Deletions'] = 'Verwijderde';
+$lang['Deny selected groups'] = 'Verbied geselecteerde groepen';
+$lang['Deny selected users'] = 'Verbied geselecteerde gebruikers';
+$lang['Description'] = 'Omschrijving';
+$lang['Display options'] = 'Toon opties';
+$lang['Dissociated'] = 'Niet gelinkt';
+$lang['Does not represent'] = 'Is niet aanwezig';
+$lang['Edit all picture informations'] = 'Bewerk afbeeldings informatie';
+$lang['Edit selected tags'] = 'Bewerk geselecteerde tags';
+$lang['Edit tags'] = 'Bewerk tags';
+$lang['Elements'] = 'Elementen';
+$lang['Email administrators when a new user registers'] = 'Email beheerders wanneer een nieuwe gebruiker zich registreerd';
+$lang['Email administrators when a valid comment is entered'] = 'Email beheerder wannneer een  geldig commentaar is ingevuld';
+$lang['Email administrators when a comment requires validation'] = 'Email beheerder wanneer een commantaart validatie nodig heeft';
+$lang['Email administrators when a picture is uploaded'] = 'Email beheerder wanneer er een plaatje is ge-upload';
+$lang['Empty caddie'] = 'Leeg caddie';
+$lang['Environment'] = 'Omgeving';
+$lang['Form'] = 'Formulier';
+$lang['Gallery URL'] = 'Gallerie URL';
+$lang['Gallery description'] = 'Gallerie omschrijving';
+$lang['Gallery title'] = 'Gallerie titel';
+$lang['Grant selected groups'] = 'Toegang geselecteerde groepen';
+$lang['Grant selected users'] = 'Toegang geselecteerde gebruikers';
+$lang['Group name'] = 'Groep naam';
+$lang['Groups'] = 'Groepen';
+$lang['Guests'] = 'Gasten';
+$lang['History'] = 'Geschiedenis';
+$lang['Informations'] = 'Informatie';
+$lang['Install'] = 'Installatie';
+$lang['Link all category elements to a new category'] = 'Link alle categorie elementen aan een nieuwe categorie';
+$lang['Link all category elements to some existing categories'] = 'Link alle categorie elementen aan bestaande categorieen';
+$lang['Linked categories'] = 'Gelinkte categorieën';
+$lang['Lock gallery'] = 'Sluit gallerie';
+$lang['Maintenance'] = 'Onderhoud';
+$lang['Manage permissions for a category'] = 'Beheer rechten voor een categorie';
+$lang['Manage permissions for group "%s"'] = 'Beheer rechten voor een groep "%s"';
+$lang['Manage permissions for user "%s"'] = 'Beheer rechten voor een gebruiker "%s"';
+$lang['Manage tags'] = 'Beheer tags';
+$lang['Members'] = 'Leden';
+$lang['Metadata synchronized from file'] = 'Metadata gesynchronizeerd van een bestand';
+$lang['Move categories'] = 'Verplaats categorie';
+$lang['Move'] = 'Verplaatsen';
+$lang['Name'] = 'Naam';
+$lang['New name'] = 'Nieuwe naam';
+$lang['New parent category'] = 'Nieuwe hoofd categorie';
+$lang['New tag'] = 'Nieuwe tag';
+$lang['No tag defined. Use Administration>Pictures>Tags'] = 'Geen tag gedefineerd. Gebruik beheer>afbeeldingen>Tags';
+$lang['Number of comments per page'] = 'Aantal commentaren per pagina';
+$lang['Number of rates'] = 'Aantal beoordelingen';
+$lang['Number of thumbnails to create'] = 'Aantal thumbnails om te maken';
+$lang['Only private categories are listed'] = 'Alleen private categorieen worden getoond';
+$lang['Operating system'] = 'Besturingssysteem';
+$lang['Options'] = 'Opties';
+$lang['Order alphanumerically'] = 'sorteer alphanumeriek';
+$lang['Other private categories'] = 'Andere private categorieën';
+$lang['Page banner'] = 'Pagina banner';
+$lang['Parent category'] = 'Hoofd categorie';
+$lang['Path'] = 'Path';
+$lang['Permalink'] = 'Permalink';
+$lang['Permalink_%s_histo_used_by_%s'] = 'Permalink %s is eerder gebruikt door categorie %s. Verwijder de permalink geschiedenis eerst';
+$lang['Permalink_name_rule'] = 'De permalink naam moet bstaan uit a-z, A-Z, 0-9, "-" of "_". Het mag geen getal zijn of starten met een "-"';
+$lang['Permalink %s is already used by category %s'] = 'Permalink %s is al in gebruik door een categorie %s';
+$lang['Permalink history'] = 'Permalink geschiedenis';
+$lang['Permalinks'] = 'Permalinks';
+$lang['Permission denied'] = 'Toegang gewijgerd';
+$lang['Permission granted thanks to a group'] = 'Rechten toegekend door een groep';
+$lang['Permission granted'] = 'Toegang toegestaan';
+$lang['Picture informations updated'] = 'afbeeldings informatie bijgewerkt';
+$lang['Plugins'] = 'Plugins';
+$lang['Position'] = 'Positie';
+$lang['Preferences'] = 'Voorkeuren';
+$lang['Properties'] = 'Eigenschappen';
+$lang['Random picture'] = 'Willekeurig plaatje';
+$lang['Rate date'] = 'Beoordelings datum';
+$lang['Rating by guests'] = 'Beoordeling van gasten';
+$lang['Rating'] = 'Beoordeling';
+$lang['Reject All'] = 'Alles afwijzen';
+$lang['Reject'] = 'Afwijzen';
+$lang['Representant'] = 'Representatief';
+$lang['Representation of categories'] = 'Representatieve categorieën';
+$lang['Representative'] = 'Representatief';
+$lang['Represents'] = 'Represents';
+$lang['Save order'] = 'Bewaar sortering';
+$lang['Save to permalink history'] = 'Opslaan in permalink geschiedenis';
+$lang['Select at least one category'] = 'Selecteer minstens 1 categorie';
+$lang['Select at least one picture'] = 'Selecteer minstens 1 plaatje';
+$lang['Select at least one user'] = 'Selecteer minstens 1 gebruiker';
+$lang['Show info'] = 'Toon info';
+$lang['Site manager'] = 'Site manager';
+$lang['Status'] = 'Status';
+$lang['Statistics'] = 'Statistieken';
+$lang['Storage category'] = 'Storage category';
+$lang['Sum of rates'] = 'Eind oordeel';
+$lang['Tag "%s" already exists'] = 'Tag "%s" bestaat al';
+$lang['Tag "%s" was added'] = 'Tag "%s" is toegevoegd';
+$lang['Tag selection'] = 'Tag selectie';
+$lang['Take selected elements out of caddie'] = 'Neem geselecteerde elementen uit de caddie';
+$lang['The %d following tag were deleted'] = 'De volgende tag is verwijderd';
+$lang['The %d following tags were deleted'] = 'De %d volgende tags zijn verwijderd';
+$lang['Unable to check for upgrade.'] = 'Onnmoglijk om een controlle te doen voor een upgrade.';
+$lang['Uninstall'] = 'Deinstalleren';
+$lang['Use default sort order']='Gebruik de standaard sortering (defineerd in de configuratie file)';
+$lang['User comments validation'] = 'Gebruikers commentaar valideren';
+$lang['Users'] = 'Gebruikers';
+$lang['Validate All'] = 'Valideer Alles';
+$lang['Validate'] = 'Valideren';
+$lang['Validation'] = 'Validatie';
+$lang['Version'] = 'Versie';
+$lang['Virtual categories movement'] = 'Virtuele categorie verplaatsing';
+$lang['Virtual categories to move'] = 'Virtuele categorien om te verplaatsen';
+$lang['Virtual category name'] = 'Virtuele categorie naam';
+$lang['Webmaster cannot be deleted'] = 'Webmaster kan niet verwijderd worden';
+$lang['You are running on development sources, no check possible.'] = 'Je werkt op basis van ontwikkelins bronnen, geen controle mogelijk.';
+$lang['You cannot delete your account'] = "Je kan je account niet verwijderen";
+$lang['You cannot move a category in its own sub category'] = 'Je kan een categorie niet verplaatsen in zijn eigen sub categorie';
+$lang['You need to confirm deletion'] = 'Je moet de verwijdering bevestigen';
+$lang['add tags'] = 'Toevoegen tags';
+$lang['adviser'] = 'Adviseer';
+$lang['associate to category'] = 'link aan categorie';
+$lang['associate to group'] = 'link aan een groep';
+$lang['authorized'] = 'Toegestaan';
+$lang['cat_add'] = 'Voeg een virtuele categorie toe';
+$lang['cat_comments_title'] = 'Gebruikers toestaan commentaar te geven op geselecteerde categorieen';
+$lang['cat_error_name'] = 'De naam van een categorie mag niet leeg zijn';
+$lang['cat_lock_title'] = 'Sluit categorieën';
+$lang['cat_private'] = 'Private categorie';
+$lang['cat_public'] = 'Publieke categorie';
+$lang['cat_representant'] = 'Vind een nieuw representant bij willekeur';
+$lang['cat_security'] = 'Publiek / Private';
+$lang['cat_status_title'] = 'Beheer toegang voor geselecteerde categorieën';
+$lang['cat_upload_title'] = 'Selecteer uploadable categorieeën';
+$lang['cat_virtual_added'] = 'Virtuele categorie toegevoegd';
+$lang['cat_virtual_deleted'] = 'Virtuele categorie verwijderd';
+$lang['category'] = 'categorie';
+$lang['conf_access'] = 'Toegangs type';
+$lang['conf_comments_title'] = 'Commentaar';
+$lang['conf_confirmation'] = 'Informatie data geregistereerd in de database';
+$lang['conf_display'] = 'Standaard weergave';
+$lang['conf_history_title'] = 'Geschiedenis';
+$lang['conf_gallery_url_error'] = 'The gallerie URL is niet correct.';
+$lang['conf_main_title'] = 'Index';
+$lang['conf_nb_comment_page_error'] = 'Het aantal commentaren moet tussen 5 and 50 liggen.';
+$lang['config'] = 'Configuratie';
+$lang['confirm'] = 'bevestig';
+$lang['Date'] = 'Datum';
+$lang['delete category'] = 'verwijder categorie';
+$lang['dissociate from category'] = 'verwijder link naar categorie';
+$lang['dissociate from group'] = 'verwijder link naar groep';
+$lang['edit category permissions'] = 'bewerk categorie rechten';
+$lang['editcat_confirm'] = 'Categorie informatie is met succes bijgewerkt.';
+$lang['editcat_uploadable'] = 'Toestaan van upload';
+$lang['elements per page'] = 'elementen per pagina';
+$lang['elements'] = 'elementen';
+$lang['enabled_high'] = 'Hoge weergaven ingeschakeld';
+$lang['file'] = 'bestand';
+$lang['filesize'] = 'bestandsgrote';
+$lang['first element added on %s'] = 'eerste element toegevoegd op %s';
+$lang['forbidden'] = 'Geweigerd';
+$lang['conf_general'] = 'Algemeen';
+$lang['global mode'] = 'global mode';
+$lang['group "%s" added'] = 'groep "%s" toegevoegd';
+$lang['group "%s" deleted'] = 'groep "%s" verwijderd';
+$lang['group "%s" updated'] = 'groep "%s" bijgewerkt';
+$lang['group'] = 'groep';
+$lang['group_add_error1'] = 'De naam van de groep mag geen spatie bevatten of leeg zijn.';
+$lang['group_add_error2'] = 'Deze naam is al in gebruik door een andere groep.';
+$lang['groups'] = 'Groepen';
+$lang['instructions'] = 'Instructies';
+$lang['is_high_disabled'] = '';
+$lang['is_high_enabled'] = 'Hoge kwaliteit';
+$lang['jump to category'] = 'ga naar categorie';
+$lang['jump to image'] = 'ga naar afbeelding';
+$lang['leave'] = 'verlaten';
+$lang['lock'] = 'Sluiten';
+$lang['locked'] = 'Gesloten';
+$lang['manage category elements'] = 'beheer categorie elementen';
+$lang['manage sub-categories'] = 'beheer sub-categorie';
+$lang['manage'] = 'Beheren';
+$lang['maximum height'] = 'maximale hoogte';
+$lang['maximum width'] = 'maximale breedte';
+$lang['nbm_background_treatment_redirect_second'] = 'Executie tijd is om, treatment moet verder gaan [Verwachte tijd: %d seconden].';
+$lang['nbm_background_treatment_redirect_seconds'] = 'Executie tijd is om, treatment moet verder gaan [Verwachte tijd: %d seconden].';
+$lang['nbm_break_timeout_list_user'] = 'Verwachte tijd voor de gebruikerslijst voor een mailing is gelimiteerd. Andere gebruikers staan niet op de lijst.';
+$lang['nbm_break_timeout_send_mail'] = 'Tijd om mail te sturen is gelimiteerd. Andere mailtjes worden overgeslagen.';
+$lang['nbm_col_check_user_send_mail'] = 'aan sturen ?';
+$lang['nbm_col_last_send'] = 'Laatst sturen';
+$lang['nbm_col_mail'] = 'email';
+$lang['nbm_col_user'] = 'Gebruiker';
+$lang['nbm_complementary_mail_content'] = 'Inhoud mail';
+$lang['nbm_content_byebye'] = 'Zie je snel,';
+$lang['nbm_content_goto_1'] = 'Ga naar ';
+$lang['nbm_content_goto_2'] = 'http://www.terwolde.net';
+$lang['nbm_content_hello_1'] = 'Hallo ';
+$lang['nbm_content_hello_2'] = ',';
+$lang['nbm_content_new_elements'] = 'Nieuwe elementen toegevoegd ';
+$lang['nbm_content_new_elements_single'] = ' op ';
+$lang['nbm_content_new_elements_between_1'] = 'tussen ';
+$lang['nbm_content_new_elements_between_2'] = ' en ';
+$lang['nbm_content_subscribe_by_admin'] = 'De webmaster heeft je ingeschreven om melding per mail te ontvangen.';
+$lang['nbm_content_subscribe_by_himself'] = 'Je hebt je ingeschreven voor meldingen per email.';
+$lang['nbm_content_subscribe_link'] = 'Inschrijven';
+$lang['nbm_content_problem_contact'] = 'Als je problemen of een vraag hebt, stuur een bericht aan: ';
+$lang['nbm_content_pb_contact_object'] = '[NBM] Problemen of vragen';
+$lang['nbm_content_unsubscribe_by_admin'] = 'De webmaster heeft je uitgeschreven van de meldingen lijst per email.';
+$lang['nbm_content_unsubscribe_by_himself'] = 'Je hebt jezelf uitgeschreven om meldingen per mail te ontvangen.';
+$lang['nbm_content_click_on'] = ', Klik op ';
+$lang['nbm_content_unsubscribe_link'] = 'Uitschrijven';
+$lang['nbm_info_send_mail_as'] = 'Wanneer niet ingevuld, zal de gallerie titel worden gebruikt';
+$lang['nbm_item_notification'] = 'Melding';
+$lang['nbm_msg_error_sending_email_to'] = 'Fout bij het versturen van email aan %s [%s].';
+$lang['nbm_msg_mail_sent_to'] = 'Mail verstuuurd aan %s [%s].';
+$lang['nbm_msg_n_mail_sent'] = '%d mail is verstuurd.';
+$lang['nbm_msg_n_mails_sent'] = '%d mails zijn verstuurd.';
+$lang['nbm_msg_n_mail_not_send'] = '%d mail is niet verstuurd.';
+$lang['nbm_msg_n_mails_not_send'] = '%d mails zijn niet verstuurd.';
+$lang['nbm_no_mail_to_send'] = 'Geen mail om te versturen.';
+$lang['nbm_no_user_available_to_send_L1'] = 'Geen gebruikers om mail te sturen.';
+$lang['nbm_no_user_available_to_send_L2'] = 'Een gebruiker is beschikbaar, er zijn nieuwe elementen te melden.';
+$lang['nbm_no_user_available_to_send_L3'] = 'Het is mogelijk dat er geen ingeschreven gebruikers zijn (alleen de webmaster kan deze tab zien).';
+$lang['nbm_no_user_to send_notifications_by_mail'] = 'Geen gebruikers om meldingen te versturen per mail.';
+$lang['nbm_object_news'] = 'Nieuwe elementen toegevoegd';
+$lang['nbm_object_subscribe'] = 'Inschrijven om een melding te ontvangen per mail';
+$lang['nbm_object_unsubscribe'] = 'Uitschrijven van meldingen per mail';
+$lang['nbm_param_mode'] = 'Parameter';
+$lang['nbm_redirect_msg'] = 'Bezig met voltooien van de bewerking.'."\n\n".'Even wachten...';
+$lang['nbm_repost_submit'] = 'Verder gaan met de bewerking';
+$lang['nbm_send_complementary_mail_content'] = 'Bijkomende mailinhoud';
+$lang['nbm_send_detailed_content'] = 'Toevoegen gedetaileerde inhoud';
+$lang['nbm_send_mail_as'] = 'Stuur mail als';
+$lang['nbm_send_mail_to_users'] = 'Stuur mail aan gebruikers';
+$lang['nbm_send_mode'] = 'Sturen';
+$lang['nbm_send_options'] = 'Opties';
+$lang['nbm_send_submit'] = 'Stuur';
+$lang['nbm_subscribe_col'] = 'Ingeschreven';
+$lang['nbm_subscribe_mode'] = 'Inschrijven';
+$lang['nbm_title_param'] = 'Parameters';
+$lang['nbm_title_send'] = 'Selecteer ontvangers';
+$lang['nbm_title_subscribe'] = 'Inschrijven/Uitschrijven gebruikers';
+$lang['nbm_unsubscribe_col'] = 'Uitgeschreven';
+$lang['nbm_updated_param_count'] = '%d parameter is bijgewerkt.';
+$lang['nbm_updated_params_count'] = '%d parameters zijn bijgewerkt.';
+$lang['nbm_user_change_enabled_error_on_updated_data_count'] = '%d gebruiker is niet bijgewerkt.';
+$lang['nbm_users_change_enabled_error_on_updated_data_count'] = '%d gebruikers zijn niet bijgewerkt.';
+$lang['nbm_user_change_enabled_false'] = 'Gebruiker %s [%s] is verwijderd van de inschrijvingen lijst.';
+$lang['nbm_user_change_enabled_true'] = 'Gebruiker %s [%s] is toegevoegd aan de inschrijvingen lijst.';
+$lang['nbm_user_change_enabled_updated_data_count'] = '%d gebruiker is bijgewerkt.';
+$lang['nbm_users_change_enabled_updated_data_count'] = '%d gebruikers zijn bijgewerkt.';
+$lang['nbm_user_not_change_enabled_false'] = 'Gebruiker %s [%s] is niet verwijderd van de inschrijvingen lijst.';
+$lang['nbm_user_not_change_enabled_true'] = 'Gebruiker %s [%s] is niet toegevoegd aan de inschrijvingen lijst.';
+$lang['nbm_user_x_added'] = 'Gebruiker %s [%s] toegevoegd.';
+$lang['nbm_warning_subscribe_unsubscribe'] = 'Waarschuwing: in/uitschrijven zal een e-mail versturen aan de gebruiker';
+$lang['nbm_send_html_mail'] = 'Stuur mail in HTML formaat';
+$lang['nbm_send_recent_post_dates'] = 'Inclusief tonen van recente afbeeldingen op basis van datum';
+$lang['nbm_info_send_recent_post_dates'] = 'Alleen beschikbaar in HTML formaat';
+$lang['no_write_access'] = 'geen schrijftoegang';
+$lang['path'] = 'path';
+$lang['permissions'] = 'Rechten';
+$lang['private'] = 'private';
+$lang['properties'] = 'Eigenschappen';
+$lang['public'] = 'publiek';
+$lang['purge never used notification feeds'] = 'verwijder nimmer gebruikte meldingen';
+$lang['purge sessions'] = 'verwijder sessies';
+$lang['randomly represented'] = 'willekeurig represented';
+$lang['registration_date'] = 'registratie datum';
+$lang['remote_site'] = 'Remote site';
+$lang['remote_site_clean'] = 'opschonen';
+$lang['remote_site_clean_hint'] = 'verwijder remote listing.xml bestand';
+$lang['remote_site_generate'] = 'genereer lijsten';
+$lang['remote_site_generate_hint'] = 'genereer bestand listing.xml op remote site';
+$lang['remote_site_local_create'] = 'maak deze site';
+$lang['remote_site_local_found'] = 'Een lokale listing.xml bestand is gevonden voor ';
+$lang['remote_site_local_update'] = 'lees locale listing.xml en werk bij';
+$lang['remote_site_test'] = 'test';
+$lang['remote_site_test_hint'] = 'test deze remote site';
+$lang['remote_site_uncorrect_url'] = 'Remote site url moet starten met http of https end moet allen bestaan uit characters met "/", "a-zA-Z0-9", "-" or "_"';
+$lang['remove tags'] = 'verwijder tags';
+$lang['repair and optimize database'] = 'repareer en optimaliseer de database';
+$lang['selection'] = 'selectie';
+$lang['set to'] = 'instellen op';
+$lang['singly represented'] = 'afzonderlijk vertegenwoordigd';
+$lang['site_already_exists'] = 'Deze site bestaat al';
+$lang['site_create'] = 'maak een nieuwe site : (geef de URL to create_listing_file.php)';
+$lang['site_created'] = 'gemaakt';
+$lang['site_delete'] = 'verwijderen';
+$lang['site_delete_hint'] = 'verwijder de site en alle bijbehorende elementen';
+$lang['site_deleted'] = 'verwijderd';
+$lang['site_err'] = 'er heeft zich een fout voorgedaan';
+$lang['site_err_remote_file_not_found'] = 'bestand create_listing_file.php op de remote site is niet gevonden';
+$lang['site_local'] = 'Lokaal';
+$lang['site_remote'] = 'Remote';
+$lang['site_synchronize'] = 'synchronizeer';
+$lang['site_synchronize_hint'] = 'werk de database bij vanuit bestanden';
+$lang['status'] = 'status';
+$lang['storage'] = 'Map';
+$lang['sub-categories'] = 'sub-categorie';
+$lang['synchronize metadata'] = 'synchronizeer metadata';
+$lang['synchronize'] = 'synchronizeer';
+$lang['target'] = 'doel';
+$lang['thumbnail'] = 'thumbnail';
+$lang['title'] = 'titel';
+$lang['title_categories'] = 'Categorie beheer';
+$lang['title_configuration'] = 'Piwigo configuratie';
+$lang['title_default'] = 'Piwigo beheer';
+$lang['title_edit_cat'] = 'Bewerk een categorie';
+$lang['title_groups'] = 'Groepsbeheer';
+$lang['title_liste_users'] = 'Gebruikerslijst';
+$lang['title_picmod'] = 'Verander de informatie van een plaatje';
+$lang['title_thumbnails'] = 'Thumbnails maken';
+$lang['title_update'] = 'Database synchronizatie met bestanden';
+$lang['title_upload'] = 'afbeeldingen wachten op bevestiging';
+$lang['tn_all'] = 'alles';
+$lang['tn_alone_title'] = 'afbeeldingen zonder thumbnail (alleen jpeg en png)';
+$lang['tn_err_height'] = 'Hoogte moet groter zijn dan';
+$lang['tn_err_width'] = 'Breedte moet groter zijn dan';
+$lang['tn_format'] = 'voor het bestandsformaat';
+$lang['tn_no_missing'] = 'Geen ontbrekende thumbnail';
+$lang['tn_no_support'] = 'Afbeelding is niet bereikbaar of er is geen support';
+$lang['tn_params_GD'] = 'GD versie';
+$lang['tn_params_title'] = 'Miniatuur parameters';
+$lang['tn_results_gen_time'] = 'genereerd in';
+$lang['tn_results_title'] = 'Resultaat van verkleinen';
+$lang['tn_stats'] = 'Algemen statistieken';
+$lang['tn_stats_max'] = 'maximale tijd';
+$lang['tn_stats_mean'] = 'gemiddelde tijd';
+$lang['tn_stats_min'] = 'minimale tijd';
+$lang['tn_stats_nb'] = 'aantal verkleinde afbeeldingen';
+$lang['tn_stats_total'] = 'totale tijd';
+$lang['tn_thisformat'] = 'voor dit bestandsformaat';
+$lang['unit mode'] = 'unit mode';
+$lang['unlocked'] = 'open';
+$lang['unset'] = 'niet ingesteld';
+$lang['up'] = 'verplaats naar boven';
+$lang['update categories informations'] = 'categorie informatie bijwerken';
+$lang['update images informations'] = 'afbeeldings informatie bijwerken';
+$lang['update'] = 'Synchronizeer';
+$lang['update_cats_subset'] = 'Alleen naar de bestaande categoriën terugbrengen';
+$lang['update_default_title'] = 'Kies een optie';
+$lang['update_display_info'] = 'toon maximale informatie (toegevoegde categoriën en elementen, verwijderde categoriën en elementen)';
+$lang['update_err_pwg_version_differs'] = 'Piwigo versie verschild op de remote site';
+$lang['update_err_pwg_version_differs_info'] = 'Versie van create_listing_file.php op de remote site en Piwigo moeten gelijk zijn';
+$lang['update_err_remote_listing_not_found'] = 'listing.xml file is niet gevonden';
+$lang['update_err_remote_listing_not_found_info'] = 'listing.xml file is niet gevonden op de remote site. Het bestand word gegenereerd door het commando "genereer listing" in de Site manager';
+$lang['update_error_list_title'] = 'Fouten lijst';
+$lang['update_errors_caption'] = 'Foutmeldingen afvangen';
+$lang['update_infos_title'] = 'Gedetaileerde informatie';
+$lang['update_missing_file_or_dir'] = 'Bestand/map lees fout';
+$lang['update_missing_file_or_dir_info'] = 'Het bestand of map kan niet worden benaderd (of het bestand of map bestaat niet of geen rechten)';
+$lang['update_missing_tn_info'] = 'Een afbeelding heeft een indexafbeelding nodig. De indexafbeeling moet in de subdirectorie "thumbnail" van de betreffende categorie aanwezig zijn. De indexafbeelding moet starten met het in de configuratie opgegeven voorvoegsel en mag alleen een extentie bevatten die voorkomt in de volgende lijst:';
+$lang['update_missing_tn_short'] = 'ontbrekende thumbnail';
+$lang['update_nb_del_categories'] = 'categoriën verwijderd uit de database';
+$lang['update_nb_del_elements'] = 'elementen verwijderd uit de database';
+$lang['update_nb_elements_metadata_available'] = 'elementen gesynchroniseerd met de metadata van de bij behorende bestanden';
+$lang['update_nb_elements_metadata_sync'] = 'element informatie gesynchronizeerd met bestands metadata';
+$lang['update_nb_errors'] = 'fouten tijdens synchronizatie';
+$lang['update_nb_new_categories'] = 'categoriën toegevoegd aan de database';
+$lang['update_nb_new_elements'] = 'elementen toegevoegd aan de database';
+$lang['update_nb_upd_elements'] = 'elementen bijgewerkt in de database';
+$lang['update_part_research'] = 'Zoek naar nieuwe afbeeldingen in mappen';
+$lang['update_research_added'] = 'toegevoegd';
+$lang['update_research_deleted'] = 'verwijderd';
+$lang['update_result_metadata'] = 'Metadata synchronizatie resultaten';
+$lang['update_simulate'] = 'alleen een simulatie uitvoeren (er worden geen veranderingen aangebracht in de database)';
+$lang['update_simulation_title'] = '[Simulatie]';
+$lang['update_sync_all'] = 'mappen + bestanden';
+$lang['update_sync_dirs'] = 'alleen mappen';
+$lang['update_sync_files'] = 'synchronizeer bestanden met de database';
+$lang['update_sync_metadata'] = 'synchronizeer bestands metadata met de database element informatie';
+$lang['update_sync_metadata_all'] = 'ook reeds synchronizeerde elementen';
+$lang['update_used_metadata'] = 'Gebruikte metadata';
+$lang['update_wrong_dirname_info'] = 'De naam van de mappen en bestanden moeten bestaan uit letters, "-", "_" of "."';
+$lang['update_wrong_dirname_short'] = 'verkeerde bestandsnaam';
+$lang['upload'] = 'Upload';
+$lang['user "%s" added'] = 'gebruiker "%s" toegevoegd';
+$lang['user_status'] = 'Gebruikers status';
+$lang['user_status_admin'] = 'Beheerder';
+$lang['user_status_generic'] = 'Generic';
+$lang['user_status_guest'] = 'Gast';
+$lang['user_status_normal'] = 'Gebruiker';
+$lang['user_status_webmaster'] = 'Webmaster';
+$lang['username'] = 'gebruikersnaam';
+$lang['users'] = 'Gebruikers';
+$lang['virtual_category'] = 'Virtuele categoriën';
+$lang['waiting'] = 'Wachten';
+$lang['is_default_group'] = 'standaard';
+$lang['toggle_is_default_group'] = 'Aanpassen \'standaard groep\' eigenschap';
+$lang['Advanced_features'] = 'Geavanceerde functies';
+$lang['Elements_not_linked'] = 'Niet gelinkte elementen';
+$lang['special_admin_menu'] = 'Speciaal';
+$lang['Duplicates'] = 'Bestanden met de zelfde naam in meer dan één physieke categorie';
+
+$lang['Overall'] = 'Totaal';
+$lang['Year'] = 'Jaar';
+$lang['Month'] = 'Maand';
+$lang['Day'] = 'Dag';
+$lang['Pages seen'] = 'Pagina\'s bekeken';
+$lang['Pictures'] = 'Afbeeldingen';
+$lang['time'] = 'tijd';
+$lang['user'] = 'gebruiker';
+$lang['IP'] = 'IP';
+$lang['image'] = '';
+$lang['section'] = 'sectie';
+$lang['tags'] = 'tags';
+$lang['conf_history_guest'] = 'Bewaar pagina bezoek van gasten';
+$lang['conf_history_user'] = 'Bewaar pagina bezoek van gebruikers';
+$lang['conf_history_admin'] = 'Bewaar pagina bezoek van beheerders';
+$lang['cat_options_title'] = 'Eigenschappen';
+$lang['An information email was sent to group "%s"'] = 'Een informatie email is verstuurd naar de groep "%s';
+$lang['Send an information email to group members'] = 'Stuur een informatie email to groep leden';
+$lang['Group'] = 'Groep';
+$lang['[%s] Come to visit the category %s'] = '[%s] Bezoek de categorie %s';
+$lang['Hello,'] = 'Hallo,';
+$lang['See you soon.'] = 'Zie je snel.';
+$lang['Come to discover the category:'] = 'Ondek de categorie:';
+$lang['mail_content'] = 'Mail inhoud';
+$lang['none'] = 'geen';
+$lang['high'] = 'hoog';
+$lang['other'] = 'anders';
+$lang['Element type'] = 'Element type';
+$lang['User'] = 'Gebruiker';
+$lang['Image id'] = 'Afbeeldings id';
+$lang['Summary'] = 'Overzicht';
+$lang['%d line filtered'] = '%d regel gefilterd';
+$lang['%d lines filtered'] = '%d regels filterd';
+$lang['%d guest'] = '%d gast';
+$lang['%d guests'] = '%d gasten';
+$lang['Hour'] = 'Uur';
+$lang['is_the_guest'] = 'gast';
+$lang['is_the_default'] = 'Standaard waarden';
+$lang['High filesize'] = 'Grote bestandsformaat';
+// --------- Starting below: New or revised $lang ---- from version 1.7.1
+$lang['Guest cannot be deleted'] = 'Gast kan niet verwijderd worden';
+$lang['Default user cannot be deleted'] = 'Standaart gebruiker kan niet verwijderd worden';
+$lang['purge history detail'] = 'details van de filtringsgeschiedenis';
+$lang['purge history summary'] = 'overzicht van de filtergeschiedenis';
+$lang['c13y_title'] = 'Controleer integriteit';
+$lang['c13y_Anomaly'] = 'Onregelmatigheid';
+$lang['c13y_Correction'] = 'Correctie';
+$lang['c13y_Automatic_correction'] = 'Automatische correctie';
+$lang['c13y_Impossible_automatic_correction'] = 'Onmogelijke automatische correctie';
+$lang['c13y_Correction_applied_success'] = 'Correctie die met succes is toegepast';
+$lang['c13y_Correction_applied_error'] = 'Correctie die met fout wordt toegepast';
+$lang['c13y_anomaly_count'] = '%d Onregelmatigheid ontdekt.';
+$lang['c13y_anomalies_count'] = '%d Onregelmatigheden ontdekt.';
+$lang['c13y_anomaly_corrected_count'] = '%d Onregelmatigheid is gecorrigeerd.';
+$lang['c13y_anomalies_corrected_count'] = '%d Onregelmatigheden die zijn gecorrigeerd.';
+$lang['c13y_anomaly_not_corrected_count'] = '%d Onregelmatigheid ontdekt is niet gecorrigeerd.';
+$lang['c13y_anomalies_not_corrected_count'] = '%d Onregelmatigheden zijn niet gecorrigeerd.';
+$lang['c13y_more_info'] = 'Gaa naar %s of %s voor meer informatie';
+$lang['c13y_more_info_forum'] = 'het forum';
+$lang['c13y_more_info_wiki'] = 'de wiki';
+$lang['c13y_exif_anomaly'] = '%s waarde is niet een correct bestand omdat exif niet ondersteund word';
+$lang['c13y_exif_correction'] = '%s moet aangepast worden naar false in je config_local.inc.php bestand';
+$lang['c13y_guest_non_existent'] = 'Hooft "gast" gebruiker bestaat niet meer';
+$lang['c13y_bad_guest_status'] = 'Hooft "gast" gebruikers status is niet correct';
+$lang['c13y_default_non_existent'] = 'Standaard gebruiker bestaat niet meer';
+$lang['c13y_webmaster_non_existent'] = 'Hoofd "webmaster" bestaat niet meer';
+$lang['c13y_bad_webmaster_status'] = 'Hoofd "webmaster" status is niet correct';
+$lang['c13y_user_created'] = 'Gebruiker "%s" gemaakt met wachtwoord "%s" ';
+$lang['c13y_user_status_updated'] = 'Status van de gebruiker "%s" is bijgewerkt';
+$lang['add new elements to caddie'] = 'Voeg nieuwe elementen toe ann caddie';
+// --------- Starting below: New or revised $lang ---- from Butterfly (1.8)
+$lang['no_display_thumbnail'] = 'Geen weergave';
+$lang['display_thumbnail_classic'] = 'Klassieke weergave';
+$lang['display_thumbnail_hoverbox'] = 'Hoverbox weergave';
+$lang['Thumbnails'] = 'Voorbeeldplaatjes';
+$lang['obligatory_user_mail_address'] = 'Email adres is verplicht voor alle gebruikers';
+$lang['Minimum privacy level'] = 'Minimale privacy nivo';
+$lang['Privacy level'] = 'Privacy nivo';
+$lang['Level 0'] = '---';
+$lang['Level 1'] = 'Contacten';
+$lang['Level 2'] = 'Vrienden';
+$lang['Level 4'] = 'Familie';
+$lang['Level 8'] = 'Admins';
+$lang['c13y_maintenance'] = 'Herinitalizeer de integrieteitscontrole';
+$lang['Check all'] = 'Selecteer alles';
+$lang['Uncheck all'] = 'Deselecteer alles';
+$lang['c13y_check_auto'] = 'Controleer de aoutomatische correcties';
+$lang['c13y_submit_correction'] = 'Pas geselecteerde correcties toe';
+$lang['c13y_submit_ignore'] = 'Negeer geselecteerde anomalieën';
+$lang['c13y_submit_refresh'] = 'Ververs';
+$lang['c13y_ignore_msg1'] = 'De anomalie worden genegeerd totdat de volgende versie';
+/* TODO */ $lang['c13y_ignore_msg2'] = 'Correction the anomaly will cancel the fact that it\'s ignored';
+$lang['c13y_anomaly_ignored_count'] = '%d anomalie is genegeerd.';
+$lang['c13y_anomalies_ignored_count'] = '%d anomalieen zijn genegeerd.';
+$lang['plugins_need_update'] = 'Plugins welke bijgewerkt moeten worden';
+$lang['plugins_dontneed_update'] = 'Plugins zijn recent';
+$lang['plugins_cant_check'] = 'Plugin versies kunnen niet gecontroleerd worden';
+$lang['plugins_actual_version'] = 'Huidige <br>versie';
+$lang['plugins_new_version'] = 'Beschikbare<br>versie';
+$lang['plugins_auto_update'] = 'Automatische upgrade';
+$lang['plugins_auto_install'] = 'Automatische installatie';
+$lang['plugins_download'] = 'Download bestand';
+$lang['plugins_tab_list'] = 'Plugin lijst';
+$lang['plugins_tab_update'] = 'Controleer op updates';
+$lang['plugins_tab_new'] = 'Andere plugins';
+$lang['plugins_revisions'] = 'Lastste revisie';
+$lang['plugins_delete'] = 'Verwijder';
+$lang['plugins_confirm_delete'] = 'Weet U het zeker dat u deze plugin wilt verwijderen?';
+$lang['plugins_confirm_install'] = 'Weet U het zeker dat u deze plugin wilt installeren?';
+$lang['plugins_confirm_upgrade'] = 'Weet U het zeker dat u deze plugin wilt bijwerken? Je moet controleren of deze versie niet gedeinstaleerd moet worden.';
+$lang['plugins_upgrade_ok'] = '%s zijn succesvol bijgewerkt.';
+$lang['plugins_install_ok'] = 'Plugin is succesvol gekopieerd';
+$lang['plugins_install_need_activate'] = 'Je zou kan gaan naar de lijst om de plugin te installeren en activeren.';
+$lang['plugins_temp_path_error'] = 'Kan geen tijdelijk bestand maken.';
+$lang['plugins_dl_archive_error'] = 'Kan geen archief downloaden.';
+$lang['plugins_archive_error'] = 'Kan het archief niet lezen of uitpakken.';
+$lang['plugins_extract_error'] = 'Een fout is opgetreden tijdens het uitpakken (%s).';
+$lang['plugins_check_chmod'] = 'Controleer de "plugins" folder en de sub-folders permissies (CHMOD).';
+$lang['plugins_server_error'] = 'Kan niet met de server verbinden.';
+$lang['Purge compiled templates'] = 'Purge samengestelde sjablonen';
+$lang['Caddie is currently empty'] = 'Caddie is momenteel leeg';
+$lang['DEMO'] = 'Demo';
+$lang['HOME'] = 'Piwigo Home';
+$lang['FORUM'] = 'Bijstand';
+$lang['BUGS'] = 'Fouten';
+$lang['EXTENSIONS'] = 'Extensies';
+$lang['WIKI / DOC'] = 'Documentatie';
+$lang['conf_upload_title'] = 'Upload';
+$lang['Show upload link every time'] = 'Show upload link altijd';
+$lang['User access level to upload'] = 'Gebruiker toegangsniveau om te uploaden';
+$lang['ACCESS_0'] = 'Gratis toegang';
+$lang['ACCESS_1'] = 'Toegang tot alles';
+$lang['ACCESS_2'] = 'Toegang tot geabbonnneerde';
+$lang['ACCESS_3'] = 'Toegang voor beheerders';
+$lang['ACCESS_4'] = 'Toegang voor webmasters';
+$lang['ACCESS_5'] = 'Geen toegang';
+$lang['A new version of Piwigo is available.'] = 'Een nieuwere versie van Piwigo is beschikbaar.';
+$lang['Piwigo Administration'] = 'Piwigo Beheer';
+$lang['Piwigo version'] = 'Piwigo versie';
+$lang['You are running the latest version of Piwigo.'] = 'Je hebt de laatste versie van Piwigo.';
+$lang['c13y_version_anomaly'] = 'De versie van %s [%s] welke geinstalleerd is is niet compatibel met de vereiste versie [%s]';
+$lang['c13y_version_correction'] = 'Je moet je systeem bijwerken om volledig gebruik te kunnen maken de software, anders kan de software mogelijk niet goed werken, of helemaal niet';
+$lang['Deleted on'] = 'Verwijderd op';
+$lang['Last hit'] =  'Laaste hit';
+$lang['Hits'] = 'Hits';
+$lang['GD library is missing'] = 'GD library is  er niet';
+$lang['conf_extents'] = 'Sjablonen';
+$lang['extend_for_templates'] = 'Uitbreiding voor sjablonen';
+$lang['Replacement of original templates'] = 
+ 'Vervanging van de originele sjablonen door aangepaste sjablonen van sjabloon-extensie submap';
+$lang['Replacers'] = 'Vervangers (eigenbouw sjabloon)';
+$lang['Original templates'] = 'Origineel sjabloontemplates';
+$lang['Optional URL keyword'] = 'Optionele URL sleutelwoord';
+$lang['Templates recorded.'] = 'Sjabloon configuratie is vastgelegd.';
+$lang['Optimizations completed'] = 'Alle verbeteringen zijn succesvol afgerond.';
+$lang['Optimizations errors'] = 'Verbeteringen zijn afgerond met enkele fouten.';
+$lang['delete this comment'] = 'verwijder dit commentaar';
+$lang['link_info_image'] = 'Aanpassen informatie';
+$lang['edit category informations'] = 'bewerk categorie informatie';
+$lang['nothing'] = 'niets';
+$lang['overrides existing values with empty ones'] = 'overschrijft de bestaande waarden met lege waardes';
+/*TODO*/$lang['manage image ranks'] = 'manage image ranks';
+/*TODO*/$lang['Manage image ranks'] = 'Manage image ranks';
+/*TODO*/$lang['Edit ranks'] = 'Edit ranks';
+/*TODO*/$lang['No element in this category'] = 'No element in this category';
+/*TODO*/$lang['Images manual order was saved'] = 'Images manual order was saved';
+/*TODO*/$lang['ranks'] = 'ranks';
+$lang['Drag to re-order'] = 'sleep om te herschikken';
+$lang['Unable to retrieve server informations since allow_url_fopen is disabled.'] = 'Kan geen server verkrijgen omdat allow_url_fopen is uitgeschakeld.';
+$lang['Quick Local Synchronization'] = 'Snelle lokale Synchronizatie';
+$lang['No photo can be deleted'] = 'Geen enkele foto kan verwijderd worden';
+$lang['Note: Only deletes photos added with pLoader'] = 'Noot: Kan alleen foto\'s verwijderen welke met ploarde geplaatst zijn';
+$lang['Delete selected photos'] = 'Verwijder geselecteerde foto\'s';
+$lang['%d photo was deleted'] = '%d foto is verwijderd';
+$lang['%d photos were deleted'] = '%d foto\'s zijn verwijderd';
+$lang['Bound template'] = 'Gebonden sjabloon';
+$lang['Downloads'] = 'Downloads';
+$lang['Released on'] = 'Uitgegeven op';
+$lang['Number of downloads'] = 'Aantal downloads';
+?>
Index: /tags/2.0.2/language/nl_NL/common.lang.php
===================================================================
--- /tags/2.0.2/language/nl_NL/common.lang.php	(revision 3278)
+++ /tags/2.0.2/language/nl_NL/common.lang.php	(revision 3278)
@@ -0,0 +1,364 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Langage informations
+$lang_info['language_name'] = 'Dutch';
+$lang_info['country'] = 'Nederland';
+$lang_info['direction'] = 'ltr';
+$lang_info['code'] = 'nl';
+$lang_info['zero_plural'] = true;
+
+$lang['%.2f (beoordeling %d aantal x, standaard deviation = %.2f)'] = '%.2f (beoordeling %d aantal x, standaard deviation = %.2f)';
+$lang['%d Kb'] = '%d Kb';
+$lang['%d category updated'] = '%d categorie bijgewerkt';
+$lang['%d categories updated'] = '%d categorieën bijgewerkt';
+$lang['%d comment to validate'] = '%d commentaar voor validatie';
+$lang['%d comments to validate'] = '%d commentaren voor validatie';
+$lang['%d new comment'] = '%d nieuw commentaar';
+$lang['%d new comments'] = '%d nieuw commentaar';
+$lang['%d comment'] = '%d commentaar';
+$lang['%d comments'] = '%d commentaren';
+$lang['%d hit'] = '%d bezoeker';
+$lang['%d hits'] = '%d bezoekers';
+$lang['%d new element'] = '%d nieuw element';
+$lang['%d new elements'] = '%d nieuwe elementen';
+$lang['%d new user'] = '%d nieuwe gebruiker';
+$lang['%d new users'] = '%d nieuwe gebruikers';
+$lang['%d waiting element'] = '%d wachtende element';
+$lang['%d waiting elements'] = '%d wachtende elementen';
+$lang['About'] = 'Over';
+$lang['All tags must match'] = 'Alle tags moeten kloppen';
+$lang['All tags'] = 'Alle tags';
+$lang['Any tag'] = 'Elke tag';
+$lang['At least one listed rule must be satisfied.'] = 'Op zijn minst moet aan één regel worden voldaan.';
+$lang['At least one tag must match'] = 'Op zijn minst moet een tag kloppen';
+$lang['Author'] = 'Auteur';
+$lang['Average rate'] = 'Gemiddeld oordeel';
+$lang['Categories'] = 'Categorieën';
+$lang['Category'] = 'Categorie';
+$lang['Close this window'] = 'Sluit dit venster';
+$lang['Complete RSS feed'] = 'Complete RSS feed (afbeeldingen, commentaar)';
+$lang['Confirm Password'] = 'Bevestig wachtwoord';
+$lang['Connection settings'] = 'Verbindingsinstellingen';
+$lang['Connection'] = 'Verbinding';
+$lang['Contact webmaster'] = 'Contact de webmaster';
+$lang['Create a new account'] = 'Maak een nieuwe account';
+$lang['Created on'] = 'Gemaakt op';
+$lang['Creation date'] = 'Aanmaak datum';
+$lang['Current password is wrong'] = 'Huidige wachtwoord is niet juist';
+$lang['Dimensions'] = 'Dimenties';
+$lang['Display'] = 'Weergeven';
+$lang['Each listed rule must be satisfied.'] = 'Aan elke regel moet worden voldaan.';
+$lang['Email address is missing'] = 'Email adres is niet ingevuld';
+$lang['Email address'] = 'Email adres';
+$lang['Enter your personnal informations'] = 'Vul uw persoonlijke informatie in';
+$lang['Error sending email'] = 'Fout bij het versturen van email';
+$lang['File name'] = 'Bestandsnaam';
+$lang['File'] = 'Bestand';
+$lang['Filesize'] = 'Bestands grote';
+$lang['Filter and display'] = 'Filteren en tonen';
+$lang['Filter'] = 'Filter';
+$lang['Forgot your password?'] = 'Wachtwoord vergeten?';
+$lang['Go through the gallery as a visitor'] = 'Ga naar de gallerie als gast';
+$lang['Help'] = 'Help';
+$lang['Identification'] = 'Identificatie';
+$lang['Image only RSS feed'] = 'Image only RSS feed';
+$lang['Keyword'] = 'Keyword';
+$lang['Links'] = 'Links';
+$lang['Mail address'] = 'Mail adres';
+$lang['N/A'] = 'Niet bekend';
+$lang['New on %s'] = 'Nieuw op %s';
+$lang['New password confirmation does not correspond'] = 'Nieuw wachtwoord bevestiging komt niet overeen';
+$lang['New password sent by email'] = 'Nieuw wachtwoord is verzonden per email';
+$lang['No email address'] = 'Geen email adres';
+$lang['No user matches this email address'] = 'Geen gebruiker gevonden met dit email adres';
+$lang['Notification'] = 'Melding';
+$lang['Number of items'] = 'Aantal items';
+$lang['Original dimensions'] = 'Originele dimenties';
+$lang['Password forgotten'] = 'Wachtwoord vergeten';
+$lang['Password'] = 'Wachtwoord';
+$lang['Post date'] = 'Plaatsings datum';
+$lang['Posted on'] = 'Geplaatst op';
+$lang['Profile'] = 'Profiel';
+$lang['Quick connect'] = 'Snel inloggen';
+$lang['RSS feed'] = 'RSS feed';
+$lang['Rate'] = 'Beoordeling';
+$lang['Register'] = 'Registreren';
+$lang['Registration'] = 'Registratie';
+$lang['Related tags'] = 'Aanverwante tags';
+$lang['Reset'] = 'Reset';
+$lang['Retrieve password'] = 'Ontvang wachtwoord';
+$lang['Search rules'] = 'Zoek opties';
+$lang['Search tags'] = 'Zoek tags';
+$lang['Search'] = 'Zoeken';
+$lang['See available tags'] = 'Toon beschikbare tags';
+$lang['Send new password'] = 'Stuur nieuw wachtwoord';
+$lang['Since'] = 'Sinds';
+$lang['Sort by'] = 'Sorteren op';
+$lang['Sort order'] = 'Sorteer volgorde';
+$lang['Tag'] = 'Tag';
+$lang['Tags'] = 'Tags';
+$lang['The RSS notification feed provides notification on news from this website : new pictures, updated categories, new comments. Use a RSS feed reader.'] = 'De RSS feed geeft meldingen als er nieuws is op deze website: nieuwe afbeeldingen, bijgewerkte categorieën, nieuw commentaar. Gebruik hiervoor een rss lezer.';
+$lang['Unknown feed identifier'] = 'Onbekende feed identifier';
+$lang['User comments'] = 'Gebruikers commentaar';
+$lang['Username'] = 'Gebruikersnaam';
+$lang['Visits'] = 'Bezoeken';
+$lang['Webmaster'] = 'Webmaster';
+$lang['Week %d'] = 'Week %d';
+$lang['about_page_title'] = 'Over Piwigo';
+$lang['access_forbiden'] = 'Je hebt geen rechten tot de opgevraagde pagina';
+$lang['add to caddie'] = 'Toevoegen aan caddie';
+$lang['add_favorites_hint'] = 'voeg deze afbeelding toe aan jou favorieten';
+$lang['admin'] = 'Beheer';
+$lang['adviser_mode_enabled'] = 'Advies mode geactiveerd';
+$lang['all'] = 'alle';
+$lang['ascending'] = 'ascending';
+$lang['author(s) : %s'] = 'auteur(s) : %s';
+$lang['auto_expand'] = 'Toon alle categorieën';
+$lang['became available after %s (%s)'] = 'geplaatst na %s (%s)';
+$lang['became available before %s (%s)'] = 'geplaats voor %s (%s)';
+$lang['became available between %s (%s) and %s (%s)'] = 'geplaatst tussen %s (%s) en %s (%s)';
+$lang['became available on %s'] = 'geplaatst op %s';
+$lang['best_rated_cat'] = 'Best beoordeeld';
+$lang['best_rated_cat_hint'] = 'weergeven van de hoogste beoordeling';
+$lang['caddie'] = 'caddie';
+$lang['calendar'] = 'kalender';
+$lang['calendar_any'] = 'Alle';
+$lang['calendar_hint'] = 'weergeven elke dag met afbeelding, maand per maand';
+$lang['calendar_picture_hint'] = 'toon alle afbeelding toegevoegt op ';
+$lang['calendar_view'] = 'Bekijk';
+$lang['chronology_monthly_calendar'] = 'Maand kalender';
+$lang['chronology_monthly_list'] = 'Maand lijst';
+$lang['chronology_weekly_list'] = 'Week lijst';
+$lang['click_to_redirect'] = 'Klik hier als je browser je niet doorstuurt';
+$lang['comment date'] = 'commentaar datum';
+$lang['comment'] = 'Commentaar';
+$lang['comment_added'] = 'Je commentaar is geregistreerd';
+$lang['comment_anti-flood'] = 'Anti-flood systeem : je moet even wachten voordat je weer nieuw commentaar kunt plaatsen';
+$lang['comment_not_added'] = 'Je commentaar is  NIET geregistreerd omdat de validatie regels de plaatsing voorkwam';
+$lang['comment_to_validate'] = 'Een beheerder moet je commentaar goedkeuren voordat het zichtbaar word.';
+$lang['comment_user_exists'] = 'Deze gebruikersnaam is al in gebruik';
+$lang['comments'] = 'Commentaar';
+$lang['comments_add'] = 'voeg commentaar toe';
+$lang['created after %s (%s)'] = 'Gemaakt na %s (%s)';
+$lang['created before %s (%s)'] = 'Gemaakt voor %s (%s)';
+$lang['created between %s (%s) and %s (%s)'] = 'Gemaakt tussen %s (%s) en %s (%s)';
+$lang['created on %s'] = 'gemaakt op %s';
+$lang['customize'] = 'Aanpassen';
+$lang['customize_page_title'] = 'Je gallerie aanpassen ';
+$lang['day'][0] = 'Zondag';
+$lang['day'][1] = 'Maandag';
+$lang['day'][2] = 'Dinsdag';
+$lang['day'][3] = 'Woensdag';
+$lang['day'][4] = 'Donderdag';
+$lang['day'][5] = 'Vrijdag';
+$lang['day'][6] = 'Zaterdag';
+$lang['default_sort'] = 'Standaard';
+$lang['del_favorites_hint'] = 'verwijder deze foto van je favorieten';
+$lang['delete'] = 'Verwijderen';
+$lang['descending'] = 'descending';
+$lang['download'] = 'download';
+$lang['download_hint'] = 'download dit bestand';
+$lang['edit'] = 'bewerk(en)';
+$lang['err_date'] = 'verkeerde datum';
+$lang['excluded'] = 'uitsluiten';
+$lang['favorite_cat'] = 'Mijn favorieten';
+$lang['favorite_cat_hint'] = 'toon mijn favoriete foto\'s';
+$lang['favorites'] = 'Favorieten';
+$lang['first_page'] = 'Eerste';
+$lang['gallery_locked_message'] = 'De gallerie is in onderhoud. Probeer het later nog eens.';
+$lang['generation_time'] = 'Pagina gegenereerd in';
+$lang['guest'] = 'gast';
+$lang['hello'] = 'Hallo';
+$lang['hint_admin'] = 'Alleen voor beheerders';
+$lang['hint_category'] = 'Toon afbeelding van het begin van de categorie';
+$lang['hint_comments'] = 'Bekijk de laatste gebruikerscommentaar';
+$lang['hint_customize'] = 'Verschijning van de gallerie aanpassen';
+$lang['hint_search'] = 'zoeken';
+$lang['home'] = 'Home';
+$lang['identification'] = 'Identificatie';
+$lang['images_available_cpl'] = 'in deze categorie';
+$lang['images_available_cat'] = 'in %d sub-categorie';
+$lang['images_available_cats'] = 'in %d sub-categorieën';
+$lang['included'] = 'inclusief';
+$lang['invalid_pwd'] = 'Verkeerd wachtwoord!';
+$lang['language']='Taal';
+$lang['last %d days'] = 'laaste %d dagen';
+$lang['last_page'] = 'Laatste';
+$lang['logout'] = 'Loguit';
+$lang['mail_address'] = 'E-mail adres';
+$lang['mandatory'] = 'verplicht';
+$lang['maxheight'] = 'Maximale hoogte van de afbeelding';
+$lang['maxheight_error'] = 'Maximale hoogte moet een veelvoud zijn van 50';
+$lang['maxwidth'] = 'Maximale breedte van het afbeelding';
+$lang['maxwidth_error'] = 'Maximale breedte moet een veelvoud zijn van 50';
+$lang['mode_created_hint'] = 'toon een kalender per aanmaak datum';
+$lang['mode_flat_hint'] = 'toont alle elementen in alle sub-categorieën';
+$lang['mode_normal_hint'] = 'terug naar normaal kijken';
+$lang['mode_posted_hint'] = 'toon een kalender met datums van plaatsen';
+$lang['month'][10] = 'Oktober';
+$lang['month'][11] = 'November';
+$lang['month'][12] = 'December';
+$lang['month'][1] = 'Januari';
+$lang['month'][2] = 'Februari';
+$lang['month'][3] = 'Maart';
+$lang['month'][4] = 'April';
+$lang['month'][5] = 'Mei';
+$lang['month'][6] = 'Juni';
+$lang['month'][7] = 'Juli';
+$lang['month'][8] = 'Augustus';
+$lang['month'][9] = 'September';
+$lang['most_visited_cat'] = 'Meest bekeken';
+$lang['most_visited_cat_hint'] = 'Toon de meest bekenen afbeelding';
+$lang['nb_image_line_error'] = 'Het aantal beelden per rij moet niet ongeldige deler zijn';
+$lang['nb_image_per_row'] = 'Aantal afbeeldingen per rij';
+$lang['nb_line_page_error'] = 'Het aantal rijen per pagina mag geen ongeldige deling zijn';
+$lang['nb_row_per_page'] = 'Aantal rijen per pagina';
+$lang['nbm_unknown_identifier'] = 'Onbekend herkenningsteken';
+$lang['new_password'] = 'Nieuw wachtwoord';
+$lang['new_rate'] = 'Beoordeel deze afbeelding';
+$lang['next_page'] = 'Volgende';
+$lang['no_category'] = 'Home';
+$lang['no_rate'] = 'geen beoordeling';
+$lang['note_filter_day'] = 'Toont alleen elementen geplaatst in de laatste %s dag.';
+$lang['note_filter_days'] = 'Toont alleen elementen geplaatst in de laatste %s dagen.';
+$lang['password updated'] = 'wachtwoord bijgewerkt';
+$lang['periods_error'] = 'Recente periode moet een positieve waarde zijn';
+$lang['picture'] = 'afbeelding';
+$lang['picture_high'] = 'Klik op de afbeelding om het te bekijken in een groter formaat';
+$lang['picture_show_metadata'] = 'Toon bestands metadata';
+$lang['powered_by'] = 'Powered by';
+$lang['preferences'] = 'Voorkeuren';
+$lang['previous_page'] = 'Vorige';
+$lang['random_cat'] = 'Random afbeelding';
+$lang['random_cat_hint'] = 'toon een set van willekeurige afbeelding';
+$lang['recent_cats_cat'] = 'Recente categorieën';
+$lang['recent_cats_cat_hint'] = 'toon recentelijk bijgewerkte categorieën';
+$lang['recent_period'] = 'Recente periode';
+$lang['recent_pics_cat'] = 'Recente afbeelding';
+$lang['recent_pics_cat_hint'] = 'toon meest recente afbeelding';
+$lang['redirect_msg'] = 'doorsturen...';
+$lang['reg_err_login1'] = 'Vul uw gebruikersnaam in AUB.';
+$lang['reg_err_login2'] = 'gebruikersnaam mag niet eindigen met een spatie';
+$lang['reg_err_login3'] = 'gebruikersnaam mag niet beginnen met een spatie';
+$lang['reg_err_login5'] = 'deze gebruikersnaam is al in gebruik';
+$lang['reg_err_mail_address'] = 'mail adres moet zijn xxx@yyy.eee (voorbeeld : jack@altern.org)';
+$lang['reg_err_pass'] = 'vul uw wachtwoord nogmaals in';
+$lang['remember_me'] = 'Auto login';
+$lang['remove this tag'] = 'verwijder de tag van de lijst';
+$lang['representative'] = 'representatief';
+$lang['return to homepage'] = 'terug naar de homepage';
+$lang['search_author'] = 'Zoek naar auteur';
+$lang['search_categories'] = 'Zoeken in Categorieën';
+$lang['search_date'] = 'Zoeken op Datum';
+$lang['search_date_from'] = 'Datum';
+$lang['search_date_to'] = 'Eind-Datum';
+$lang['search_date_type'] = 'Datum type';
+$lang['search_keywords'] = 'Zoek naar hele woorden';
+$lang['search_mode_and'] = 'Zoeken naar alle woorden';
+$lang['search_mode_or'] = 'Zoeken naar een woord';
+$lang['search_one_clause_at_least'] = 'Lege zoekopdracht. Er is niets ingevuld.';
+$lang['search_options'] = 'Zoek Opties';
+$lang['search_result'] = 'Zoekresultaten';
+$lang['search_subcats_included'] = 'Zoeken in subcategorieën';
+$lang['search_title'] = 'Zoeken';
+$lang['searched words : %s'] = 'zoekwoorden : %s';
+$lang['send_mail'] = 'Contact';
+$lang['set as category representative'] = 'Stel in als standaard categorie';
+$lang['show_nb_comments'] = 'Toon aantal commentaren';
+$lang['show_nb_hits'] = 'Toon aantal bezoekers';
+$lang['slideshow'] = 'slideshow';
+$lang['slideshow_stop'] = 'stop de slideshow';
+$lang['special_categories'] = 'Speciaal';
+$lang['sql_queries_in'] = 'SQL queries in';
+$lang['start_filter_hint'] = 'toon alleen de recent geplaatste elementen';
+$lang['stop_filter_hint'] = 'terug naar het tonen van alles';
+$lang['the beginning'] = 'het begin';
+$lang['theme'] = 'thema';
+$lang['thumbnails'] = 'Thumbnails';
+$lang['title_menu'] = 'Menu';
+$lang['title_send_mail'] = 'commentaar op je site';
+$lang['today'] = 'vandaag';
+$lang['update_rate'] = 'Werk je beoordeling bij';
+$lang['update_wrong_dirname'] = 'verkeerde bestandsnaam';
+$lang['upload_advise_filesize'] = 'het bestandsformaat mag niet te groot zijn : ';
+$lang['upload_advise_filetype'] = 'de afbeelding moet een extensie hebbben die eindigt op jpg, gif of png';
+$lang['upload_advise_height'] = 'de hoogte van de afbeelding mag niet te groot zijn : ';
+$lang['upload_advise_thumbnail'] = 'Optioneel, maar aanbevolen : kies een thumbnail voor associatie';
+$lang['upload_advise_width'] = 'de breedte van de afbeelding mag niet te groot zijn : ';
+$lang['upload_author'] = 'Auteur';
+$lang['upload_cannot_upload'] = 'kan de afbeelding niet op de server plaatsen';
+$lang['upload_err_username'] = 'de gebruikersnaam moet ingevuld zijn';
+$lang['upload_file_exists'] = 'De naam is al in gebruik';
+$lang['upload_filenotfound'] = 'Je moet een afbeeldingsformaat opgeven voor de afbeelding';
+$lang['upload_forbidden'] = 'Je kan geen afbeelding plaatsen in deze categorie';
+$lang['upload_name'] = 'Naam van de afbeelding';
+$lang['upload_picture'] = 'Uploaden van een afbeelding';
+$lang['upload_successful'] = 'Afbeelding met succes ge-upload, een beheerder moet de afbeelding valideren, dit gebeurd zsm.';
+$lang['upload_title'] = 'Upload een afbeelding';
+$lang['useful when password forgotten'] = 'handig bij het vergeten van je wachtwoord';
+$lang['qsearch'] = 'Snel zoeken';
+$lang['Connected user: %s'] = 'Aangemeld als gebruiker: %s';
+$lang['IP: %s'] = 'IP: %s';
+$lang['Browser: %s'] = 'Browser: %s';
+$lang['Author: %s'] = 'Auteur: %s';
+$lang['Comment: %s'] = 'Commentaar: %s';
+$lang['Delete: %s'] = 'Verwijderen: %s';
+$lang['Validate: %s'] = 'Valideren: %s';
+$lang['Comment by %s'] = 'Commentaar van %s';
+$lang['User: %s'] = 'Gebruiker: %s';
+$lang['Email: %s'] = 'Email: %s';
+$lang['Admin: %s'] = 'Beheerder: %s';
+$lang['Registration of %s'] = 'Registratie van %s';
+$lang['Category: %s'] = 'Categorie: %s';
+$lang['Picture name: %s'] = 'Afbeeldings naam: %s';
+$lang['Creation date: %s'] = 'Aanmaak datum: %s';
+$lang['Waiting page: %s'] = 'Wacht pagina: %s';
+$lang['Picture uploaded by %s'] = 'Afbeelding ge-uploaded door %s';
+// --------- Starting below: New or revised $lang ---- from version 1.7.1
+$lang['guest_must_be_guest'] = 'Foutieve status voor gebruiker "guest", gebruik standaard status. Waarschuw de webmaster.';
+// --------- Starting below: New or revised $lang ---- from Butterfly (1.8)
+$lang['Administrator, webmaster and special user cannot use this method'] = 'Administrator, webmaster en speciale gebruiker kunnen deze methode niet gebruiken';
+$lang['reg_err_mail_address_dbl'] = 'Een andere gebruiker maakt al gebruik van dit email adres';
+$lang['Category results for'] = 'Categorie resultaten voor';
+$lang['Tag results for'] = 'Tag resultaten voor';
+$lang['from %s to %s'] = 'van %s tot %s';
+$lang['start_play'] = 'Start de slideshow';
+$lang['stop_play'] = 'Pauzeer de slideshow';
+$lang['start_repeat'] = 'Herstart de slideshow';
+$lang['stop_repeat'] = 'Herhaal de slideshow NIET';
+$lang['inc_period'] = 'Diaporama snelheid verminderen';
+$lang['dec_period'] = 'Diaporama snelheid versnellen';
+$lang['Submit'] = 'Bevestig';
+$lang['Yes'] = 'Ja';
+$lang['No'] = 'Nee';
+$lang['%d element']='%d afbeelding';
+$lang['%d elements']='%d afbeeldingen';
+$lang['%d element are also linked to current tags'] = '%d image are also linked to current tags';
+$lang['%d elements are also linked to current tags'] = '%d images are also linked to current tags';
+$lang['See elements linked to this tag only'] = 'Toon afbeelding gelinkt met deze tag';
+$lang['elements posted during the last %d days'] = 'afbeelding binnen de %d dagen';
+$lang['Choose an image'] = 'Kies een afbeelding om';
+$lang['Piwigo Help'] = 'Piwigo Help';
+
+?>
Index: /tags/2.0.2/language/nl_NL/help.html
===================================================================
--- /tags/2.0.2/language/nl_NL/help.html	(revision 3278)
+++ /tags/2.0.2/language/nl_NL/help.html	(revision 3278)
@@ -0,0 +1,320 @@
+<div class="instructions">
+<h2>Help</h2>
+
+<div id="instructionPLoader" class="instructionBlock">
+  <div
+    id="pLoader_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('pLoader_header', 'pLoader_content')"
+  ><span>
+    <!--TODO-->Add photos, the pLoader way
+  </span></div>
+  <div
+    id="pLoader_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+<!--TODO-->    <p><a href="http://piwigo.org/ext/extension_view.php?eid=270">pLoader for Windows</a> or <a href="http://piwigo.org/ext/extension_view.php?eid=269">pLoader for Linux</a> : description, download and details about new revisions.</p>
+    <ol>
+      <!--TODO--><li>Create a directory "upload" next to directory "galleries" in your Piwigo installation, with write access.</li>
+      <!--TODO--><li>Install pLoader on your computer, start it and fill the connection settings : your gallery URL, your username and password.</li>
+      <!--TODO--><li>Drag'n drop photos from your directory browser into pLoader photo selection.</li>
+      <!--TODO--><li>Create a category and select it.</li>
+      <!--TODO--><li>Select some photos.</li>
+      <!--TODO--><li>Click on the green arrow to transfer photos in your gallery</li>
+    </ol>
+<!--TODO-->Congratulations! You have successfuly created the first category of your photo gallery.
+  </div> <!-- pLoader_content -->
+</div> <!-- instructionPLoader -->
+
+<div id="instructionFTP" class="instructionBlock">
+  <div
+    id="FTP_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('FTP_header', 'FTP_content')"
+  ><span>
+    <!--TODO-->Add photos, the FTP way
+  </span></div>
+  <div
+    id="FTP_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+
+
+<h3>Snelle start</h3>
+
+<ol>
+  <!--TODO--><li>Create a directory on your computer.</li>  
+
+  <!--TODO--><li>Copy some photos inside this directory, resize them for web display. <em>Warning</em>: the name of directories and files must contain only letters, figures, "-", "_" or ".". No blank space, no accentuated characters.</li>
+
+  <!--TODO--><li>With a FTP client, copy your directory in the "galleries" directory of your Piwigo installation.</li>
+
+  <!--TODO--><li>Logon your gallery and go to <span class="pwgScreen">Administration &raquo; Pictures &raquo; Thumbnails</span> to create missing thumbnails.</li>
+
+  <!--TODO--><li>Go to <span class="pwgScreen">Administration</span> and click on the big Synchronization button.</li>
+</ol>
+
+<!--TODO-->Congratulations! You have successfuly created the first category of your photo gallery.
+
+<!--TODO--><h3>Directories and files organization</h3>
+
+<ul>
+
+  <li>
+
+    <p>Categorie mappen zijn in de Piwigo map "galleries". Bekijk de mapstructuur van een kleine gallerie (maar met een hoop mogelijkheden) :</p>
+
+    <pre>
+.
+|-- admin
+|-- doc
+|-- galleries
+|   |-- categorie-1
+|   |   |-- categorie-1.1
+|   |   |   |-- categorie-1.1.1
+|   |   |   |   |-- categorie-1.1.1.1
+|   |   |   |   |   |-- pwg_high
+|   |   |   |   |   |   +-- wedding.jpg
+|   |   |   |   |   |-- thumbnail
+|   |   |   |   |   |   +-- TN-wedding.jpg
+|   |   |   |   |   +-- wedding.jpg
+|   |   |   |   +-- categorie-1.1.1.2
+|   |   |   +-- categorie-1.1.2
+|   |   |-- categorie-1.2
+|   |   |   |-- pookie.jpg
+|   |   |   +-- thumbnail
+|   |   |       +-- TN-pookie.jpg
+|   |   +-- categorie-1.3
+|   +-- categorie-2
+|       |-- piglet.gif
+|       |-- pwg_representative
+|       |   +-- video.jpg
+|       |-- thumbnail
+|       |   +-- TN-piglet.jpg
+|       +-- video.avi
+|-- include
+|-- install
+|-- language
+|-- template
++-- tool</pre>
+
+  </li>
+  
+  <li>Eigenlijk, een categorie is gepresenteerd door een map op welke level in
+  Piwigo map "galleries". Elke categorie kan zoveel submappen als jij wilt bevatten.
+  In het voorbeeld hierboven, categorie-1.1.1.1 is op nivo 4 van de trap.</li>
+
+  <li>Eigenlijk, een element is gepresenteerd door een bestand. Een bestand kan een
+  Piwigo element zijn als de extenstie is <code>file_ext</code>
+  configuration parameter mofenlijkheden (zie <span
+  class="filename">include/config_default.inc.php</span> file). Een bestand kan
+  een afbeelding zijn als de extensie gelijk is aan <code>picture_ext</code>
+  configuration parameter possibilities.</li>
+
+  <li>Afbeeldings elementen moeten een link naar een thumbnail hebben.(zie sectie hieronder
+  over thumbnails)</li>
+
+  <li>Afbeeldings elementen kunnen gekoppeld zijn aan hoge kwaliteit bestanden. Zoals 
+  in het voorbeeld wedding.jpg hierboven. Er is geen andere naamsaanpassing nodig voor de
+   hoge kwaliteit afbeelding verplicht.
+  </li>
+
+  <li>Niet afbeeldings elementen (video, geluid, tekstbestanden, wat je wil...) worden 
+  standaard vertegenwoordigt door een ikoontje die overeenkomt met de bestandsextensie.
+   Optioneel, je kan zelf een associatie met een thumbnail en een bestand opgeven (zie video.avi in het voorbeeld hierboven).</li>
+
+  <li><em>Waarshuwing</em> : de naam van de mappen en bestanden moeten bestaan uit de letters en koppeltekens "-", "_" of ".". Geen spaties en geen accenten
+ op de karakters</li>
+
+  <li><em>Advies</em> : Een categorie kan elementen en sub-categorieën hebben
+op het zelfde moment. Desalnietemin, word je geadviseerd om te kiezen uit categorieën die elementen bevatten <strong>of</strong> categorieën
+die sub-categorieën bevatten.</li>
+
+  <li>Als bestanden, thumbnails en representativev corrct zijn geplaatst in
+ mappen ga dan naar: <span class="pwgScreen">Administratie &raquo; Categorieën &raquo; Synchronizeren</span></li>
+
+</ul>
+
+<h3>Thumbnails</h3>
+
+<ul>
+
+  <li>Zoals eerde gemeld, elk element of afbeeldingstype moet geassociateerd worden met een thumbnail.</li>
+
+  <li>Thumbnails worden opgeslagen in een sub-directory "thumbnail" of de categorie map. De thumbnail is een afbeelding (zelfde bestandsnaam extensies mogelijk
+  als de afbeeldingbestanden) welke is prefixed met een geconfigureerde
+  "Thumbnail prefix" (zie administratie paneel, Configuratie, Algemeen).</li>
+
+  <li>Thumbnails hoeven niet de zelfde extensie te hebben als het geassocieerde
+  afbeelding (een afbeelding met .jpg extensie kan een thumbnail hebben met .GIF
+  extentie als voorbeeld).</li>
+
+  <li>Advies: gebruik een ecterne module voor het maken van thumbnails.</li>
+
+  <li>Je kunt ook de pagina thumbnail maken gebruiken (<span
+  class="pwgScreen">Administratie, Afbeeldingen, Thumbnails</span>), maar dat word niet aangeraden.
+   De thumbnail kwaliteit kan slecht zijn en het gebruikt een hoge CPU kracht welke een probleem kan zijn bij gratis webhost.</li>
+
+  <li>Als je er voor kiest om de thumbnails te laten maken door de webhoster, dan dien je de rechten toe te wijzen op die mappen om de thumbnail te kunnen maken.
+  De correcte rechten op de mappen en sub-mappen zijn gebruiker/goep/wereld (ook wel 777)
+</li>
+
+</ul>
+
+
+  </div> <!-- FTP_content -->
+</div> <!-- instructionFTP -->
+
+<div id="instructionPermissions" class="instructionBlock">
+  <div
+    id="permissions_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('permissions_header', 'permissions_content')"
+  ><span>
+    <!--TODO-->Permissions
+  </span></div>
+  <div
+    id="permissions_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+
+<ul>
+
+  <!--TODO--><li>You can forbid access to categories. Switch the category access type to "private" if you want to manage permissions.</li>
+
+  <li>U kunt een categorie aan private maken door het aanpassen van een enkele categorie(<span
+  class="pwgScreen">Administratie &raquo; Categorieën &raquo; Beheren &raquo; bewerken</span>) of bij het aanpassen van de opties op de hele categorie map (<span
+  class="pwgScreen">Administratie &raquo; Categorieën &raquo; Eigenschappen &raquo; Publiek / Private</span>).</li>
+
+  <li>
+
+    <p>Als de categorie private is, dan kun je de rechten aanpassen voor de groepen en gebruikers via 3 schermen :</p>
+
+    <ul>
+
+      <li><span class="pwgScreen">Administratie &raquo; Identificatie &raquo; Gebruikers &raquo; rechten aanpassen (een link per gebruiker)</span></li>
+
+      <li><span class="pwgScreen">Administratie &raquo; Identificatie &raquo; Groepen &raquo; rechten aanpassen (een link per groep)</span></li>
+
+      <li><span class="pwgScreen">Administratie &raquo; Categorieën &raquo; Beheren &raquo; bewerk categorie rechten aanpassen (one link per categorie)</span></li>
+
+    </ul>
+
+  </li>
+
+</ul>
+  </div> <!-- permissions_content --> 
+</div> <!-- instructionPermissions -->
+
+<div id="instructionGroups" class="instructionBlock">
+  <div
+    id="groups_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('groups_header', 'groups_content')"
+  ><span>
+    Gebruikers en groepen
+  </span></div>
+  <div
+    id="groups_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+<ul>
+
+    <!--TODO--><li>Groups is a convenient way to set permissions for a list of users.</li>
+
+  <li>Je kan groepen maken in <span class="pwgScreen">Administratie &raquo; Identificatie &raquo; Groepen</span> en voeg gebruikers toe aan de groep via <span class="pwgScreen">Administratie, Identicatie, Gebruikers</span>.</li>
+
+  <li>Een gebruiker kan behoren tot verschillende groepen. De vergunning is sterker dan verbod : als gebruiker "jack" behoord tot de groep "familie" en "Vrienden", en alleen de groep "familie" kan de categorie "Christmas 2003" zien,
+  "jack" zal de mogelijkheid hebben om de categorie "Christmas 2003" te zien.</li>
+
+</ul>
+  </div> <!-- groups_content --> 
+</div> <!-- instructionGroups -->
+
+<div id="instructionUpload" class="instructionBlock">
+  <div
+    id="upload_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('upload_header', 'upload_content')"
+  ><span>
+    Bestands upload door gebruikers
+  </span></div>
+  <div
+    id="upload_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+<!--TODO--><p>Users can upload their photos too.</p>
+
+<ol>
+
+  <!--TODO--><li>Authorize upload on any physical categories (<span
+  class="pwgScreen">Administration &raquo; Categories &raquo; Manage &raquo; edit</span> or <span
+  class="pwgScreen">Administration &raquo; Categories &raquo; Properties &raquo; Upload</span>). Virtual categories can't receive any upload.</li>
+
+  <li>geef rechten op de mappen 777 (gebruiker, groepen, wereld)</li>
+
+</ol>
+
+<!--TODO--><p>Photos uploaded by users are not directly visible on the website. An administrator
+must validate uploaded photos in <span class="pwgScreen">Administration &raquo; Pictures &raquo; Waiting</span>.</p>
+  </div> <!-- upload_content --> 
+</div> <!-- instructionUpload -->
+
+<div id="instructionCategoryLinks" class="instructionBlock">
+  <div
+    id="categoryLinks_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('categoryLinks_header', 'categoryLinks_content')"
+  ><span>
+    Links tussen elementen en categorieën, virtuele categorieën
+  </span></div>
+  <div
+    id="categoryLinks_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+<ul>
+
+  <!--TODO--><li>Photos are displayed in the category corresponding to the file directory.</li>
+
+  <!--TODO--><li>You can also display a picture in several categories, without duplicating the file on your web server. Associate the photo to any category from the photo editing screen (that any administrator can reach from the photo page on the gallery side).</li>
+
+  <!--TODO--><li>Virtual categories are based on this concept: they have no corresponding directory. Create virtual categories from <span class="pwgScreen">Administration &raquo; Categories &raquo; Manage</span>.</li>
+
+</ul>
+  </div> <!-- categoryLinks_content --> 
+</div> <!-- instructionCategoryLinks -->
+
+<div id="instructionMisc" class="instructionBlock">
+  <div
+    id="misc_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('misc_header', 'misc_content')"
+  ><span>
+    Diverse informatie
+  </span></div>
+  <div
+    id="misc_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+
+<ul>
+
+  <li>Als je je gallery-installatie hebt afgerond, verander dan het uiterlijk van de standaard weergave 
+  in <span class="pwgScreen">Administratie paneel &raquo; Configuratie &raquo; 
+  Standaard</span>. Elke nieuwe geregistreerde gebruiker zal dezelfde standaard vertoningseigenschappen hebben.</li>
+
+   <!--TODO--><li>If you have any question, Piwigo community will welcome you on <a
+  href="http://piwigo.org/forum">its forum</a>.</li>
+
+</ul>
+  </div> <!-- misc_content --> 
+</div> <!-- instructionMisc -->
+
+</div>
Index: /tags/2.0.2/language/nl_NL/help/advanced_feature.html
===================================================================
--- /tags/2.0.2/language/nl_NL/help/advanced_feature.html	(revision 3278)
+++ /tags/2.0.2/language/nl_NL/help/advanced_feature.html	(revision 3278)
@@ -0,0 +1,16 @@
+<h2>Geavanceerde mogelijkheden</h2>
+
+<p>Lijst met speciale functies voor een deskundig PWG administrator:</p>
+
+<ul>
+
+  <li>
+    <strong>Niet gelinkte elementen:</strong>
+    Toon afbeeldingen die niet gekoppeld zijn aan enige virtuele categorie.
+  </li>
+  <li>
+    <strong>Bestanden met dezelfde naam in meer dan één physieke categorie:</strong>
+    Toon afbeeldingen of bestanden met dezelfde naam in verschillende categorieën.
+  </li>
+
+</ul>
Index: /tags/2.0.2/language/nl_NL/help/cat_modify.html
===================================================================
--- /tags/2.0.2/language/nl_NL/help/cat_modify.html	(revision 3278)
+++ /tags/2.0.2/language/nl_NL/help/cat_modify.html	(revision 3278)
@@ -0,0 +1,128 @@
+<h2>Een categorie bewerken</h2>
+
+<h3>Informatie</h3>
+
+<ul>
+
+  <li><strong>naam</strong>: hernoem de categorie (een virtuele hernoeming in het geval van een physieke categorie).</li>
+
+  <li><strong>omschrijving</strong>: geef informatie over de inhoud die getoond word in de categorie,
+  deze tekst word onder de thumbnail.</li>
+
+</ul>
+
+<h3>Verplaatsen</h3>
+
+<p>Als het een virtuele categorie is, dan kun je hem verplaatssen. Het verplaatsen van een categorie houd in dat je het ouderschap veranderd.</p>
+
+<h3>Opties</h3>
+
+<ul>
+
+  <li><strong>Toegangs type</strong>: Rechten beheren. Als je een 
+  categorie private maakt, worden alle daaronderliggende (kinder)categorieën worden dan ook private.<br>
+  Als je een categorie publiek maakt, worden alle ouder categorieën zullen dan ook publiek worden.</li>
+
+  <li><strong>Sluiten</strong>: De categorie en zijn sub-categorieë zijn
+  tijdelijk uitgeschakeld voor onderhoud.</li>
+
+  <li><strong>Commentaar</strong>: Machtig gebruikers om commentaar te geven op de elementen in deze categorie.</li>
+
+  <li><strong>Machtiging tot upload</strong>: Machtig gebruikers om bestanden te-uploaden. Deze optie is alleen beschikbaar als de categorie physiek is (niet
+  virtueel).</li>
+
+</ul>
+
+<p>Je kan de opties ook beheren via "Eigenschappen" beheer schermen (scherm <span class="pwgScreen">Upload</span>, <span
+class="pwgScreen">Commentaar</span>, <span class="pwgScreen">Sluiten</span>,
+<span class="pwgScreen">Publiek/Private</span>, <span
+class="pwgScreen">Vertegewoordiging</span> beschikbaar via <span
+class="pwgScreen">Administratie, Categorieën, Eigenschappen</span>).</p>
+
+<h3>Sorteer volgorde</h3>
+
+<p>Kies als de standaard sortering word gebruikt.</p>
+
+<p>Indicatie dat de sortering wort toegepast op de sub-categorieën.</p>
+
+<p>Gebruik specifieke sorteren middels de kolommen in deze categorie.</p>
+<ul>
+<li><strong>Aanmaak datum</strong>: Aanmaak datum foto</li>
+<li><strong>Plaatings datum</strong>: Synchronizatie datum</li>
+<li><strong>Gemiddelde waardering(*)</strong>: Gemiddelde waardering kan gewijzigt worden door een bezoeker</li>
+<li><strong>Most visited (*)</strong>: The current visit change the most visited order</li>
+<li><strong>Bestandsnaam</strong>: Gekozen naam in het informatie veld</li>
+<li><strong>Id</strong>: Interne Id (recente categorieën hoger id dan vorige id's.</li>
+
+</ul>
+<p><strong>(*)</strong>Neem zorg en test het voor uw zelf aangezien het onvoorspelbare resultaten kan geven.</p>
+
+
+<h3>Vertegenwoordiging</h3>
+
+<p>De vertegenwoordiging van de categorie is een indexplaatje "thumbnail" welke getoond word
+om de categorie te tonen op de hoofdpagina (<span class="pwgScreen">category.php</span>) wanneer een
+categorie alleen sub-categorieieën bevat (alleen als root categorie).</p>
+
+<p>Er zijn 4 manieren om een indexplaatje te tonen als weergavevan een categoie :</p>
+
+<ul>
+
+  <li><span class="pwgScreen">Picture page</span>: in het aktiemenu, 
+  met een van de knoppen is het mogelijk om een plaatje te kiezen als
+  vertegenwoordiging van een categorie. Deze knop is alleen beschikbaar voor administrators.</li>
+
+  <li><span class="pwgScreen">Verander informatie over een plaatje</span> via de administratie.
+  Je kunt bij dit scherm komen via <span class="pwgScreen">picture.php</span> of 
+  <span class="pwgScreen">Batch management</span> in <em>unit mode</em>. Kijk voor meer info in de documentatie voor meer details.</li>
+
+  <li><span class="pwgScreen">Administratie, Categorieën, Eigenschappen, Thumbnails</span>. Kijk voor meer info in de documentatie voor meer details.</li>
+
+  <li><span class="pwgScreen">Bewerk een categorie</span> (dit scherm).</li>
+
+</ul>
+
+<p>De indexafbeelding is afhankelijk van de configuratie parameter <code>allow_random_representative</code> (zie <span
+class="filename">include/config_default.inc.php</span>).</p>
+
+<p>Standaard is <code>allow_random_representative</code> ingesteld op false (onwaar)
+elke categorie die tenminste 1 element bevat is vertegenwoordigd door een vastgestelde afbeelding. 
+Eenmaal ingesteld (Bij het maken van de categorie), kan deze alleen veranderd worden door administrator 
+ die daar dan om verzoekt it. Als de indexafbeelding niet meer bestaat kun je er <strong>willekeurig</strong> een nieuwe aan toewijzen.</p>
+
+<p>Als de configuratie parameter <code>allow_random_representative</code> is
+ingesteld op true (waar), dan is eer geen vaste indexafbeelding. Gebruik gewoon <strong>Verwijder indexafbeelding</strong> knop.</p>
+
+<p>Als de categorie geen elementen bevat (maar alleen sub-categorieën) kan het 
+vertegenwoordigt worden dankzij het scherm <span class="pwgScreen">verander informatie over een afbeelding</span>. De enigste optie 
+op het huidige scherm is <strong>Verwijder vertegenwoordigingsafbeelding</strong> knop, na deze optie te hebben gebruikt is er geen 
+afbeeldingsafbeeldings optie meer om te veranderen.</p>
+
+<h3>Link alle categorie elementen aan een nieuwe categorie</h3>
+
+<ul>
+
+<li><strong>Virtuele categorie naam</strong>: Nieuwe categorie naam aanmaaken, 
+alle afbeeldingen van de huidige categorie zullen gekoppeld worden aan de nieuwecategorie.</li>
+
+<li><strong>Ouder categorie</strong>: Waar de nieuwe moet komen, laat dit leeg om deze in de root te maken.</li>
+
+</ul>
+
+<h3>Link alle categorie elementen aan bestaande categorieën</h3>
+
+<ul>
+
+<li><strong>Categorieën</strong>: Kies de doelcategorie.</li>
+
+</ul>
+
+<h3>Stuur een informatie email naar de groepsleden</h3>
+
+<ul>
+
+<li><strong>Groep</strong>: Geadresseerden groep</li>
+
+<li><strong>Email inhoud</strong>: Vrije tekst om mee te sturen.</li>
+
+</ul>  
Index: /tags/2.0.2/language/nl_NL/help/cat_move.html
===================================================================
--- /tags/2.0.2/language/nl_NL/help/cat_move.html	(revision 3278)
+++ /tags/2.0.2/language/nl_NL/help/cat_move.html	(revision 3278)
@@ -0,0 +1,15 @@
+<h2>Verplaatsen virtuele categorieën</h2>
+
+<p>Allen virtuele categorieën kunnen een nieuwe ouder-categorie hebben.</p>
+
+<h3>Virtuele categorieën verplaatsen</h3>
+
+<p>Selecteer een virtuele categorie die je wilt verplaatsen.
+Als de lijst leeg is, wil dat zeggen dat je er geen gemaakt hebt.</p>
+
+<h3>Nieuwe ouder categorie</h3>
+
+<p>Selecteer de nieuwe ouder (virtueel of physiek). 
+Als je het niet doet zullen de geselecteerde categorieën verplaatst worden 
+naar het begin van de map (root). Categorieën kunnen niet verplaatst worden
+naar zichzelf of een kind van de categorie.</p>
Index: /tags/2.0.2/language/nl_NL/help/cat_options.html
===================================================================
--- /tags/2.0.2/language/nl_NL/help/cat_options.html	(revision 3278)
+++ /tags/2.0.2/language/nl_NL/help/cat_options.html	(revision 3278)
@@ -0,0 +1,30 @@
+<h2>Categorie opties</h2>
+
+<p>Dit scherm geeft administrators de mogelijkheid om categorie opties te beheren voor meerde categorieën in één keer.</p>
+
+<dl>
+
+  <dt>Upload</dt>
+  <dd>Maak categorieën benaderbaar voor bezoekers om er bestanden in te plaatsen. Alleen niet virtuele en externe categorieën worden getoond.</dd>
+
+  <dt>Commentaar</dt>
+  <dd>Geef gebruikers rechten om commentaar te plaatsen in de geselecteerde categorieën.
+	Selecteer de categorie waarop commentaar gegeven kan worden.
+	Op een afbeelding kan alleen commentaar gegeven worden als deze behoord tot een categorie waar dit is toegestaan.</dd>
+
+  <dt>sluiten</dt>
+  <dd>Geselecteerde categorieën zijn op dit moment gesloten voor onderhoud. 
+	Als je een categorie sluit, alle daaronder liggende categorieën zijn dan ook gesloten. Als je een categorie 
+	weer opent, alle ouder categorieën worden dan ook weer geopend.</dd>
+
+  <dt>Publiek / private</dt>
+  <dd>Beheer rechten voor de geselecteerde categorieën. Geselecteerde categorieën zijn private : je moet gebruikers/groepen rechten geven op deze categorieën.
+	 Als je een categorie private maakt, alle daaronderliggende categorieën worden dan ook private. 
+	Als je eeen categorie publiek maakt, alle ouder categorieën worden dan ook publiek</dd>
+
+  <dt>Vertegenwoordiging</dt>
+  <dd>Deze opties kunnen alleen beheerd worden als de configuratie parameter <code>allow_random_representative</code>
+	 is ingesteld op <em>true</em>.(zie <span class="filename">include/config_defaults.inc.php</span>)
+	Elke categorie kan vertegenwoordigd worden door een willekeurige of afzonderlijke vertegenwoordiging (door een unieke afbeelding).</dd>
+
+</dl>
Index: /tags/2.0.2/language/nl_NL/help/cat_perm.html
===================================================================
--- /tags/2.0.2/language/nl_NL/help/cat_perm.html	(revision 3278)
+++ /tags/2.0.2/language/nl_NL/help/cat_perm.html	(revision 3278)
@@ -0,0 +1,14 @@
+<h2>Beheer rechten voor een categorie</h2>
+
+<p>Dit scherm is allen beschikbaar voor private categorën. Hier kun je gebruikers en groepn toegang geven voor deze categorie.</p>
+
+<h3>Groepen</h3>
+
+<p>Je kan groepen toegang geven of toegang weigeren op de huidige categorie. Door het aanpassen van de groepsrechten kun je dat
+<br>bereiken. Je zal de lijst met gebruikers die toegang hebben tot deze categorie moeten wijzigen
+op basis van groepsrechten.</p>
+
+<h3>Gebruikers</h3>
+
+<p>Je kan een individuele gebruiker toegang geven of weigeren.
+Gebruikers die behoren tot een groep kunnen ook toegang gegeven of geweigerd worden.</p>
Index: /tags/2.0.2/language/nl_NL/help/configuration.html
===================================================================
--- /tags/2.0.2/language/nl_NL/help/configuration.html	(revision 3278)
+++ /tags/2.0.2/language/nl_NL/help/configuration.html	(revision 3278)
@@ -0,0 +1,106 @@
+<h2>Configuratie</h2>
+
+<p>Dit scherm geeft de administrator de mogenlijkheid tot basisconfiguratie. Dit scherm toont namelijk slechts eenvoudige 
+configuratieparameters die zouden moeten zijn genoeg voor de overgrote meerderheid van beheerders. Als je de andere mogelijkheden wilt zien
+(geavanceerde) over de configuratie parameters, lees dan <span class="filename">include/config_default.inc.php</span>.</p>
+
+<p>Dit scherm wordt verdeeld in verscheidene secties, hergroeperend configuratieparameters per thema.</p>
+
+
+<h3>Begin</h3>
+<ul>
+  <li><strong>Gallerie titel</strong>: word gebruikt in RSS meldingen en meldingen per email.</li>
+
+  <li><strong>Pagina banner</strong>: word getoond op elke publieke pagina.</li>
+
+  <li><strong>Gallerie URL</strong>: word gebruikt voor de RSS meldingen.</li>
+
+  <li><strong>Sluit gallery</strong>: Sluit de hele gallerie voor onderhoud. Alleen administrators kunnen de gallerie nog bereiken.</li>
+
+  <li><strong>Waardering</strong>: Waarderings optie is ingeschakeld.</li>
+
+  <li><strong>Waardering door gasten</strong>: Niet geregisteerde gebruikers kunnen ook hun waardering geven aan afbeeldingen.</li>
+
+  <li><strong>Sta registratie toe</strong>: Registratie is gratis voor iedereen.</li>
+
+  <li><strong>Email adres is verplicht voor alle gebruikers</strong>: Email adres word gecontroleerd bij registratie of profiel update uitgezonderd als de actie word uitgevoerd op de administratie scherm.</li>
+
+  <li><strong>Email admins wanneer een nieuwe gebruiker zich registreerd</strong>: Administrators ontvangen een mailtje bij elke registratie.</li>
+
+</ul>
+
+<h3>Geschiedenis</h3>
+
+  <p>Bezoek op de pagina's <span class="pwgScreen">category.php</span> en <span class="pwgScreen">picture.php</span> worden opgeslagen in de <code>history</code> tabel.</p>
+  
+  <p>Bezoek word getoond in <span class="pwgScreen">Administratie, Speciaal, Geschiedenis</span>.</p>
+
+<ul>
+  <li><strong>Bewaar pagina bezoek door gasten</strong>: pagina bezoek van gasten wordt opgeslagen.</li>
+
+  <li><strong>Bewaar pagina bezoek door gebruikers</strong>: pagina bezoek van geregistreerde gebruikers wordt opgeslagen.</li>
+
+  <li><strong>Bewaar pagina bezoek door administrators</strong>: pagina bezoek van administrators wordt opgeslagen.</li>
+
+</ul>
+
+<h3>Commentaar</h3>
+<ul>
+
+  <li><strong>Commentaar door iedereen</strong>: Ook gasten kunnen commentaar plaatsen.</li>
+
+  <li><strong>Aantal commentaren per per pagina</strong>.</li>
+
+  <li><strong>Validatie</strong>: een administrator valideerd de door gebruikers geplaatste commentaren voordat deze zichtbaar wordt op de website.
+   Valideren van gebruikers commentaar gebeurd via het scherm <span class="pwgScreen">Administratie, Afbeeldingen, Commentaar</span>.</li>
+
+  <li><strong>Email admins when a valid comment is entered</strong>:
+Sends an email to the administrators when a user enters a comment and this comment is validated.</li>
+
+  <li><strong>Email admins wanneer een commentaar validatie nodig heeft</strong>:
+Stuurt de administrator een bericht dat een gebruiker een p[merking heeft geplaatst die nog gevalideerd moet worden door de administrator.
+Gebruikers commentaar valideren gaat via het scherm <span class="pwgScreen">Administratie, Afbeeldingen, Commentaren</span>.</li>
+
+</ul>
+
+<!--TODO --><h3>Upload</h3>
+<ul>
+<!--TODO -->  <li><strong>Show upload link every time</strong>: If exists uploadeable categories, add link will be show for each categoy.</li>
+<!--TODO -->  <li><strong>User access level to upload</strong>: Allows to restrict upload by users</li>
+  <li><strong>Email admins wanneer een afbeelding is ge-upload</strong>: Administrators ontvangen een mailtje voor elke ge-uploade bestand door gebruikers.</li>
+</ul>
+
+<h3>Standaard weergave</h3>
+
+<p>Hier kan je de weergave aan passen die als standaard worden ingesteld, die je gast ziet als hij zich niet heeft aangemeld. Eenmaal aangemeld worden deze 
+opties overschreven door de gebruikers eigen opties (aanpasbaar in <span class="pwgScreen">profiel</span>).</p>
+
+<p>Het is mogelijk om de weergave opties voor alle gebruikers aan te passen, via scherm <span class="pwgScreen">Administratie, Identificatie, Gebruikers</span>, waar de opties voor de geslecteerde lijst van gebruikers word getoond.</p>
+
+<ul>
+
+  <li><strong>Talen</strong>: betreft slechts Piwigo labels. De namen van de categorie, de bestandsnamen en alle beschrijvingen vallen hier buiten.</li>
+
+  <li><strong>Aantal afbeeldingen per rij</strong></li>
+
+  <li><strongAantal afbeeldingen per pagina</strong></li>
+
+  <li><strong>aangezichts thema</strong></li>
+
+  <li><strong>Recente periode</strong>: per dag. Periode waarin de foto aangeduid moet worden als nieuw. Moet meer dan 1 dag zijn.</li>
+
+  <li><strong>Toon alle categorieën</strong>: Toon standaard alle categorieën in het menu? <em>Warning</em>: deze optie is een server belastende optie 
+en toont mogelijk een erg groot menu als je categorie erg veel sub categorieën bevat.</li>
+
+  <li><strong>Aantal commentaren tonen</strong>: Het aantal commentaren zichtbaar bij een afbeelding op de thumbnails pagina. Zware belasting.</li>
+
+  <li><strong>Toon aantal hits</strong>: Toon het aantal keren dat een afbeelding bekeken is, onder de afbeelding op de thumbnails pagina. 
+  Allen mogelijk als de geavanceerde configuratie parameter is: <br />  $conf['show_nb_hits'] = true; <br />
+  Opmerking: standaars is dit false.</li>
+
+  <li><strong>Maximale breedte van de afbeeldingen</strong>: maximale toonbare breedte. Als de afbeeldingen groter zijn dan deze instelling, worden ze verkleind op het scherm.  Als je deze optie gebruikt, denk er dan over na om de afbeelding aan te passen voor je ze plaatst op je gallery.</li>
+
+  <li><strong>Maximale hoogte van de afbeeldingen</strong>: Zelfde als hierboven.</li>
+
+</ul>
+
Index: /tags/2.0.2/language/nl_NL/help/extend_for_templates.html
===================================================================
--- /tags/2.0.2/language/nl_NL/help/extend_for_templates.html	(revision 3278)
+++ /tags/2.0.2/language/nl_NL/help/extend_for_templates.html	(revision 3278)
@@ -0,0 +1,100 @@
+<h2>Extend for templates configuration</h2>
+
+<h3>Goal</h3>
+<p>Define replacement conditions for each template from template-extension
+(template called "replacer").</p>
+
+<p>"original template" from ./template/yoga (or any other than yoga)
+ will be replaced by a "replacer" if the replacer is linked to this "original template"
+ (and optionally, when the requested URL contains an "optional URL keyword").</p>
+
+<p>"Optional URL keywords" are those you can find after the module name in URLs.</p>
+
+<p>Therefore "Optional URL keywords" can be an active "permalink" 
+(see permalinks in our documentation for further explanation).</p>
+
+<p>Read: `<a href="#warnings">Warning</a>` usage conditions.</p>
+
+<h3>What are template extensions?</h3>
+
+<p>This configuration tool is powerfull for beginners and advanced users.
+By FTP, in the template-extension folder, the Webmaster can duplicate a lot of
+ the distributed .tpl files ("original template") with a different name 
+ ("replacer").
+ 
+ "Original templates", current original supported templates are:</p>
+<ul>
+  <li><span class="filename">index.tpl</span></li>
+  <li><span class="filename">mainpage_categories.tpl</span> and/or <span class="filename">thumbnails.tpl</span></li>
+  <li><span class="filename">menubar.tpl</span></li>
+  <li><span class="filename">header.tpl</span> and/or <span class="filename">footer.tpl</span></li>
+  <li><span class="filename">picture_content.tpl</span> and/or <span class="filename">picture.tpl</span></li>
+  <!-- <li><span class="filename">slideshow.tpl</span></li> -->
+  <li><span class="filename">profile.tpl</span> and/or <span class="filename">profile_content.tpl</span></li>
+  <li><span class="filename">tags.tpl</span></li>
+  <li><span class="filename">upload.tpl</span></li>
+  <li><span class="filename">about.tpl</span></li>
+  <li><span class="filename">popuphelp.tpl</span></li>
+  <li><span class="filename">search.tpl</span> and/or <span class="filename">search_rules.tpl</span></li>
+  <li><span class="filename">nbm.tpl</span> and/or <span class="filename">notification.tpl</span></li>
+  <li><span class="filename">identification.tpl</span> and/or <span class="filename">register.tpl</span></li>
+  <li><span class="filename">redirect.tpl</span></li>
+</ul>
+
+<h3>Where can I find "original templates"?</h3>
+
+<p>Distributed original templates are in template/yoga/ 
+(don't edit them in place for upgrade perspectives). So with "original templates", 
+any webmaster can create his "replacers (customized templates)".</p>
+
+<h3>Where should I save "replacers"?</h3>
+
+<p><strong>Replacers (customized templates)</strong> must be placed in the 
+template-extension folder (or its subfolders).
+Replacers can have any filename with the .tpl extension. For example: <span
+class="filename">template-extension/my-extension/video.tpl</span>.</p>
+
+
+<h3>How can I activate my "replacers"?</h3>
+<p>An <strong>original template</strong> should be assigned to each
+ <strong>replacer (customized templates)</strong> to activate the related replacements.
+ This is the goal of "Extend for templates" in the Configuration Administration menu.</p>
+
+<p>If you select an <strong>optional URL keyword</strong> then replacements 
+will be operate only on pages with this keyword. For example: <span
+  class="pwgScreen">index.php?/<strong>most_visited</strong></span></p>
+  
+<p>Advanced users will use permalinks as <strong>optional URL keyword</strong>. </p>
+
+<p>If you select a <strong>Bound template</strong> then replacements will be operate only on this template.</p>
+
+<h3>How can I deactivate my "replacers"?</h3>
+<ul>
+<li>Unselect related "Original templates".</li>
+<li>By FTP delete of "replacers".</li>
+</ul>
+<a name="warnings"></a>
+<h3>Warnings</h3>
+<ul>
+
+  <li><strong>Original template</strong> must be the "original" template 
+  otherwise you could have unpredictable results!</li>
+
+  <li>On several <strong>replacers (customized templates)</strong> with the
+  same<strong>Original template</strong> and the same <strong>optional URL 
+  keyword</strong> only the last replacer is active.</li>
+
+  <li>Unselected <strong>optional URL keyword</strong> will active the replacer
+  on any template usage. As previous point, order can override previous
+  selected replacers.</li>
+
+  <li>Subfolders:
+Subfolders are ignored but they are usefull to change current order.<br />
+distributed-samples: for test purpose are distributed! 
+<strong>Don't edit them</strong> create your own ones.
+</li>
+
+  <li>On delete of a replacer the <strong>Original template</strong> is 
+  immediately reactivated.</li>
+
+</ul>
Index: /tags/2.0.2/language/nl_NL/help/group_list.html
===================================================================
--- /tags/2.0.2/language/nl_NL/help/group_list.html	(revision 3278)
+++ /tags/2.0.2/language/nl_NL/help/group_list.html	(revision 3278)
@@ -0,0 +1,22 @@
+<h2>Groepen lijst</h2>
+
+<p>Hier kan je de gedefinieerde groepen beheren.</p>
+
+<h3>Voeg een groep toe</h3>
+
+<p>Een administrator kan groepen toevoegen.</p>
+
+<h3>Groeps lijst</h3>
+
+<p>De lijst staat voor elk element toe:</p>
+
+
+<ul>
+  <li>naar de ledenlijst gaan</li>
+  <li>naar rechten gaan</li>
+  <li>een groep verwijderen (vereist een bevestiging)</li>
+  <li>stel de staus in als "standaard" (vereist een bevestiging)</li>
+</ul>
+
+<h3>Standaard groepen</h3>
+<p>Standaard groepen zijn groepen waar nieuwe gebruikers automatisch lid van worden.</p>
Index: /tags/2.0.2/language/nl_NL/help/index.php
===================================================================
--- /tags/2.0.2/language/nl_NL/help/index.php	(revision 3278)
+++ /tags/2.0.2/language/nl_NL/help/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/language/nl_NL/help/maintenance.html
===================================================================
--- /tags/2.0.2/language/nl_NL/help/maintenance.html	(revision 3278)
+++ /tags/2.0.2/language/nl_NL/help/maintenance.html	(revision 3278)
@@ -0,0 +1,37 @@
+<h2>Onderhoud</h2>
+
+<p>Om de pagina genereringstijd te optimaliseren, gebruikt Piwigo gecachde informatie. Voorbeeld, 
+inplaats van in plaats van het tellen van het aantal beelden, bevat elke categorie bij paginaherladen, 
+wordt deze informatie opgeslagen inde database. In theorie, zou deze informatie altijd correct zijn, 
+maar soms kan een fout optreden en de cache informatie is dan foutief.</p>
+
+<p>Bepaalde informatie word door tijd nutteloos. Door de nutteloze informatie te verwijderen uit de database bespaar je ruimte.</p>
+
+<ul>
+
+  <li><strong>Update categorie informatie:</strong> Voor elke categorie,
+  informatie bijwerken of controleren zijn de volgende: lijst van hooft
+  categorieën, aantal afbeeldingen, datum van de laatste afbeelding, positie onder 
+  broeder categorieën, positie onder alle categorieën. Deze aktie controleerd ook de koppeling met de indexafbeelding.</li>
+
+  <li><strong>Update afbeeldings informatie:</strong> Voor elke afbeelding,
+  informatie om te updaten zijn : volledige adres naar het bestand, gemiddelde waardering. 
+  <em>Waarschuwing</em>: raak niet in verwarring met de metadata informatie, welke gesynchroniseerd word via <span class="pwgScreen">Administratie,
+  Categorieën, Synchronizeren</span> of doormiddel van wijzigen enkele afbeelding (via <span class="pwgScreen">Afbeelding</span> voorbeeld).</li>
+
+  <li><strong>Repareren en optimalizeren database:</strong>
+  Voor elke tabel, re-odrer, reparatie en optimalizatie worden voltooid.
+  </li>
+</ul>
+
+<ul>
+  <li><strong>Filter geschiedenis:</strong> Verwijder alle <code>geschiedenis</code>uit de tabel. Scherm <span class="pwgScreen">Administratie,
+  Speciaal, Geschiedenis</span> toont geen informatie meer uit de verleden tijd. <em>Waarschuwing</em>: alle data wordt verwijderd en is niet meer te herstellen.</li>
+
+  <li><strong>Filter samenvatting:</strong> Verwijder alle informatie over het bezoek aan de website. Deze samenvatting is samengesteld uit de geschiedenis informatie.</li>
+
+  <li><strong>Filter sessies:</strong> Verwijder verlopen gebruikers sessies.</li>
+
+  <li><strong>Filter nooit gebruikte meldingen</strong></li>
+
+</ul>
Index: /tags/2.0.2/language/nl_NL/help/notification_by_mail.html
===================================================================
--- /tags/2.0.2/language/nl_NL/help/notification_by_mail.html	(revision 3278)
+++ /tags/2.0.2/language/nl_NL/help/notification_by_mail.html	(revision 3278)
@@ -0,0 +1,15 @@
+<h2>Meldingen per email</h2>
+
+<p>Dit scherm geeft je de mogelijkheid om emailmeldingen te configureren en te beheren om je gebruikers op de hoogte te stellen van nieuws op je website.</p>
+
+<p>Dit scherm is verdeelt in 3 delen:</p>
+
+<h3>Parameters</h3>
+<p>Alleen beschikbaar voor webmasters, dit deel configureerd de meldingen per email.</p>
+
+<h3>Inschrijven</h3>
+<p>Alleen beschikbaar voor webmasters, dit deel beheerd de in/uitschrijvingen voor email meldingen.</p>
+
+<h3>Verzending</h3>
+<p>Alleen beschikbaar voor webmasters en administrators, dit deel staat het toe om email meldingen te verzenden.</p>
+
Index: /tags/2.0.2/language/nl_NL/help/permalinks.html
===================================================================
--- /tags/2.0.2/language/nl_NL/help/permalinks.html	(revision 3278)
+++ /tags/2.0.2/language/nl_NL/help/permalinks.html	(revision 3278)
@@ -0,0 +1,7 @@
+<h2>Permanente links</h2>
+
+<p>Permanente links worden gebruikt om de adressen naar de categorie mooier te maken. wanneer een categorie een bepaalde permanente link heeft, wordt categorienaam niet meer vereist in de link ernaar toe.</p>
+
+<p>Wanneer een permanente link wordt verwijderd heb je de mogelijkheid om de geschiedenis te bewaren omde externe links naar de gallery werkend te houden. In de tabel met de permanente link geschiedenis kun je zien wanneer een permanente link is verwijderd, alsmede de laatste keer dat hij is gebruikt en het aantal keer.<p>
+
+<p>Let op: De permanente link naar een categorie moet uniek zijn. In de geschiedenis kan ook maar één keer dezelfde permanente link bestaan.</p>
Index: /tags/2.0.2/language/nl_NL/help/search.html
===================================================================
--- /tags/2.0.2/language/nl_NL/help/search.html	(revision 3278)
+++ /tags/2.0.2/language/nl_NL/help/search.html	(revision 3278)
@@ -0,0 +1,19 @@
+<h2>Zoeken</h2>
+
+<p>Via deze pagina kun je afbeeldingen zoeken in de totale gallerie.</p>
+
+<dl>
+
+  <dt>Zoeken naar woorden</dt>
+  <dd>Zoek naar opgegeven woorden in alle eigenschappen die betrekking heeft op de afbeelding die in de gallerie word getoond. Gebruik * als vervanging voor gedeeltelijke overeenkomsten.</dd>
+
+  <dt>Zoeken naar Auteur</dt>
+  <dd>Gebruik * als vervanging voor gedeeltelijke overeenkomsten.</dd>
+
+  <dt>Zoeken op datum</dt>
+  <dd>Selecteer een datum en/of een eind datum voor je zoekopdracht. Laat de datum leeg als je zoekt op een datum voor vandaag. Het jaartal moet zijn in het formaat : 0000 (2004)</dd>
+
+  <dt>Zoeken in Categorieën</dt>
+  <dd>Selecteer de categorie of categorieën waarin je wil zoeken. Voor snelheid kunnen alle subcategorieën worden doorzocht door de ouder te selecteren, en dan kun je kiezen om de subcategorieën te doorzoeken doormiddel van het aanvinken van die optie.</dd>
+
+</dl>
Index: /tags/2.0.2/language/nl_NL/help/site_manager.html
===================================================================
--- /tags/2.0.2/language/nl_NL/help/site_manager.html	(revision 3278)
+++ /tags/2.0.2/language/nl_NL/help/site_manager.html	(revision 3278)
@@ -0,0 +1,36 @@
+<h2>Externe sites</h2>
+
+<p>Piwigo biedt de mogelijkheid om verscheidene servers te gebruiken om de afbeeldingen op te slaan die uw gallerie zullen samenstellen.
+ Het kan nuttig zijn als uw gallerie beperkte ruimte is op de server, en dat u een grote hoeveelheid beelden aan hebt wordt getoond.<p>
+
+<ol>
+
+  <li>bewerk bestand <span class="filename">beheer/create_listing_file.php</span>,
+  door het veranderen van de parameters opties zoals <code>$conf['prefix_thumbnail']</code> of
+  <code>$conf['use_exif']</code>.</li>
+
+  <li>plaats het aangepaste bestand <span class="filename">beheer/create_listing_file.php</span>
+  op de andere server, in dezelfde map als je huidige categorie mappen  (als de map <span class="filename">galleries</span> op
+  deze website) via ftp. Voorbeeld, je hebt toegang tot <span class="filename">http://example.com/galleries/create_listing_file.php</span>.</li>
+
+  <li>ga naar <span class="pwgScreen">administratie paneel, Categorieën, Site manager</span>. maak een nieuwe site aan, voorbeeld <span class="filename">http://example.com/galleries</span>.</li>
+
+  <li>een nieuwe externe site is geregistreerd. Je hebt nu 4 mogelijkheden :
+
+    <ol>
+
+      <li><strong>genereer een lijst</strong> : stuurd verzoek om een externe lijst te maken.</li>
+
+      <li><strong>synchronizeer</strong> : leest de externe <span class="filename">listing.xml</span> bestand en synchronizeerd deze met de database informatie.</li>
+
+      <li><strong>opschonen</strong> : verwijderd externe <span class="filename">listing.xml</span> bestandem.</li>
+
+      <li><strong>verwijderen</strong> : verwijderd de site (en alle gerelateerde categorieën en elementen) in de database.</li>
+
+    </ol>
+  </li>
+</ol>
+
+<!-- <p>Je kan ook handmatig deze <span class="filename">listing.xml</span> genereren, door dit bestand te kopieëren vanaf de externe server en te plaatsen in je huidige 
+Piwigo root map en dan het beheersscherm  te openen : Piwigo zal voorstellen om de gevonden listing.xml te gebruiken.</p>-->
+
Index: /tags/2.0.2/language/nl_NL/help/synchronize.html
===================================================================
--- /tags/2.0.2/language/nl_NL/help/synchronize.html	(revision 3278)
+++ /tags/2.0.2/language/nl_NL/help/synchronize.html	(revision 3278)
@@ -0,0 +1,8 @@
+<h2>Synchronizeren</h2>
+
+<p>Er zijn 2 synchronizaties mogelijk : mappen/bestanden en bestands metadata. mapppen/bestanden gaat over het synchronizeren van je mapstructuur met de categorie structuur in de database.
+ metadata gaat over het bijwerken van de informatie zoals bestandsgrootte, dimenties in pixels en EXIF of IPTC informatie.</p>
+
+<p>De eerste synchronizatie moet zijn mappen/bestanden.</p>
+
+<p>Het synchronizatiren kan een lange tijd duren (afhankelijk van de server belasting en het aantal bestanden) daarom is het mogelijk om de categorieën één voor één te doen. (categorie voor categorie)</p>
Index: /tags/2.0.2/language/nl_NL/help/thumbnail.html
===================================================================
--- /tags/2.0.2/language/nl_NL/help/thumbnail.html	(revision 3278)
+++ /tags/2.0.2/language/nl_NL/help/thumbnail.html	(revision 3278)
@@ -0,0 +1,25 @@
+<h2>Thumbnails maken</h2>
+
+<p>Deze pagina geeft je de mogelijkheid om ontbrekende thumbnails aan te maken.</p>
+
+<dl>
+
+  <dt>GD versie</dt>
+
+  <dd>GD is een afbeeldings m,anipulatie software voor bebruik in PHP. Kies de versie van GD welke op deze server is geinstalleerd. Als je de verkeerde kiest, kun je foutberichten
+te zien krijgen, ga dan terug en kies de andere versie. Als geen enkele versie werkt, dan betekent dit dat de server geen GD ondersteund.</dd>
+
+  <dt>Breedte en hoogte</dt>
+
+  <dd>Maximale groote die een indexafbeelding (thumbnail) mag hebben, daarbij blijft de verhouding behouden.</dd>
+
+  <dt>Aantal thumbnails aanmaken</dt>
+
+  <dd>Probeer niet in één keer teveel thumbnails te maken, dit vergt namelijk erg veel processorkracht. Als je phpgallery hebt geinstalleerd bij een gratis webhoster kan deze door de hoge
+   processorkracht die je vraagt het besluit nemen om je website te verwijderen.</dd>
+
+  <dt>Bestandsformaat</dt>
+
+  <dd>Alleen het bestandsformaat JPEG wordt ondersteund om thumbnails te maken. Thumbnails kunnen alleen gemaakt worden van PNG en JPEG afbeeldingen.</dd>
+
+</dl>
Index: /tags/2.0.2/language/nl_NL/help/user_list.html
===================================================================
--- /tags/2.0.2/language/nl_NL/help/user_list.html	(revision 3278)
+++ /tags/2.0.2/language/nl_NL/help/user_list.html	(revision 3278)
@@ -0,0 +1,39 @@
+<h2>Gebruikers lijst</h2>
+
+<p>Hier kun je geregistreerde gebruikers beheren. Rechten kun je aanpassen in een aantal andere schermen.</p>
+
+<h3>Gebruiker toevoegen</h3>
+
+<p>Administrators kunnen zelf handmatig een gebruiker toevoegen.</p>
+
+<h3>Bebruikerslijst</h3>
+
+<p>De lijst kan gefilterd worden op gebruikersnaam (gebruike * als wildcard), groepen of status. De lijst kan gesorteerd worden op registratiedatum of gebruikersnaam, van A tot Z
+of van Z tot A.</p>
+
+<p>Dit scherm werkt verschillende gebruikers bij met verschillende akties:</p>
+
+<ul>
+
+  <li>verwijder gebruikers (vereist een bevestiging)</li>
+
+  <li>veranderen status</li>
+
+  <li>aan/af koppelen van groepen</li>
+
+  <li>wijzig weergave eigenschappen</li>
+
+  <li>wijzig extra eigenschappen</li>
+
+</ul>
+
+<p>Het doel is de geselecteerde groep gebruikers (standaard) of alle gebruikers. dit word gevraagd.</p>
+<h3>Adviseur</h3>
+<p>Definitie van adviseursgebruiker:</p>
+<ul>
+  <li>verleen toegang op alle schermen die door deze status wordt toegestaan</li>
+  <li>alleen lezen of simulatie toegang</li>
+</ul>
+
+<p>Het is mogelijk om de advies toe te staan via de variabel $conf['allow_adviser'].</p>
+<p>Als de variabele is 'true', dan is het moegelijk om een gebruiker aan te wijzen als adviseur</p>
Index: /tags/2.0.2/language/nl_NL/index.php
===================================================================
--- /tags/2.0.2/language/nl_NL/index.php	(revision 3278)
+++ /tags/2.0.2/language/nl_NL/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/language/nl_NL/install.lang.php
===================================================================
--- /tags/2.0.2/language/nl_NL/install.lang.php	(revision 3278)
+++ /tags/2.0.2/language/nl_NL/install.lang.php	(revision 3278)
@@ -0,0 +1,76 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+$lang['Installation'] = 'Installatie';
+$lang['Initial_config'] = 'Basis configuratie';
+$lang['Default_lang'] = 'Standaard gallery taal';
+$lang['step1_title'] = 'Database configuratie';
+$lang['step2_title'] = 'Admin configuratie';
+$lang['Start_Install'] = 'Start Installatie';
+$lang['reg_err_mail_address'] = 'E-mail adres moet lijken op xxx@yyy.eee (voorbeeld : jack@altern.org)';
+
+$lang['install_webmaster'] = 'Webmaster login';
+$lang['install_webmaster_info'] = 'Het word getoond aan de bezoekers. Het is ook noodzakelijk voor de administratie van de website';
+
+$lang['step1_confirmation'] = 'Parameters zijn correct';
+$lang['step1_err_db'] = 'De verbinding met de server is geslaagd, maar het is niet mogelijk om verbinding te krijgen met de database';
+$lang['step1_err_server'] = 'Geen verbinding met de server';
+$lang['step1_err_copy_2'] = 'Het is nu mogelijk om verder te gaan met de volgende stap van de installatie';
+$lang['step1_err_copy_next'] = 'volgende stap';
+$lang['step1_err_copy'] = 'Kopieer de tekst tussen de lijnen en plak deze in het bestand "include/mysql.inc.php"(Waarschuwing: mysql.inc.php mag alleen het roze gedeelte bevatten, geen return of extra spatie). Dit moet alleen wanneer dit bestand geen schrijfrechten';
+
+$lang['step1_host'] = 'MySQL host';
+$lang['step1_host_info'] = 'localhost, sql.multimania.com, toto.freesurf.fr';
+$lang['step1_user'] = 'Gebruiker';
+$lang['step1_user_info'] = 'De gebruikersnaam welke door uw provider is gegeven';
+$lang['step1_pass'] = 'Wachtwoord';
+$lang['step1_pass_info'] = 'De gebruikersnaam welke door uw provider is gegeven';
+$lang['step1_database'] = 'Database naam';
+$lang['step1_database_info'] = 'Ook deze is door uw provider gegeven';
+$lang['step1_prefix'] = 'Database tabel voorvoegsel';
+$lang['step1_prefix_info'] = 'Tabellen in de database worden voorzien van dit voorvoegsel (dit maakt een beter beheer van de database mogelijk) ook wel prefix genoemd';
+$lang['step2_err_login1'] = 'Geef een gebruikersnaam voor de beheerder';
+$lang['step2_err_login3'] = 'De gebruikersnaam mag geen \' of " bevatten';
+$lang['step2_err_pass'] = 'Vul a.u.b. nogmaals uw wachtwoord in';
+$lang['install_end_title'] = 'Installatie voltooid';
+$lang['step2_pwd'] = 'Webmaster wachtwoord';
+$lang['step2_pwd_info'] = 'Hou dit vertrouwlijk, dit geeft toegang tot de beheermodule';
+$lang['step2_pwd_conf'] = 'Wachtwoord [bevestigen]';
+$lang['step2_pwd_conf_info'] = 'verificatie';
+$lang['install_help'] = 'Hulp nodig ? stel een vraag op het <a href="%s" target="_blank">Piwigo forum</a>.';
+$lang['install_end_message'] = 'Het installeren van Piwigo is klaar, de volgende stap is<br /><br />
+* Ga naar de Indentificatie pagina en gebruik hiervoor het eerder opgegeven gebruikersnaam met wachtwoord<br />
+* Deze gebruikersnaam geeft u toegang tot de beheermenu zodat u afbeeldingen op uw website kan plaatsen';
+$lang['conf_mail_webmaster'] = 'Webmaster email adres';
+$lang['conf_mail_webmaster_info'] = 'Het is mogelijk dat bezoekers contact opnemen met de beheerder middels e-mail';
+
+/* TODO */$lang['PHP 5 is required'] = 'PHP 5 is required';
+/* TODO */$lang['It appears your webhost is currently running PHP %s.'] = 'It appears your webhost is currently running PHP %s.';
+/* TODO */$lang['Piwigo may try to switch your configuration to PHP 5 by creating or modifying a .htaccess file.'] = 'Piwigo may try to switch your configuration to PHP 5 by creating or modifying a .htaccess file.';
+/* TODO */$lang['Note you can change your configuration by yourself and restart Piwigo after that.'] = 'Note you can change your configuration by yourself and restart Piwigo after that.';
+/* TODO */$lang['Try to configure PHP 5'] = 'Try to configure PHP 5';
+/* TODO */$lang['Sorry!'] = 'Sorry!';
+/* TODO */$lang['Piwigo was not able to configure PHP 5.'] = 'Piwigo was not able to configure PHP 5.';
+/* TODO */$lang["You may referer to your hosting provider's support and see how you could switch to PHP 5 by yourself."] = "You may referer to your hosting provider's support and see how you could switch to PHP 5 by yourself.";
+/* TODO */$lang['Hope to see you back soon.'] = 'Hope to see you back soon.';
+?>
Index: /tags/2.0.2/language/nl_NL/iso.txt
===================================================================
--- /tags/2.0.2/language/nl_NL/iso.txt	(revision 3278)
+++ /tags/2.0.2/language/nl_NL/iso.txt	(revision 3278)
@@ -0,0 +1,1 @@
+Nederlands [NL]
Index: /tags/2.0.2/language/nl_NL/upgrade.lang.php
===================================================================
--- /tags/2.0.2/language/nl_NL/upgrade.lang.php	(revision 3278)
+++ /tags/2.0.2/language/nl_NL/upgrade.lang.php	(revision 3278)
@@ -0,0 +1,45 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+/* TODO */
+$lang['Upgrade'] = 'Upgrade';
+$lang['introduction message'] = 'This page proposes to upgrade your database corresponding to your old version of Piwigo to the current version.
+The upgrade assistant thinks you are currently running a <strong>release %s</strong> (or equivalent).';
+$lang['Upgrade from %s to %s'] = 'Upgrade from version %s to %s';
+$lang['Statistics'] = 'Statistics';
+$lang['total upgrade time'] = 'total upgrade time';
+$lang['total SQL time'] = 'total SQL time';
+$lang['SQL queries'] = 'SQL queries';
+$lang['Upgrade informations'] = 'Upgrade informations';
+$lang['perform a maintenance check'] = 'Perform a maintenance check in [Administration>Specials>Maintenance] if you encounter any problem.';
+$lang['deactivated plugins'] = 'As a precaution, following plugins have been deactivated. You must check for plugins upgrade before reactiving them:';
+$lang['upgrade login message'] = 'Only administrator can run upgrade: please sign in below.';
+$lang['You do not have access rights to run upgrade'] = 'You do not have access rights to run upgrade';
+$lang['in include/mysql.inc.php, before ?>, insert:'] = 'In <i>include/mysql.inc.php</i>, before <b>?></b>, insert:';
+
+// Upgrade informations from upgrade_1.3.1.php
+$lang['all sub-categories of private categories become private'] = 'All sub-categories of private categories become private';
+$lang['user permissions and group permissions have been erased'] = 'User permissions and group permissions have been erased';
+$lang['only thumbnails prefix and webmaster mail saved'] = 'Only thumbnails prefix and webmaster mail address have been saved from previous configuration';
+
+?>
Index: /tags/2.0.2/language/pl_PL/about.html
===================================================================
--- /tags/2.0.2/language/pl_PL/about.html	(revision 3278)
+++ /tags/2.0.2/language/pl_PL/about.html	(revision 3278)
@@ -0,0 +1,10 @@
+  <li>Piwigo jest aplikacją WEB dającą mozliwość
+  tworzenia galerii zdjęć online.</li>
+
+  <li>Technicznie, Piwigo jest stworzone z wykorzystaniem PHP (elePHPant)
+  i w oparciu o bazę danych MySQL (SQuirreL).</li>
+
+  <li>Jeżeli masz jakieś uwagi lub sugestie odwiedź oficjalną
+  <a href="http://piwigo.org">Piwigo</a>, lub dedykowane
+  <a href="http://forum.Piwigo.net">forum</a>.</li>
+
Index: /tags/2.0.2/language/pl_PL/admin.lang.php
===================================================================
--- /tags/2.0.2/language/pl_PL/admin.lang.php	(revision 3278)
+++ /tags/2.0.2/language/pl_PL/admin.lang.php	(revision 3278)
@@ -0,0 +1,650 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008      Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+$lang['%d association'] = '%d powiązanie';
+$lang['%d associations'] = '%d powiązań';
+$lang['cat_inclu_part1_S'] = '%d kategoria zawierająca ';
+$lang['cat_inclu_part1_P'] = '%d kategorii zawierających ';
+$lang['cat_inclu_part2_S'] = '%d fizycznie';
+$lang['cat_inclu_part2_P'] = '%d fizycznie';
+$lang['cat_inclu_part3_S'] = ' i %d wirtualnie';
+$lang['cat_inclu_part3_P'] = ' i %d wirtualnie';
+$lang['%d category moved'] = '%d kategoria przeniesiona';
+$lang['%d categories moved'] = '%d kategorii przeniesionych';
+$lang['%d group'] = '%d grupa';
+$lang['%d groups'] = '%d grup';
+$lang['%d member'] = '%d członek';
+$lang['%d members'] = '%d członków';
+$lang['%d tag'] = '%d tag';
+$lang['%d tags'] = '%d tagów';
+$lang['%d user comment rejected'] = '%d komentarz użytkownika odrzucony';
+$lang['%d user comments rejected'] = '%d komentarzy użytkownika odrzuconych';
+$lang['%d user comment validated'] = '%d komentarz użytkownika zaakceptowany';
+$lang['%d user comments validated'] = '%d komentarzy użytkowników zaakceptowanych';
+$lang['%d user deleted'] = '%d użytkownik usunięty';
+$lang['%d users deleted'] = '%d usuniętych użytkowników';
+$lang['%d user'] = '%d użytkownik';
+$lang['%d users'] = '%d użytkowników';
+$lang['%d waiting for validation'] = '%d oczekujących na zatwierdzenie';
+$lang['%d waiting pictures rejected'] = '%d oczekujących zdjęć odrzuconych';
+$lang['%d waiting pictures validated'] = '%d oczekujących zdjęć zatwierdzoych';
+$lang['Actions'] = 'Akcje';
+$lang['Activate'] = 'Aktywacja';
+$lang['Add/delete a permalink'] = 'Dodaj/Usuń permalink';
+$lang['Add a tag'] = 'Dodaj tag';
+$lang['Add a user'] = 'dodaj użytkownika';
+$lang['Add group'] = 'Dodaj grupę';
+$lang['Add selected elements to caddie'] = 'Dodaj wybrane elementy do koszyka';
+$lang['Add'] = 'Dodaj';
+$lang['Allow user registration'] = 'Zezwól na rejestrację użytkowników';
+$lang['Apply to subcategories'] = 'Zastosuj do podkategorii';
+$lang['Are you sure?'] = 'Jesteś pewien?';
+$lang['Associated'] = 'Powiązane';
+$lang['Association to categories'] = 'Powiązania do kategorii';
+$lang['Batch management'] = 'Zarządzanie batch';
+$lang['Caddie management'] = 'Zarządzanie koszykiem';
+$lang['Caddie'] = 'Koszyk';
+$lang['Categories authorized thanks to group associations'] = 'Kategorie zautoryzowane dzięki powiązaniu z grupami';
+$lang['Categories manual order was saved'] = 'Zapisano ręcznie wykonaną kolejność kategorii';
+$lang['Categories ordered alphanumerically'] = 'Kategorie sortowane alfanumerycznie';
+$lang['Category elements associated to the following categories: %s'] = 'Elementy kategorii powiązane z następującymi kategoriami: %s';
+$lang['Check for upgrade failed for unknown reasons.'] = 'Sprawdzenie aktualizacji nie powiodło się z nieznanych powodów.';
+$lang['Check for upgrade'] = 'Sprawdź aktualizacje';
+$lang['Comments for all'] = 'Komentarze dla wszystkich';
+$lang['Controversy'] = 'Kontorversyjność';
+$lang['Current name'] = 'Bieżąca nazwa';
+$lang['Database'] = 'Baza danych';
+$lang['Deactivate'] = 'Deaktywuj';
+$lang['Delete Representant'] = 'Usuń reprezentanta';
+$lang['Delete selected tags'] = 'Usuń zaznaczone tagi';
+$lang['Delete selected users'] = 'Usuń zaznaczonych użytkowników';
+$lang['Deletions'] = 'Usunięcia';
+$lang['Deny selected groups'] = 'Zabroń zaznaczonym grupom';
+$lang['Deny selected users'] = 'Zabroń zaznaczonym użytkownikom';
+$lang['Description'] = 'Opis';
+$lang['Display options'] = 'Opcje wyświetlania';
+$lang['Dissociated'] = 'Niepowiązane';
+$lang['Does not represent'] = 'Nie reprezentuje';
+$lang['Edit all picture informations'] = 'Edytuj informacje dla wszystkich obrazów';
+$lang['Edit selected tags'] = 'Edytuj zaznaczone tagi';
+$lang['Edit tags'] = 'Edytuj tagi';
+$lang['Elements'] = 'Elementy';
+$lang['Email administrators when a new user registers'] = 'Wyślij wiadomość do administratora gdy zarejestruje się nowy użytkownik';
+$lang['Email administrators when a valid comment is entered'] = 'Wyślij wiadomość do administratora gdy zostanie wprowadzony poprawny komentarz';
+$lang['Email administrators when a comment requires validation'] = 'Wyślij wiadomość do administratora gdy komentarz wymaga weryfikacji';
+$lang['Email administrators when a picture is uploaded'] = 'Wyślij wiadomość do administratora gdy został wgrany nowy obraz';
+$lang['Empty caddie'] = 'Wyczyść koszyk';
+$lang['Environment'] = 'Środowisko';
+$lang['Form'] = 'Formularz';
+$lang['Gallery URL'] = 'Adres URL galerii';
+$lang['Gallery description'] = 'Opis galerii';
+$lang['Gallery title'] = 'Tytuł galerii';
+$lang['Grant selected groups'] = 'Zezwól zaznaczonym grypom';
+$lang['Grant selected users'] = 'Zezwól zaznaczonym użytkownikom';
+$lang['Group name'] = 'Nazwa grupy';
+$lang['Groups'] = 'Grupy';
+$lang['Guests'] = 'Goście';
+$lang['History'] = 'Historia';
+$lang['Informations'] = 'Informacje';
+$lang['Install'] = 'Instaluj';
+$lang['Link all category elements to a new category'] = 'Podepnij wszystkie elementy kategorii do nowej kategorii';
+$lang['Link all category elements to some existing categories'] = 'Podepnij wszystkie elementy kategorii do istniejącej kategorii';
+$lang['Linked categories'] = 'Podpięte kategorie';
+$lang['Lock gallery'] = 'Zablokuj galerię';
+$lang['Maintenance'] = 'Maintenance';
+$lang['Manage permissions for a category'] = 'Zarządzaj uprawnieniami dla kategorii';
+$lang['Manage permissions for group "%s"'] = 'Zarządzaj uprawnieniami dla grupy "%s"';
+$lang['Manage permissions for user "%s"'] = 'Zarządzaj uprawnieniami dla użytkownika "%s"';
+$lang['Manage tags'] = 'Zarządzaj tagami';
+$lang['Members'] = 'Członkowie';
+$lang['Metadata synchronized from file'] = 'Metadane zsynchronizowane z pliku';
+$lang['Move categories'] = 'Przenieś kategorie';
+$lang['Move'] = 'Przenieś';
+$lang['Name'] = 'Nazwa';
+$lang['New name'] = 'Nowa nazwa';
+$lang['New parent category'] = 'Nowa nadrzędna kategoria';
+$lang['New tag'] = 'Nowy tag';
+$lang['No tag defined. Use Administration>Pictures>Tags'] = 'Brak zdefiniowanych tagów. Użyj Administracja>Obrazy>Tagi';
+$lang['Number of comments per page'] = 'Liczba komentarzy na stronę';
+$lang['Number of rates'] = 'Liczba ocen';
+$lang['Number of thumbnails to create'] = 'Liczba miniatru do stworzenia';
+$lang['Only private categories are listed'] = 'Tylko prywatne kategorie zostały wyświetlone';
+$lang['Operating system'] = 'System operacyjny';
+$lang['Options'] = 'Opcje';
+$lang['Order alphanumerically'] = 'Sortuj alfanumerycznie';
+$lang['Other private categories'] = 'Inne kategorie prywatne';
+$lang['Page banner'] = 'Banner strony';
+$lang['Parent category'] = 'Nadrzędna kategoria';
+$lang['Path'] = 'Ścieżka';
+$lang['Permalink'] = 'Link permanentny';
+$lang['Permalink_%s_histo_used_by_%s'] = 'Link permanentny %s został poprzednio wykorzystany przez %s. Najpierw usuń link z historii';
+$lang['Permalink_name_rule'] = 'Nzawa linku permanentnego musi składać się z następujących znaków a-z, A-Z, 0-9, "-", "_" lub "/". Nie może być cyfrą lub zaczynać się od "-"';
+$lang['Permalink %s is already used by category %s'] = 'Link permanentny %s jest już używany przez kategorię %s';
+$lang['Permalink history'] = 'Historia linków permanentnych';
+$lang['Permalinks'] = 'Linki permanentne';
+$lang['Permission denied'] = 'Dostęp zabroniony';
+$lang['Permission granted thanks to a group'] = 'Uprawnienia przyznane dzięki grupie';
+$lang['Permission granted'] = 'Dostęp przyznany';
+$lang['Picture informations updated'] = 'Zaktualizowano informację o obrazie';
+$lang['Plugins'] = 'Wtyczki';
+$lang['Position'] = 'Pozycja';
+$lang['Preferences'] = 'Preferencje';
+$lang['Properties'] = 'Właściwości';
+$lang['Random picture'] = 'Losowy obraz';
+$lang['Rate date'] = 'Oceny po dacie';
+$lang['Rating by guests'] = 'Oceny przez gości';
+$lang['Rating'] = 'Oceny';
+$lang['Reject All'] = 'Odrzuć wszystkie';
+$lang['Reject'] = 'Odrzuć';
+$lang['Representant'] = 'Reprezentant';
+$lang['Representation of categories'] = 'Representacja kategorii';
+$lang['Representative'] = 'Representacyjny';
+$lang['Represents'] = 'Representuje';
+$lang['Save order'] = 'Zapisz kolejność';
+$lang['Save to permalink history'] = 'Zapisz do historii linków permanentnych';
+$lang['Select at least one category'] = 'Wybierz przynajmniej jedną kategorię';
+$lang['Select at least one picture'] = 'Wybierz przynajmniej jeden obraz';
+$lang['Select at least one user'] = 'Wybierz przynajmniej jednego użytkownika';
+$lang['Show info'] = 'Pokaż informacje';
+$lang['Site manager'] = 'Menadżer strony';
+$lang['Status'] = 'Status';
+$lang['Statistics'] = 'Statystyki';
+$lang['Storage category'] = 'Miejsce przechowywania kategorii';
+$lang['Sum of rates'] = 'Suma ocen';
+$lang['Tag "%s" already exists'] = 'Tag "%s" już istnieje';
+$lang['Tag "%s" was added'] = 'Tag "%s" został dodany';
+$lang['Tag selection'] = 'Wybór tagu';
+$lang['Take selected elements out of caddie'] = 'Usuń wybrane elementy z koszyka';
+$lang['The %d following tag were deleted'] = 'NAstępujące tagi zostały usunięte';
+$lang['The %d following tags were deleted'] = '%d tagów zostało usuniętych';
+$lang['Unable to check for upgrade since allow_url_fopen is disabled.'] = 'Nie można sprawdzić aktualizacji z powodu wyłączonej funkcji allow_url_fopen.';
+$lang['Uninstall'] = 'Odinstaluj';
+$lang['Use default sort order']='Uzyj domyślnego sortowania obrazów (zdefiniowane w pliku konfiguracyjnym)';
+$lang['User comments validation'] = 'Zatwierdzanie komentarzy użytkowników';
+$lang['Users'] = 'Użytkownicy';
+$lang['Validate All'] = 'Zatwierdź wszystkie';
+$lang['Validate'] = 'Zatwierdź';
+$lang['Validation'] = 'Zatwierdzanie';
+$lang['Version'] = 'Wersja';
+$lang['Virtual categories movement'] = 'Przenoszenie kategorii wirtualnych';
+$lang['Virtual categories to move'] = 'Kategorie wirtualne do przeniesienia';
+$lang['Virtual category name'] = 'Nazwa kategorii wirtualnej';
+$lang['Webmaster cannot be deleted'] = 'Nie można usunąć użytkownika Webmaster';
+$lang['You are running on development sources, no check possible.'] = 'Nie można sprawdzić, ponieważ używasz źródeł developer\'skich.';
+$lang['You cannot delete your account'] = "Nie możesz usunąć swojego konta";
+$lang['You cannot move a category in its own sub category'] = 'Nie możnesz przenieść kategorii do jej własnej podkategorii';
+$lang['You need to confirm deletion'] = 'Musisz potwierdzić usunięcie';
+$lang['add tags'] = 'dodaj tagi';
+$lang['adviser'] = 'Doradca';
+$lang['associate to category'] = 'powiązane z kategorią';
+$lang['associate to group'] = 'powiązane z grupą';
+$lang['authorized'] = 'Zautoryzowane';
+$lang['cat_add'] = 'Dodaj wirualną kategorię';
+$lang['cat_comments_title'] = 'Autoryzuj użytkowników by mogli dodawać komentarze do wybranych kategorii';
+$lang['cat_error_name'] = 'Nazwa kategorii nie może być pusta';
+$lang['cat_lock_title'] = 'Zablokuj kategorie';
+$lang['cat_private'] = 'Kategoria prywatna';
+$lang['cat_public'] = 'Kategoria publiczna';
+$lang['cat_representant'] = 'Znajdź losowo nowego reprezentanta';
+$lang['cat_security'] = 'Publiczne / Prywatne';
+$lang['cat_status_title'] = 'Zarządzaj autoryzacjami dla wybranych kategorii';
+$lang['cat_upload_title'] = 'Zaznacz kategorie, do których można wgrywać';
+$lang['cat_virtual_added'] = 'Dodano wirtualną kategorię';
+$lang['cat_virtual_deleted'] = 'Usunięto wirtualną kategorię';
+$lang['category'] = 'kategoria';
+$lang['conf_access'] = 'Typ dostępu';
+$lang['conf_comments_title'] = 'Komentarze';
+$lang['conf_confirmation'] = 'Dane zapisane w bazie danych';
+$lang['conf_display'] = 'Wyświetlanie domyślne';
+$lang['conf_history_title'] = 'Historia';
+$lang['conf_gallery_url_error'] = 'Adres URL galerii jest niepoprawny.';
+$lang['conf_main_title'] = 'Główne';
+$lang['conf_nb_comment_page_error'] = 'Liczba komentarzy na stronę musi być pomiędzy 5 a 50.';
+$lang['config'] = 'Konfiguracja';
+$lang['confirm'] = 'potwierdź';
+$lang['Date'] = 'Data';
+$lang['delete category'] = 'usuń kategorię';
+$lang['dissociate from category'] = 'usuń powiązanie od kategorii';
+$lang['dissociate from group'] = 'usuń powiązanie od grupy';
+$lang['edit category permissions'] = 'edytuj uprawnienia kategorii';
+$lang['editcat_confirm'] = 'Informacje o kategorii zaktualizowano pomyślnie.';
+$lang['editcat_uploadable'] = 'Zautoryzuj upload';
+$lang['elements per page'] = 'elementów na stronę';
+$lang['elements'] = 'elementy';
+$lang['enabled_high'] = 'Wysoka jakość włączona';
+$lang['file'] = 'plik';
+$lang['filesize'] = 'rozmiar pliku';
+$lang['first element added on %s'] = 'pierwszy element dodany %s';
+$lang['forbidden'] = 'Zabronione';
+$lang['conf_general'] = 'Ogólne';
+$lang['global mode'] = 'tryb globalny';
+$lang['group "%s" added'] = 'dodano grupę "%s"';
+$lang['group "%s" deleted'] = 'usunięto grupę "%s"';
+$lang['group "%s" updated'] = 'zaktualizowano grupę "%s"';
+$lang['group'] = 'grupa';
+$lang['group_add_error1'] = 'Nazwa grupy nie może zawierać znaków " lub \' lub być pusta.';
+$lang['group_add_error2'] = 'NAzwa jest już używana przez inną grupę.';
+$lang['groups'] = 'Grupy';
+$lang['instructions'] = 'Instrukcje';
+$lang['is_high_disabled'] = '';
+$lang['is_high_enabled'] = 'Wysoka jakość';
+$lang['jump to category'] = 'przejdź do kategorii';
+$lang['jump to image'] = 'przejdź do obrazu';
+$lang['leave'] = 'opuść';
+$lang['lock'] = 'Zablokuj';
+$lang['locked'] = 'Zablokowane';
+$lang['manage category elements'] = 'zarządzaj elementami kategorii';
+$lang['manage sub-categories'] = 'zarządzaj podkategoriami';
+$lang['manage'] = 'Zarządzaj';
+$lang['maximum height'] = 'maksymalna wysokość';
+$lang['maximum width'] = 'maksymalna szerokość';
+$lang['nbm_background_treatment_redirect_second'] = 'Czas wykonania minął, proces musi być kontynuowany [Szacowany czas: %d sekund].';
+$lang['nbm_background_treatment_redirect_seconds'] = 'Czas wykonania minął, proces musi być kontynuowany [Szacowany czas: %d sekund].';
+$lang['nbm_break_timeout_list_user'] = 'Czas wysłania wiadomości do listy użytkowników jest ograniczony. Pozostali użytkownicy nie znajdują się na liście.';
+$lang['nbm_break_timeout_send_mail'] = 'Czas wysłania wiadomości jest ograniczony. Pozostałe wiadomości zostaną pominięte.';
+$lang['nbm_col_check_user_send_mail'] = 'Do wysłania ?';
+$lang['nbm_col_last_send'] = 'Ostantnio wysłane';
+$lang['nbm_col_mail'] = 'email';
+$lang['nbm_col_user'] = 'Użytkownik';
+$lang['nbm_complementary_mail_content'] = 'Uzupełniająca treść wiadomości';
+$lang['nbm_content_byebye'] = 'Do zobaczenia wkrótce,';
+$lang['nbm_content_goto_1'] = 'Przejdź do ';
+$lang['nbm_content_goto_2'] = '.';
+$lang['nbm_content_hello_1'] = 'Witaj ';
+$lang['nbm_content_hello_2'] = ',';
+$lang['nbm_content_new_elements'] = 'dodano nowe elementy ';
+$lang['nbm_content_new_elements_single'] = ' dnia ';
+$lang['nbm_content_new_elements_between_1'] = 'pomiędzy ';
+$lang['nbm_content_new_elements_between_2'] = ' i ';
+$lang['nbm_content_subscribe_by_admin'] = 'Webmaster zapisał Cię na listę powiadomień.';
+$lang['nbm_content_subscribe_by_himself'] = 'Zapisałeś(łaś) się aby otrzymywać powiadomienia.';
+$lang['nbm_content_subscribe_link'] = 'Aby się zapisać';
+$lang['nbm_content_problem_contact'] = 'Jeżeli napotkasz problem lub masz pytania wyślij wiadomość do ';
+$lang['nbm_content_pb_contact_object'] = '[NBM] Problemy i pytania';
+$lang['nbm_content_unsubscribe_by_admin'] = 'Webmaster wypisał Cię z otrzymywania powiadomień.';
+$lang['nbm_content_unsubscribe_by_himself'] = 'Zostałeś wypisany z otrzymywania powiadomień.';
+$lang['nbm_content_click_on'] = ', kliknij ';
+$lang['nbm_content_unsubscribe_link'] = 'Aby się wypisać';
+$lang['nbm_info_send_mail_as'] = 'Tytuł galerii będzie używany jeżli pole zostanie puste';
+$lang['nbm_item_notification'] = 'Powiadomienia';
+$lang['nbm_msg_error_sending_email_to'] = 'Błąd podczas wysyłania wiadomości do %s [%s].';
+$lang['nbm_msg_mail_sent_to'] = 'Wysłano wiadomość do %s [%s].';
+$lang['nbm_msg_n_mail_sent'] = 'Wysłano %d wiadomość.';
+$lang['nbm_msg_n_mails_sent'] = 'Wysłano %d wiadomości.';
+$lang['nbm_msg_n_mail_not_send'] = 'Nie wysłano %d wiadomości.';
+$lang['nbm_msg_n_mails_not_send'] = 'Nie wysłano %d wiadomości.';
+$lang['nbm_no_mail_to_send'] = 'Brak wiadomości do wysłania.';
+$lang['nbm_no_user_available_to_send_L1'] = 'Brak dostępnych użytkowników do wysłania powiadomienia.';
+$lang['nbm_no_user_available_to_send_L2'] = 'Użytkownik jest dostępny, jeżeli są nowe elementy do powiadomienia.';
+$lang['nbm_no_user_available_to_send_L3'] = 'Prawdopodobnie nie ma zapisanych użytkowników (tę zakładkę widzi tylko użytkownik webmaster).';
+$lang['nbm_no_user_to send_notifications_by_mail'] = 'Brak użytkowników do wysłania powiadomień.';
+$lang['nbm_object_news'] = 'Dodano nowe elementy';
+$lang['nbm_object_subscribe'] = 'Zapisz do powiadomień email';
+$lang['nbm_object_unsubscribe'] = 'Wypisz z powiadomień email';
+$lang['nbm_param_mode'] = 'Parametr';
+$lang['nbm_redirect_msg'] = 'Procesowanie.'."\n\n".'Proszę czekać...';
+$lang['nbm_repost_submit'] = 'Kontynuuj procesowanie';
+$lang['nbm_send_complementary_mail_content'] = 'Uzupełniająca treść wiadomości';
+$lang['nbm_send_detailed_content'] = 'Dodaj szczegółową treść';
+$lang['nbm_send_mail_as'] = 'Wyślij wiadomość jako';
+$lang['nbm_send_mail_to_users'] = 'Wyślij wiadomość do użytkowników';
+$lang['nbm_send_mode'] = 'Wyślij';
+$lang['nbm_send_options'] = 'Opcje';
+$lang['nbm_send_submit'] = 'Wyślij';
+$lang['nbm_subscribe_col'] = 'Zapisani';
+$lang['nbm_subscribe_mode'] = 'Zapisy';
+$lang['nbm_title_param'] = 'Parametry';
+$lang['nbm_title_send'] = 'Wybierz odbiorców';
+$lang['nbm_title_subscribe'] = 'Zapisz/wypisz użytkowników';
+$lang['nbm_unsubscribe_col'] = 'Nie zapisani';
+$lang['nbm_updated_param_count'] = 'Zaktualizowano %d parametr.';
+$lang['nbm_updated_params_count'] = 'Zaktualizowano %d parametrów.';
+$lang['nbm_user_change_enabled_error_on_updated_data_count'] = 'Użytkownik %d nie został zaktualizowany.';
+$lang['nbm_users_change_enabled_error_on_updated_data_count'] = 'Nie zaktualizowano %d użytkowników.';
+$lang['nbm_user_change_enabled_false'] = 'Użytkownik %s [%s] usunięty z listy zapisanych.';
+$lang['nbm_user_change_enabled_true'] = 'Użytkownik %s [%s] został dodany do listy zapisanych na listę.';
+$lang['nbm_user_change_enabled_updated_data_count'] = 'Zaktualizowano użytkownika %d.';
+$lang['nbm_users_change_enabled_updated_data_count'] = 'Zaktualizowano %d użytkowników.';
+$lang['nbm_user_not_change_enabled_false'] = 'Użytkownik %s [%s] nie został usunięty z listy zapisanych.';
+$lang['nbm_user_not_change_enabled_true'] = 'Nie dodano użytkownika %s [%s] do listy zapisanych.';
+$lang['nbm_user_x_added'] = 'Dodano użytkownika %s [%s] .';
+$lang['nbm_warning_subscribe_unsubscribe'] = 'Ostrzeżenie: zapisanie lub wypisanie spowoduje wyłanie wiadomości do użytkowników';
+$lang['nbm_send_html_mail'] = 'Wyslij email w formacie HTML';
+$lang['nbm_send_recent_post_dates'] = 'Dodaj wyświetlanie aktualnych obrazów grupowane po dacie';
+$lang['nbm_info_send_recent_post_dates'] = 'Dostępne tylko w formacie HTML';
+$lang['no_write_access'] = 'brak praw do zapisu';
+$lang['path'] = 'ścieżka';
+$lang['permissions'] = 'Uprawnienia';
+$lang['private'] = 'prywatna';
+$lang['properties'] = 'Właściwości';
+$lang['public'] = 'publiczna';
+$lang['purge never used notification feeds'] = 'Wyczyść nigdy nie używane RSS feed';
+$lang['purge sessions'] = 'Wyczyść sesje';
+$lang['randomly represented'] = 'reprezentowane losowo';
+$lang['registration_date'] = 'data rejestracji';
+$lang['remote_site'] = 'Zdalne strony';
+$lang['remote_site_clean'] = 'wyczyść';
+$lang['remote_site_clean_hint'] = 'usuń na zdalnej stronie plik listing.xml';
+$lang['remote_site_generate'] = 'generuj listę';
+$lang['remote_site_generate_hint'] = 'generuj plik listing.xml na zdalnej stronie';
+$lang['remote_site_local_create'] = 'Utwórz tę stronę';
+$lang['remote_site_local_found'] = 'Odnaleziono lokalny plik listing.xml dla ';
+$lang['remote_site_local_update'] = 'odczytaj i aktualizuj lokalny plik listing.xml';
+$lang['remote_site_test'] = 'test';
+$lang['remote_site_test_hint'] = 'testuj zdalną stronę';
+$lang['remote_site_uncorrect_url'] = 'Adres zdalnej strony musi rozpoczynać się od http lub https i musi zawierać tylko następujące znaki "/", "a-zA-Z0-9", "-" lub "_"';
+$lang['remove tags'] = 'usuń tagi';
+$lang['repair and optimize database'] = 'Napraw i optymalizuj bazę danych';
+$lang['selection'] = 'zaznaczenie';
+$lang['set to'] = 'ustaw na';
+$lang['singly represented'] = 'pojedynczy reprezentant';
+$lang['site_already_exists'] = 'Taka strona już istnieje';
+$lang['site_create'] = 'Stwórz nową stronę : (podaj adres URL pliku create_listing_file.php)';
+$lang['site_created'] = 'utworzona';
+$lang['site_delete'] = 'usuń';
+$lang['site_delete_hint'] = 'usuń tę stronę oraz wszystkie załączone elementy';
+$lang['site_deleted'] = 'usunięte';
+$lang['site_err'] = 'wystąpił błąd';
+$lang['site_err_remote_file_not_found'] = 'nie odnaleziono pliku create_listing_file.php na zdalnej stronie';
+$lang['site_local'] = 'Lokalny';
+$lang['site_remote'] = 'Zdalny';
+$lang['site_synchronize'] = 'synchronizuj';
+$lang['site_synchronize_hint'] = 'aktualizuj bazę danych z plików';
+$lang['status'] = 'status';
+$lang['storage'] = 'Katalog';
+$lang['sub-categories'] = 'pod-kategorie';
+$lang['synchronize metadata'] = 'synchronizuj metadane';
+$lang['synchronize'] = 'synchronizuj';
+$lang['target'] = 'cel';
+$lang['thumbnail'] = 'miniatura';
+$lang['title'] = 'tytuł';
+$lang['title_categories'] = 'Zarządzanie kategoriami';
+$lang['title_configuration'] = 'Konfiguracja Piwigo';
+$lang['title_default'] = 'Administracja Piwigo';
+$lang['title_edit_cat'] = 'Edytuj kategorię';
+$lang['title_groups'] = 'Zarządzanie grupami';
+$lang['title_liste_users'] = 'Lista użytkowników';
+$lang['title_picmod'] = 'Edytuj informacje o obrazie';
+$lang['title_thumbnails'] = 'Tworzenie miniatur';
+$lang['title_update'] = 'Synchronizacja bazy danych z plikami';
+$lang['title_upload'] = 'Obrazy oczekujące na akceptację';
+$lang['tn_all'] = 'wszystkie';
+$lang['tn_alone_title'] = 'obrazy bez miniatur (tylko pliki jpeg i png)';
+$lang['tn_err_height'] = 'wysokość musi być liczbą większą od';
+$lang['tn_err_width'] = 'szerokość musi być liczbą większą od';
+$lang['tn_format'] = 'dla typu pliku';
+$lang['tn_no_missing'] = 'Aktualnie nie ma brakujących miniatur';
+$lang['tn_no_support'] = 'Obraz niedostępny lub brak wsparcia';
+$lang['tn_params_GD'] = 'Wersja GD';
+$lang['tn_params_title'] = 'Parametry tworzenia miniatur';
+$lang['tn_results_gen_time'] = 'wygenerowane w';
+$lang['tn_results_title'] = 'Wyniki tworzenia miniatur';
+$lang['tn_stats'] = 'Ogólne statystyki';
+$lang['tn_stats_max'] = 'czas maksymalny';
+$lang['tn_stats_mean'] = 'czas średni';
+$lang['tn_stats_min'] = 'czas minimalny';
+$lang['tn_stats_nb'] = 'liczba plików, dla których zostały dodane miniatury';
+$lang['tn_stats_total'] = 'czas sumaryczny';
+$lang['tn_thisformat'] = 'dla tego rodzaju plików';
+$lang['unit mode'] = 'tryb jednostkowy';
+$lang['unlocked'] = 'Odblokowane';
+$lang['unset'] = 'nie ustawione';
+$lang['up'] = 'Przenieś wyżej';
+$lang['update categories informations'] = 'Aktualizuj informacje o kategoriach';
+$lang['update images informations'] = 'Aktualizuj informacje o obrazach';
+$lang['update'] = 'Synchronizuj';
+$lang['update_cats_subset'] = 'zredukuj do pojedynczej istniejącej kategorii';
+$lang['update_default_title'] = 'Wybierz opcję';
+$lang['update_display_info'] = 'wyświetlaj jak dużo informacji (dodane kategorie i elementy, usunięte kategorie i elementy)';
+$lang['update_err_pwg_version_differs'] = 'Wersja Piwigo na zdalnej stronie jest inna';
+$lang['update_err_pwg_version_differs_info'] = 'Wersja pliku create_listing_file.php na zdalnej stronie musi być taka sama jak w Piwigo';
+$lang['update_err_remote_listing_not_found'] = 'Nie odnaleziono pliku listing.xml';
+$lang['update_err_remote_listing_not_found_info'] = 'Nie odnaleziono pliku listing.xml na zdalnej stronie. Plik ten jest generowany przez wybranie "generuj listę" w Menadżerze strony';
+$lang['update_error_list_title'] = 'Lista błędów';
+$lang['update_errors_caption'] = 'Nagłówki błędów';
+$lang['update_infos_title'] = 'Informacje szczegółowe';
+$lang['update_missing_file_or_dir'] = 'Błąd odczytu pliku/katalogu';
+$lang['update_missing_file_or_dir_info'] = 'Brak dostępu do pliku lub katalogu (nie istnieje lub brak uprawnień)';
+$lang['update_missing_tn_info'] = 'typ pliku wymaga miniatury. Miniatura musi znajdować się w podkatalogu "thumbnail" danej kategorii. Nazwa pliku z miniaturą musi zaczynać się od skonfigurowanego prefixu, a rozszerzenie pliku musi być nastepujące :';
+$lang['update_missing_tn_short'] = 'brakujące miniatury';
+$lang['update_nb_del_categories'] = 'kategorii usuniętych z bazy danych';
+$lang['update_nb_del_elements'] = 'elementów usuniętych z bazy danych';
+$lang['update_nb_elements_metadata_available'] = 'obrazów dla których można zsynchronizować metadane';
+$lang['update_nb_elements_metadata_sync'] = 'informacji o elementach zsynchronizowanych z metadanymi plików';
+$lang['update_nb_errors'] = 'błędów podczas synchronizacji';
+$lang['update_nb_new_categories'] = 'kategorii dodanych do bazy danych';
+$lang['update_nb_new_elements'] = 'elementów dodanych do bazy danych';
+$lang['update_nb_upd_elements'] = 'elementów zaktualizowanych w bazie danych';
+$lang['update_part_research'] = 'Szukaj nowych obrazów w katalogach';
+$lang['update_research_added'] = 'dodane';
+$lang['update_research_deleted'] = 'usunięte';
+$lang['update_result_metadata'] = 'Wynik synchronizacji metadanych';
+$lang['update_simulate'] = 'przeprowadź tylko symulację (nie będzie żadnych zmian w bazie danych)';
+$lang['update_simulation_title'] = '[Symulacja]';
+$lang['update_sync_all'] = 'katalogi + pliki';
+$lang['update_sync_dirs'] = 'tylko katalogi';
+$lang['update_sync_files'] = 'syncronizuj strukturę plików z bazą danych';
+$lang['update_sync_metadata'] = 'synchronizuj metadane z informacjami o elementach z bazy danych';
+$lang['update_sync_metadata_all'] = 'także elementy już zsynchronizowane';
+$lang['update_used_metadata'] = 'Wykorzystane metadane';
+$lang['update_wrong_dirname_info'] = 'NAzwy plików i katalogów muszą się składać z liter, cyfr, znaków: "-", "_" lub "."';
+$lang['update_wrong_dirname_short'] = 'zła nazwa pliku';
+$lang['upload'] = 'Upload';
+$lang['user "%s" added'] = 'użytkownik "%s" został dodany';
+$lang['user_status'] = 'Staus użytkownika';
+$lang['user_status_admin'] = 'Administrator';
+$lang['user_status_generic'] = 'Ogólny';
+$lang['user_status_guest'] = 'Gość';
+$lang['user_status_normal'] = 'Użytkownik';
+$lang['user_status_webmaster'] = 'Webmaster';
+$lang['username'] = 'nazwa użytkownika';
+$lang['users'] = 'Użytkownicy';
+$lang['virtual_category'] = 'Kategoria wirtualna';
+$lang['waiting'] = 'Oczekujące';
+$lang['is_default_group'] = 'domyślna';
+$lang['toggle_is_default_group'] = 'Właściwości przełączania \'grupy domyślnej\'';
+$lang['Advanced_features'] = 'Zaawansowane';
+$lang['Elements_not_linked'] = 'Elementy nie przypisane';
+$lang['special_admin_menu'] = 'Specjalne';
+$lang['Duplicates'] = 'Pliki o tych samych nazwach w jednej lub więcej kategoriach';
+
+$lang['Overall'] = 'W sumie';
+$lang['Year'] = 'Rok';
+$lang['Month'] = 'Miesiąc';
+$lang['Day'] = 'Dzień';
+$lang['Pages seen'] = 'Oglądanych stron';
+$lang['Pictures'] = 'Obrazy';
+$lang['time'] = 'czas';
+$lang['user'] = 'użytkownik';
+$lang['IP'] = 'IP';
+$lang['image'] = '';
+$lang['section'] = 'sekcja';
+$lang['tags'] = 'tagi';
+$lang['conf_history_guest'] = 'Zapisuj odwiedziny strony przez  gości';
+$lang['conf_history_user'] = 'Zapisuj odwiedziny strony przez  użytkowników';
+$lang['conf_history_admin'] = 'Zapisuj odwiedziny strony przez administratorów';
+$lang['cat_options_title'] = 'Właściwości';
+$lang['An information email was sent to group "%s"'] = 'Powiadomienie wysłane do członków grupy "%s';
+$lang['Send an information email to group members'] = 'Wyślij powiadomienie do członków grupy';
+$lang['Group'] = 'Grupa';
+$lang['[%s] Come to visit the category %s'] = '[%s] Wejdź aby zobaczyć kategorie %s';
+$lang['Hello,'] = 'Witaj,';
+$lang['See you soon.'] = 'Do zobaczenia wkrótce.';
+$lang['Come to discover the category:'] = 'Wejdź aby zobacyzć kategorie:';
+$lang['mail_content'] = 'Treść maila';
+$lang['none'] = 'brak';
+$lang['high'] = 'wysoki';
+$lang['other'] = 'inny';
+$lang['Element type'] = 'Typ elementu';
+$lang['User'] = 'Użytkownik';
+$lang['Image id'] = 'ID obrazu';
+$lang['Summary'] = 'Podsumowanie';
+$lang['%d line filtered'] = '%d linia odfltrowana';
+$lang['%d lines filtered'] = '%d linii odfiltrowanych';
+$lang['%d guest'] = '%d gość';
+$lang['%d guests'] = '%d gości';
+$lang['Hour'] = 'Godzina';
+$lang['is_the_guest'] = 'gość';
+$lang['is_the_default'] = 'wartości domyślne';
+$lang['High filesize'] = 'Duży rozmiar pliku';
+// --------- Starting below: New or revised $lang ---- from version 1.7.1
+$lang['Guest cannot be deleted'] = 'Gość nie może sostać usunięty';
+$lang['Default user cannot be deleted'] = 'domyślny użytkownik nie moze zostać usunięty';
+$lang['purge history detail'] = 'Usuń szczegóły historii';
+$lang['purge history summary'] = 'Usuń podsumowanie historii';
+$lang['c13y_title'] = 'Sprawdź integralność';
+$lang['c13y_Anomaly'] = 'Anomalie';
+$lang['c13y_Correction'] = 'Poprawki';
+$lang['c13y_Automatic_correction'] = 'Automatyczne poprawki';
+$lang['c13y_Impossible_automatic_correction'] = 'Automatyczna poprawka niemożliwa';
+$lang['c13y_Correction_applied_success'] = 'Poprawki zastosowana pomyślnie';
+$lang['c13y_Correction_applied_error'] = 'Poprawka zastosowana, ale wystąpił błąd';
+$lang['c13y_anomaly_count'] = 'Została wykryta %d anomalia.';
+$lang['c13y_anomalies_count'] = 'Zostało wykrytych %d anomalii.';
+$lang['c13y_anomaly_corrected_count'] = '%d anomali została poprawnie wykrytych.';
+$lang['c13y_anomalies_corrected_count'] = '%d anomalii zostało poprawnie wykrytych.';
+$lang['c13y_anomaly_not_corrected_count'] = '%d anomalia nie została poprawiona.';
+$lang['c13y_anomalies_not_corrected_count'] = '%d anomalii nie zostało poprawionych.';
+$lang['c13y_more_info'] = 'Aby uzyskać więcej informacji przejdź do %s lub %s';
+$lang['c13y_more_info_forum'] = 'forum';
+$lang['c13y_more_info_wiki'] = 'wiki';
+$lang['c13y_exif_anomaly'] = 'Wartość %s nie jest poprawna, ponieważ exif nie jest wspierany';
+$lang['c13y_exif_correction'] = 'Wartość %s musi być ustawiona na false w pliku konfiguracyjnym config_local.inc.php';
+$lang['c13y_guest_non_existent'] = 'Główny użytkownik "gość" nie istnieje';
+$lang['c13y_bad_guest_status'] = 'Status głównego użytkownika "gość" jest niepoprawny';
+$lang['c13y_default_non_existent'] = 'Domyślny użytkownik nie istnieje';
+$lang['c13y_webmaster_non_existent'] = 'Główny użytkownik "webmaster" nie istnieje';
+$lang['c13y_bad_webmaster_status'] = 'Status głównego użytkownika "webmaster" jest niepoprawny';
+$lang['c13y_user_created'] = 'Użytkownik "%s" został utworzony z hasłem "%s"';
+$lang['c13y_user_status_updated'] = 'Status użytkownika "%s" został zaktualizowany';
+$lang['add new elements to caddie'] = 'dodaj nowe elementy do koszyka';
+// --------- Starting below: New or revised $lang ---- from Butterfly
+$lang['no_display_thumbnail'] = 'Brak wyświetlania';
+$lang['display_thumbnail_classic'] = 'Wyświetlanie klasyczne';
+$lang['display_thumbnail_hoverbox'] = 'Wyświetlanie w ramkach w kształcie poduszek';
+$lang['Thumbnails'] = 'Miniatury';
+$lang['obligatory_user_mail_address'] = 'Adres email jest obowiązkowy dla wszystkich użytkowników';
+$lang['Minimum privacy level'] = 'Minimalny poziom prywatności';
+$lang['Privacy level'] = 'Poziom prywatności';
+$lang['Level 0'] = '---';
+$lang['Level 1'] = 'Kontakty';
+$lang['Level 2'] = 'Przyjaciele';
+$lang['Level 4'] = 'Rodzina';
+$lang['Level 8'] = 'Administratorzy';
+$lang['c13y_maintenance'] = 'Rozpocznij jeszcze raz sprawdzenie integralności';
+$lang['Check all'] = 'Zaznacz wszystkie';
+$lang['Uncheck all'] = 'Odznacz wszystkie';
+$lang['c13y_check_auto'] = 'Automatycznie sprawdzaj poprawki';
+$lang['c13y_submit_correction'] = 'Zastosuj wybrane poprawki';
+$lang['c13y_submit_ignore'] = 'Ignoruj wybrane anomalie';
+$lang['c13y_submit_refresh'] = 'Odśwież';
+$lang['c13y_ignore_msg1'] = 'Anomalia zostania zignorowana aż do nastepnej aktualizacji wersji';
+$lang['c13y_ignore_msg2'] = 'Poprawka anomalii anuluje fakt, żę została zignorowana';
+$lang['c13y_anomaly_ignored_count'] = '%d anomalia zostałą zignorowana.';
+$lang['c13y_anomalies_ignored_count'] = '%d anomalii zostało zignorowanych.';
+$lang['plugins_need_update'] = 'Wtyczki wymagające aktualizacji';
+$lang['plugins_dontneed_update'] = 'Wtyczki są aktualne';
+$lang['plugins_cant_check'] = 'Nie można sprawdzić wersji wtyczek';
+$lang['plugins_actual_version'] = 'Aktualna<br>wersja';
+$lang['plugins_new_version'] = 'Dostępna<br>wersja';
+$lang['plugins_auto_update'] = 'Automatyczna aktualizacja';
+$lang['plugins_auto_install'] = 'Instalacja automatyczna';
+$lang['plugins_download'] = 'Pobierz plik';
+$lang['plugins_tab_list'] = 'Lista wtyczek';
+$lang['plugins_tab_update'] = 'Sprawdź dostepność aktualizaji';
+$lang['plugins_tab_new'] = 'Inne wtyczki';
+$lang['plugins_revisions'] = 'Ostatnie wersje';
+$lang['plugins_delete'] = 'Usuń';
+$lang['plugins_confirm_delete'] = 'Czy na pewno chcesz usunąć tę wtyczkę?';
+$lang['plugins_confirm_install'] = 'Czy na pewno chcesz zainstalować tę wtyczkę?';
+$lang['plugins_confirm_upgrade'] = 'Czy na pewno chcesz zainstalować aktualizację? Musisz zweryfikować czy aktualna wersja nie wymaga odinstalowania.';
+$lang['plugins_upgrade_ok'] = '%s zostały pomyslnie zaktualizowane.';
+$lang['plugins_install_ok'] = 'Wtyczka została poprawnie skopiowana';
+$lang['plugins_install_need_activate'] = 'Aby zainstalować lub aktywować wtyczkę udaj się do listy wtyczek.';
+$lang['plugins_temp_path_error'] = 'Nie można stworzyć pliku tymczasowego.';
+$lang['plugins_dl_archive_error'] = 'Nie można pobrać archiwum.';
+$lang['plugins_archive_error'] = 'Nie można odczytać lub rozpakować archiwum.';
+$lang['plugins_extract_error'] = 'Błąd podczas rozpakowywania (%s).';
+$lang['plugins_check_chmod'] = 'Sprawdź uprawnienia (CHMOD) do katalogu "plugins" oraz podfolderów.';
+$lang['plugins_server_error'] = 'Nie można połączyć się do serwera.';
+$lang['Purge compiled templates'] = 'Usuń skompilowane szablony';
+$lang['Caddie is currently empty'] = 'Koszyk jest aktualnie pusty';
+$lang['conf_upload_title'] = 'Upload';
+$lang['Show upload link every time'] = 'Zawsze pokazuj link upload';
+$lang['User access level to upload'] = 'Poziom uprawnień użytkoników dla upload\'u';
+$lang['ACCESS_0'] = 'Wolny dostęp';
+$lang['ACCESS_1'] = 'Dostęp dla wszystkich';
+$lang['ACCESS_2'] = 'Dostep dla zapisanych';
+$lang['ACCESS_3'] = 'Dostęp dla Administratorów';
+$lang['ACCESS_4'] = 'Dostęp dla webmasterów';
+$lang['ACCESS_5'] = 'Brak dostępu';
+$lang['DEMO'] = 'Demo';
+$lang['HOME'] = 'Strona domowa Piwigo';
+$lang['FORUM'] = 'Wsparcie';
+$lang['BUGS'] = 'Błędy';
+$lang['EXTENSIONS'] = 'Rozszerzenia';
+$lang['WIKI / DOC'] = 'Dokumentacja';
+$lang['A new version of Piwigo is available.'] = 'Dostepna jest nowa wersja Piwigo.';
+$lang['Piwigo Administration'] = 'Administracja Piwigo';
+$lang['Piwigo version'] = 'Wersja Piwigo';
+$lang['You are running the latest version of Piwigo.'] = 'Używasz aktualnej wersji Piwigo.';
+$lang['c13y_version_anomaly'] = 'Zainstalowana wersja %s [%s] jest niekompatybilna z wymaganą wersją [%s]';
+$lang['c13y_version_correction'] = 'Musisz zaktualizować swój system by ......... w przeciwnym wypadku aplikacja nie będzie działała poprawnie lub w ogóle';
+$lang['Deleted on'] = 'Usunięte';
+$lang['Last hit'] =  'Ostatnie wejście';
+$lang['Hits'] = 'Wejść';
+$lang['GD library is missing'] = 'Brak biblioteki GD';
+$lang['conf_extents'] = 'Szablony';
+$lang['extend_for_templates'] = 'Rozszerz dla szablony';
+$lang['Replacement of original templates'] =
+ 'Zamienniki oryginalnych szablonów przez spersonalizowane szablony z katalogu template-extension';
+$lang['Replacers'] = 'Zamienniki (spersonalizowane szablony)';
+$lang['Original templates'] = 'Oryginalne szablony';
+$lang['Optional URL keyword'] = 'Opcjonalne słowo klucz dla URL';
+$lang['Templates recorded.'] = 'Konfiguracja szablonów została zapisana.';
+$lang['Optimizations completed'] = 'Wszystkie optymalizacje zakończone pomyślnie.';
+$lang['Optimizations errors'] = 'Optymalizacje zakończone z kilkoma błędami.';
+$lang['delete this comment'] = 'usuń ten komentarz';
+$lang['link_info_image'] = 'Modyfikuj informacje';
+$lang['edit category informations'] = 'edytuj informacje o kategorii';
+$lang['nothing'] = 'nic';
+$lang['overrides existing values with empty ones'] = 'nadpisuje istniejące wartości pustymi';
+$lang['manage image ranks'] = 'zarządzaj rankingami obrazów';
+$lang['Manage image ranks'] = 'Zarządzaj rankingami obrazów';
+$lang['Edit ranks'] = 'Edytuj rankingi';
+$lang['No element in this category'] = 'Brak elementów w tej kategorii';
+$lang['Images manual order was saved'] = 'Ręczne sortowanie obrazów zostało zapisane';
+$lang['ranks'] = 'rankingi';
+$lang['Drag to re-order'] = 'Przesuń aby zreorganizować';
+$lang['Unable to retrieve server informations since allow_url_fopen is disabled.'] = 'Nie można pobrać informacji o serwerze z powodu wyłączonego allow_url_fopen.';
+$lang['Quick Local Synchronization'] = 'Szybka synchronizacja lokalna';
+$lang['No photo can be deleted'] = 'Żadne zdjęcie nie zostało usunięte';
+$lang['Note: Only deletes photos added with pLoader'] = 'Info: Usuwa tylko zdjęcia dodane przez pLoader';
+$lang['Delete selected photos'] = 'Usuń zaznaczone zdjęcie';
+$lang['%d photo was deleted'] = '%d zdjęcie zostało usunięte';
+$lang['%d photos were deleted'] = '%d zdjęć zostało usuniętych';
+$lang['Bound template'] = 'Przypisz Szablon';
+/* TODO */ $lang['Downloads'] = 'Downloads';
+/* TODO */ $lang['Released on'] = 'Released on';
+/* TODO */ $lang['Number of downloads'] = 'Number of downloads';
+?>
Index: /tags/2.0.2/language/pl_PL/common.lang.php
===================================================================
--- /tags/2.0.2/language/pl_PL/common.lang.php	(revision 3278)
+++ /tags/2.0.2/language/pl_PL/common.lang.php	(revision 3278)
@@ -0,0 +1,368 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008      Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Langage informations
+//Polish translation by voyteckst (voyteckst@yahoo.com). You can edit them free and post corrections to Piwigo.
+$lang_info['language_name'] = 'Polish';
+$lang_info['country'] = 'Polska';
+$lang_info['direction'] = 'ltr';
+$lang_info['code'] = 'pl';
+$lang_info['zero_plural'] = true;
+$lang['%.2f (rated %d times, standard deviation = %.2f)'] = '%.2f (oceniane %d razy, standard deviation = %.2f)';
+$lang['%d Kb'] = '%d Kb';
+$lang['%d category updated'] = '%d kategoria zaktualizowana';
+$lang['%d categories updated'] = '%d zaktualizowanych kategorii';
+$lang['%d comment to validate'] = '%d komentarz do weryfikacji';
+$lang['%d comments to validate'] = '%d komentarzy do weryfikacji';
+$lang['%d new comment'] = '%d nowy komentarz';
+$lang['%d new comments'] = '%d nowe komentarze';
+$lang['%d comment'] = '%d komentarz';
+$lang['%d comments'] = '%d komentarzy';
+$lang['%d hit'] = '%d hit';
+$lang['%d hits'] = '%d hits';
+$lang['%d new element'] = '%d nowy element';
+$lang['%d new elements'] = '%d nowych elementów';
+$lang['%d new user'] = '%d nowy użytkownik';
+$lang['%d new users'] = '%d nowi użytkownicy';
+$lang['%d waiting element'] = '%d oczekujący element';
+$lang['%d waiting elements'] = '%d oczekujących elementów';
+$lang['About'] = 'O Piwigo';
+$lang['All tags must match'] = 'Wszystkie tagi musza pasować';
+$lang['All tags'] = 'Wszystkie tagi';
+$lang['Any tag'] = 'Dowolny tag';
+$lang['At least one listed rule must be satisfied.'] = 'At least one listed rule must be satisfied.';
+$lang['At least one tag must match'] = 'Przynajmniej jedentag musi pasować';
+$lang['Author'] = 'Autor';
+$lang['Average rate'] = 'Średnia ocena';
+$lang['Categories'] = 'Kategorie';
+$lang['Category'] = 'Kategoria';
+$lang['Close this window'] = 'Zamknij okno';
+$lang['Complete RSS feed'] = 'Kompletny RSS feed (zdjęcia, komentarze)';
+$lang['Confirm Password'] = 'Potwierdź hasło';
+$lang['Connection settings'] = 'Ustawienia połączenia';
+$lang['Connection'] = 'Logowanie';
+$lang['Contact webmaster'] = 'Kontakt z webmasterem';
+$lang['Create a new account'] = 'Utwórz nowe konto';
+$lang['Created on'] = 'Utworzone';
+$lang['Creation date'] = 'Data utworzenia';
+$lang['Current password is wrong'] = 'Złe hasło';
+$lang['Dimensions'] = 'Rozmiary';
+$lang['Display'] = 'Wyświetlanie';
+$lang['Each listed rule must be satisfied.'] = 'Each listed rule must be satisfied.';
+$lang['Email address is missing'] = 'Brak adresu email';
+$lang['Email address'] = 'Adres email';
+$lang['Enter your personnal informations'] = 'Wprowadź informacje';
+$lang['Error sending email'] = 'Błąd podczas wysyłania maila';
+$lang['File name'] = 'Nazwa pliku';
+$lang['File'] = 'Plik';
+$lang['Filesize'] = 'Rozmiar pliku';
+$lang['Filter and display'] = 'Filtrowanie i wyświetlanie';
+$lang['Filter'] = 'Filtr';
+$lang['Forgot your password?'] = 'Zapomniane hasło?';
+$lang['Go through the gallery as a visitor'] = 'Przejdź do galerii jako gość';
+$lang['Help'] = 'Pomoc';
+$lang['Identification'] = 'Logowanie';
+$lang['Image only RSS feed'] = 'RSS feed tylko dla zdjęć';
+$lang['Keyword'] = 'Keyword';
+$lang['Links'] = 'Linki';
+$lang['Mail address'] = 'Adres email';
+$lang['N/A'] = 'N/A';
+$lang['New on %s'] = 'Nowe %s';
+$lang['New password confirmation does not correspond'] = 'Potwierdzenie podczas potwierdzania nowego hasła';
+$lang['New password sent by email'] = 'Nowe hasło wysłane na pocztą email';
+$lang['No email address'] = 'Brak adresu email';
+$lang['No user matches this email address'] = 'Brak użytkwoników odpowiadających danemu adresowi email';
+$lang['Notification'] = 'Powiadamianie';
+$lang['Number of items'] = 'Liczba obiektów';
+$lang['Original dimensions'] = 'Original dimensions';
+$lang['Password forgotten'] = 'Zapomniane hasło';
+$lang['Password'] = 'Hasło';
+$lang['Post date'] = 'Data umieszczenia';
+$lang['Posted on'] = 'Data umieszczenia';
+$lang['Profile'] = 'Profil';
+$lang['Quick connect'] = 'Logowanie';
+$lang['RSS feed'] = 'RSS feed';
+$lang['Rate'] = 'Ocena';
+$lang['Register'] = 'Zarejestruj';
+$lang['Registration'] = 'Rejestracja';
+$lang['Related tags'] = 'Powiązane tagi';
+$lang['Reset'] = 'Resetuj';
+$lang['Retrieve password'] = 'Retrieve password';
+$lang['Search rules'] = 'Reguły wyszukiwania';
+$lang['Search tags'] = 'Szukaj tagów';
+$lang['Search'] = 'Szukaj';
+$lang['See available tags'] = 'Zobacz dostępne tagi';
+$lang['Send new password'] = 'Prześlij nowe hasło';
+$lang['Since'] = 'Od';
+$lang['Sort by'] = 'Sortuj po';
+$lang['Sort order'] = 'Sortowanie po';
+$lang['Tag'] = 'Tag';
+$lang['Tags'] = 'Tagi';
+$lang['The RSS notification feed provides notification on news from this website : new pictures, updated categories, new comments. Use a RSS feed reader.'] = 'The RSS notification feed provides notification on news from this website : new pictures, updated categories, new comments. Use a RSS feed reader.';
+$lang['Unknown feed identifier'] = 'Nieznany identyfikator feed';
+$lang['User comments'] = 'Komentarze użytkowników';
+$lang['Username'] = 'Użytkownik';
+$lang['Visits'] = 'Odwiedzin';
+$lang['Webmaster'] = 'Webmaster';
+$lang['Week %d'] = 'Tydzień %d';
+$lang['about_page_title'] = 'O Piwigo';
+$lang['access_forbiden'] = 'Nie masz uprawnień do oglądania tej strony';
+$lang['add to caddie'] = 'Dodaj do koszyka';
+$lang['add_favorites_hint'] = 'Dodaj zdjęcie do ulubionych';
+$lang['admin'] = 'Administracja';
+$lang['adviser_mode_enabled'] = 'Adviser mode enabled';
+$lang['all'] = 'wszystkie';
+$lang['ascending'] = 'rosnąco';
+$lang['author(s) : %s'] = 'Autor(-rzy) : %s';
+$lang['auto_expand'] = 'Rozwiń wszystkie kategorie';
+$lang['became available after %s (%s)'] = 'umieszczone po %s (%s)';
+$lang['became available before %s (%s)'] = 'umieszczone przed %s (%s)';
+$lang['became available between %s (%s) and %s (%s)'] = 'umieszczone pomiędzy %s (%s) i %s (%s)';
+$lang['became available on %s'] = 'umieszczone %s';
+$lang['best_rated_cat'] = 'Najlepiej oceniane';
+$lang['best_rated_cat_hint'] = 'wyświetl najlepiej oceniane obiekty';
+$lang['caddie'] = 'koszyk';
+$lang['calendar'] = 'Kalendarz';
+$lang['calendar_any'] = 'Wszystkie';
+$lang['calendar_hint'] = 'wyświetl każdy dzień ze zdjęciem, miesiąc po miesiącu';
+$lang['calendar_picture_hint'] = 'wyświetl zdjęcia dodane w ';
+$lang['calendar_view'] = 'Pokaż';
+$lang['chronology_monthly_calendar'] = 'Kalendarz miesięczny';
+$lang['chronology_monthly_list'] = 'Lista miesięczna';
+$lang['chronology_weekly_list'] = 'Lista tygodniowa';
+$lang['click_to_redirect'] = 'Kliknij jeżeli nie zostałeś przekierowany poprawnie';
+$lang['comment date'] = 'data komentarza';
+$lang['comment'] = 'Komentarz';
+$lang['comment_added'] = 'Twój komentarz został zapisany';
+$lang['comment_anti-flood'] = 'Anti-flood system : poczekaj chwilę aby wysłać nastepny komentarz';
+$lang['comment_not_added'] = 'Twój komentarz nie został zarejestrowany, ponieważ nie jest zgodny z regułami walidacji';
+$lang['comment_to_validate'] = 'Administrator musi zatwierdzić Twój komentarz zanim będzie on widoczny.';
+$lang['comment_user_exists'] = 'Ten login jest już używany przez innego użytkownika';
+$lang['comments'] = 'Komentarze';
+$lang['comments_add'] = 'Dodaj komentarz';
+$lang['created after %s (%s)'] = 'utworzone po %s (%s)';
+$lang['created before %s (%s)'] = 'utworzone przed %s (%s)';
+$lang['created between %s (%s) and %s (%s)'] = 'utworzone pomiędzy %s (%s) i %s (%s)';
+$lang['created on %s'] = 'utworzone %s';
+$lang['customize'] = 'Dostosuj';
+$lang['customize_page_title'] = 'Twoje dostosowanie ';
+$lang['day'][0] = 'Niedziela';
+$lang['day'][1] = 'Poniedziałek';
+$lang['day'][2] = 'Wtorek';
+$lang['day'][3] = 'Środa';
+$lang['day'][4] = 'Czwartek';
+$lang['day'][5] = 'Piątek';
+$lang['day'][6] = 'Sobota';
+$lang['default_sort'] = 'Domyślnie';
+$lang['del_favorites_hint'] = 'Usuń zdjęcie ze swoich ulubionych';
+$lang['delete'] = 'Usuń';
+$lang['descending'] = 'malejąco';
+$lang['download'] = 'Pobierz';
+$lang['download_hint'] = 'Pobierz ten plik';
+$lang['edit'] = 'edytuj';
+$lang['err_date'] = 'zła data';
+$lang['excluded'] = 'wykluczone';
+$lang['favorite_cat'] = 'Moje ulubione';
+$lang['favorite_cat_hint'] = 'pokaż moje ulubione zdjęcia';
+$lang['favorites'] = 'Ulubione';
+$lang['first_page'] = 'Pierwsza';
+$lang['gallery_locked_message'] = 'Galeria zablokowana w celach konserwacji. Wróć później.';
+$lang['generation_time'] = 'Strona wygenerowana w';
+$lang['guest'] = 'gość';
+$lang['hello'] = 'Witaj';
+$lang['hint_admin'] = 'dostępne tylko dla administratorów';
+$lang['hint_category'] = 'pokaż zdjęcia tylko dla głównej kategorii';
+$lang['hint_comments'] = 'Zobacz ostatnie komentarze';
+$lang['hint_customize'] = 'dostosuj wyglód galerii';
+$lang['hint_search'] = 'szukaj';
+$lang['home'] = 'Strona Główna';
+$lang['identification'] = 'Uprawnienia';
+$lang['images_available_cpl'] = 'w tej kategorii';
+$lang['images_available_cat'] = 'w %d podkategori';
+$lang['images_available_cats'] = 'w %d podkategoriach';
+$lang['included'] = 'zawarte';
+$lang['invalid_pwd'] = 'Złe hasło!';
+$lang['language']='Język';
+$lang['last %d days'] = 'ostatnich %d dni';
+$lang['last_page'] = 'Ostatnia';
+$lang['logout'] = 'Wyloguj';
+$lang['mail_address'] = 'Adres email';
+$lang['mandatory'] = 'obowiązkowe';
+$lang['maxheight'] = 'Maxymalna wysokość zdjęć';
+$lang['maxheight_error'] = 'Maxymalna wysokość musi być liczbą do 50';
+$lang['maxwidth'] = 'Maxymalna szerokość zdjęć';
+$lang['maxwidth_error'] = 'Maxymalna szerokość musi być liczbą do 50';
+$lang['mode_created_hint'] = 'wyświetla kalendarz po dacie utworzenia';
+$lang['mode_flat_hint'] = 'wyświetla wszystkie elementy we wszystkich podkategoriach';
+$lang['mode_normal_hint'] = 'powrót do normalnego widoku';
+$lang['mode_posted_hint'] = 'wyświetla kalendarz po dacie umieszczenia';
+$lang['month'][10] = 'Październik';
+$lang['month'][11] = 'Listopad';
+$lang['month'][12] = 'Grudzień';
+$lang['month'][1] = 'Styczeń';
+$lang['month'][2] = 'Luty';
+$lang['month'][3] = 'Marzec';
+$lang['month'][4] = 'Kwiecień';
+$lang['month'][5] = 'Maj';
+$lang['month'][6] = 'Czerwiec';
+$lang['month'][7] = 'Lipiec';
+$lang['month'][8] = 'Sierpień';
+$lang['month'][9] = 'Wrzesień';
+$lang['most_visited_cat'] = 'Najczęściej odwiedzane';
+$lang['most_visited_cat_hint'] = 'pokaż najczęściej odwiedzane zdjęcia';
+$lang['nb_image_line_error'] = 'Liczba zdjęć w wierszu musi być większa od zera';
+$lang['nb_image_per_row'] = 'Liczba zdjęć w wierszu';
+$lang['nb_line_page_error'] = 'Liczba wierszy na stronie musi być większa od zera';
+$lang['nb_row_per_page'] = 'Liczba wierszy na stronie';
+$lang['nbm_unknown_identifier'] = 'Nieznany identyfikator';
+$lang['new_password'] = 'Nowe hasło';
+$lang['new_rate'] = 'Oceń to zdjęcie';
+$lang['next_page'] = 'Następne';
+$lang['no_category'] = 'Strona główna';
+$lang['no_rate'] = 'nie oceniane';
+$lang['note_filter_day'] = 'Wyświetl elementy umieszczone w ciągu ostatniego %s dnia.';
+$lang['note_filter_days'] = 'Wyświetl elementy umieszczone w ciąu ostatnich %s dni.';
+$lang['password updated'] = 'hasło zmienione';
+$lang['periods_error'] = 'Okres czasu musi być liczbą dodatnią';
+$lang['picture'] = 'zdjęcie';
+$lang['picture_high'] = 'Wybierz zdjęcie aby je zobaczyć w większej rozdzielczości';
+$lang['picture_show_metadata'] = 'Pokaż metadane (EXIF)';
+$lang['powered_by'] = 'Powered by';
+$lang['preferences'] = 'Preferencje';
+$lang['previous_page'] = 'Poprzednia';
+$lang['random_cat'] = 'Losowe zdjęcia';
+$lang['random_cat_hint'] = 'wyświetla zbior losowych zdjęć';
+$lang['recent_cats_cat'] = 'Aktualne kategorie';
+$lang['recent_cats_cat_hint'] = 'wyświetla ostatnio uaktualnione kategorie';
+$lang['recent_period'] = 'Najnowszy okres';
+$lang['recent_pics_cat'] = 'Najnowsze zdjęcia';
+$lang['recent_pics_cat_hint'] = 'wyświetla najnowsze zdjęcia';
+$lang['redirect_msg'] = 'Przekierowywanie...';
+$lang['reg_err_login1'] = 'Wprowadź login';
+$lang['reg_err_login2'] = 'Login nie może posiadać spacji';
+$lang['reg_err_login3'] = 'Login nie moż się zaczynać od znaku specjalnego';
+$lang['reg_err_login5'] = 'ten login już istnieje';
+$lang['reg_err_mail_address'] = 'mail musi być w postaci xxx@yyy.eee (przykład : jack@altern.org)';
+$lang['reg_err_pass'] = 'wprowadź hasło jeszcze raz';
+$lang['remember_me'] = 'Pamiętaj mnie';
+$lang['remove this tag'] = 'usuń ten tag z listy';
+$lang['representative'] = 'reprezentant';
+$lang['return to homepage'] = 'powrót do strony głównej';
+$lang['search_author'] = 'Szukaj Autora';
+$lang['search_categories'] = 'Szukaj w Kategoriach';
+$lang['search_date'] = 'Szukaj po Dacie';
+$lang['search_date_from'] = 'Data od';
+$lang['search_date_to'] = 'Data do';
+$lang['search_date_type'] = 'Rodzaj daty';
+$lang['search_keywords'] = 'Szukaj słów';
+$lang['search_mode_and'] = 'Szukaj po wszystkim ';
+$lang['search_mode_or'] = 'Szukaj po wszystkim';
+$lang['search_one_clause_at_least'] = 'Puste zapytanie. Nie zostały wprowadzone żadne kryteria.';
+$lang['search_options'] = 'Opcje wyszukiwania';
+$lang['search_result'] = 'Wyniki wyszukiwania';
+$lang['search_subcats_included'] = 'Szukaj w podkategoriach';
+$lang['search_title'] = 'Szukaj';
+$lang['searched words : %s'] = 'szukane słowa : %s';
+$lang['send_mail'] = 'Kontakt';
+$lang['set as category representative'] = 'ustaw jako reprezentanta kategorii';
+$lang['show_nb_comments'] = 'Pokaż liczbę komentarzy';
+$lang['show_nb_hits'] = 'Pokaż liczbę wyświetleń';
+$lang['slideshow'] = 'pokaz zdjęć';
+$lang['slideshow_stop'] = 'zatrzymaj pokaz';
+$lang['special_categories'] = 'Specjalne';
+$lang['sql_queries_in'] = 'Zapytania SQL w';
+$lang['start_filter_hint'] = 'wyświetla tylko ostatnio umieszczone';
+$lang['stop_filter_hint'] = 'powrót do wyświetlania wszystkich elementów';
+$lang['the beginning'] = 'poczatek';
+$lang['theme'] = 'Styl interfejsu';
+$lang['thumbnails'] = 'Miniatury';
+$lang['title_menu'] = 'Menu';
+$lang['title_send_mail'] = 'Komentarz do Twojej strony';
+$lang['today'] = 'dzisiaj';
+$lang['update_rate'] = 'Aktualizuj Twoją ocenę';
+$lang['update_wrong_dirname'] = 'zła nazwa pliku';
+$lang['upload_advise_filesize'] = 'rozmiar zdjęcia nie może przekraczać : ';
+$lang['upload_advise_filetype'] = 'zdjęcia muszą być w formacie jpg, gif lub png';
+$lang['upload_advise_height'] = 'wysokość zdjęcia nie może przekraczać : ';
+$lang['upload_advise_thumbnail'] = 'Opcjonalne, ale zalecane : wybierz miniaturę do powiązania z ';
+$lang['upload_advise_width'] = 'szerokość zdjęcia nie może przekraczać : ';
+$lang['upload_author'] = 'Autor (np. "Pierrick LE GALL")';
+$lang['upload_cannot_upload'] = 'nie można wgrać zdjęcia na serwer';
+$lang['upload_err_username'] = 'nazwa użytkonika musi być podana';
+$lang['upload_file_exists'] = 'Nazwa zdjęcia już wykorzystana';
+$lang['upload_filenotfound'] = 'Musisz wybrać format pliku dla zdjęcia';
+$lang['upload_forbidden'] = 'Nie moćesz wgrywać zdjęć do tej kategorii';
+$lang['upload_name'] = 'Nazwa zdjęcia';
+$lang['upload_picture'] = 'Wgraj zdjęcie';
+$lang['upload_successful'] = 'Zdjęcie wgrane pomyślnie. Zostanie zaakceptowane przez administratora tak szybko jak to możliwe';
+$lang['upload_title'] = 'Wgraj zdjęcie';
+$lang['useful when password forgotten'] = 'przydatne gdy zostanie zapomniane hasło';
+$lang['qsearch'] = 'Szybkie wyszukiwanie';
+$lang['Connected user: %s'] = 'Zalogowany użytkownik: %s';
+$lang['IP: %s'] = 'IP: %s';
+$lang['Browser: %s'] = 'Przeglądarka: %s';
+$lang['Author: %s'] = 'Autor: %s';
+$lang['Comment: %s'] = 'Komentarz: %s';
+$lang['Delete: %s'] = 'Usuń: %s';
+$lang['Validate: %s'] = 'Akceptuj: %s';
+$lang['Comment by %s'] = 'Komentarz wystawiony przez %s';
+$lang['User: %s'] = 'Użytkownik: %s';
+$lang['Email: %s'] = 'Email: %s';
+$lang['Admin: %s'] = 'Admin: %s';
+$lang['Registration of %s'] = 'Rejestracja %s';
+$lang['Category: %s'] = 'Kategoria: %s';
+$lang['Picture name: %s'] = 'Nazwa zdjęcia: %s';
+$lang['Creation date: %s'] = 'Data utworzenia: %s';
+$lang['Waiting page: %s'] = 'Strona oczekująca: %s';
+$lang['Picture uploaded by %s'] = 'Zdjęcie wgrane przez %s';
+// --------- Starting below: New or revised $lang ---- from version 1.7.1
+$lang['guest_must_be_guest'] = 'Zły status dla użytkownika "gość", używam domyślnego';
+// --------- Starting below: New or revised $lang ---- from Butterfly (2.0)
+$lang['Administrator, webmaster and special user cannot use this method'] = 'Administrator, webmaster i special user nie mogą uzywać tej metody';
+$lang['reg_err_mail_address_dbl'] = 'użytkownik już używa tego adresu email';
+$lang['Category results for'] = 'Wyniki kategorii dla';
+$lang['Tag results for'] = 'Wyniki tagów dla';
+$lang['from %s to %s'] = 'od %s do %s';
+$lang['start_play'] = 'Odtwórz jako slideshow';
+$lang['stop_play'] = 'Pause pokazu';
+$lang['start_repeat'] = 'Powtarzaj slideshow';
+$lang['stop_repeat'] = 'Nie powtarzaj slideshow';
+$lang['inc_period'] = 'Zmniejsz prędkość diaporamy';
+$lang['dec_period'] = 'Zwiększ prędkość diaporamy';
+$lang['Submit'] = 'Wyślij';
+$lang['Yes'] = 'Tak';
+$lang['No'] = 'Nie';
+$lang['%d element']='%d obraz';
+$lang['%d elements']='%d obrazów';
+$lang['%d element are also linked to current tags'] = '%d image is also linked to current tags';
+$lang['%d elements are also linked to current tags'] = '%d images are also linked to current tags';
+$lang['See elements linked to this tag only'] = 'See images linked to this tag only';
+$lang['elements posted during the last %d days'] = 'obrazy wgrane przez ostatnich %d dni';
+$lang['Choose an image'] = 'Wybierz obraz';
+$lang['Piwigo Help'] = 'Piwigo Pomoc';
+$lang['Rank'] = 'Ranking';
+$lang['group by letters'] = 'grupuj literami';
+$lang['letters'] = 'litery';
+$lang['show tag cloud'] = 'pokazuj tag jako chmurkę';
+$lang['cloud'] = 'chmurka';
+?>
Index: /tags/2.0.2/language/pl_PL/help.html
===================================================================
--- /tags/2.0.2/language/pl_PL/help.html	(revision 3278)
+++ /tags/2.0.2/language/pl_PL/help.html	(revision 3278)
@@ -0,0 +1,297 @@
+<div class="instructions">
+<h2>Pomoc</h2>
+
+<div id="instructionPLoader" class="instructionBlock">
+  <div
+    id="pLoader_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('pLoader_header', 'pLoader_content')"
+  ><span>
+    Dodaj zdjęcia z wykorzystaniem aplikacji pLoader
+  </span></div>
+  <div
+    id="pLoader_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+			<p><a href="http://piwigo.org/ext/extension_view.php?eid=270">pLoader dla Windows</a> or <a href="http://piwigo.org/ext/extension_view.php?eid=269">pLoader dla Linux</a> : opis, pobieranie oraz szczegóły o nowych wersjach.</p>
+    <ol>
+      <li>W miejscu gdzie zainstalowałeś Piwigo, utwórz katalog "upload" obok katalogu "galleries", z włączonymi prawami do zapisu.</li>
+      <li>Zainstaluj na komputerze aplikację pLoader, uruchom, a następnie uzupełnij odpowiednio dane połączenia do Twojej galerii : adres URL, nazwę użytkownika i hasło.</li>
+      <li>"Przeciągnij i upuść" obrazy do aplikacji pLoader w sekcji zdjęcia.</li>
+      <li>Utwórz kategorię, a następnie ją zaznacz.</li>
+      <li>Wybierz zdjęcia.</li>
+      <li>Kliknij w przycisk z zieloną strzałką, aby wgrać zdjęcia do galerii</li>
+    </ol>
+Gratulacje! Stworzyłeś pierwszą kategorię w swojej galerii.
+  </div> <!-- pLoader_content -->
+</div> <!-- instructionPLoader -->
+
+<div id="instructionFTP" class="instructionBlock">
+  <div
+    id="FTP_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('FTP_header', 'FTP_content')"
+  ><span>
+    Dodaj obrazy za pomocą FTP
+  </span></div>
+  <div
+    id="FTP_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+
+<h3>Szybki start</h3>
+
+<ol>
+  <li>Utwórz katalog lokalny na swoim komputerze.</li>
+
+  <li>Skopiuj zdjęcia do tego katalogu (zmień ich rozmiar na potrzeby galerii). <em>Uwaga</em>: naawy katalogów oraz plików mogą zawierać tylko litery, cyfry oraz znaki "-", "_" lub ".". Ne mogą zawierać znaku spacji lub akcentowania.</li></li>
+
+  <li>Za pomocą klienta FTP skopiuj katalog katalogu "galleries".</li>
+
+ <li>Zaloguj się do galerii i przejdź do <span class="pwgScreen">Administracja &raquo; Obrazy &raquo; Miniatury</span> aby stworzyć brakujące miniatury.</li>
+
+  <li>Przejdź do <span class="pwgScreen">Administracja</span> i wybierz duży przycisk Synchronizacja.</li>
+  
+</ol>
+Gratulacje! Stworzyłeś pierwszą kategorię w swojej galerii.
+
+<h3>Struktura katalogów i plików</h3>
+<ul>
+
+  <li>
+
+    <p>W Piwigo katalogi kategorii znajdują sięwewnątrz katalogu
+    "galleries". Poniżej mozna zobaczyć drzewo niewielkiej galerii (ale wykorzystującej wiele funkcji) :</p>
+
+    <pre>
+.
+|-- admin
+|-- doc
+|-- galleries
+|   |-- category-1
+|   |   |-- category-1.1
+|   |   |   |-- category-1.1.1
+|   |   |   |   |-- category-1.1.1.1
+|   |   |   |   |   |-- pwg_high
+|   |   |   |   |   |   +-- wedding.jpg
+|   |   |   |   |   |-- thumbnail
+|   |   |   |   |   |   +-- TN-wedding.jpg
+|   |   |   |   |   +-- wedding.jpg
+|   |   |   |   +-- category-1.1.1.2
+|   |   |   +-- category-1.1.2
+|   |   |-- category-1.2
+|   |   |   |-- pookie.jpg
+|   |   |   +-- thumbnail
+|   |   |       +-- TN-pookie.jpg
+|   |   +-- category-1.3
+|   +-- category-2
+|       |-- piglet.gif
+|       |-- pwg_representative
+|       |   +-- video.jpg
+|       |-- thumbnail
+|       |   +-- TN-piglet.jpg
+|       +-- video.avi
+|-- include
+|-- install
+|-- language
+|-- template
++-- tool</pre>
+
+  </li>
+  
+  <li>Każdy podkatalog w katalogu "galleries" tworzy kategorię. Nie ma limitu na poziomy zagłębień katalogów.</li>
+
+  <li>Ogólnie element jest reprezentowany przez plik. Plik może być elementem Piwigo jeżeli
+  jego rozszerzenie jest zawarte w parametrze <code>file_ext</code> (plik <span
+  class="filename">include/config_default.inc.php</span>). Plik może być obrazem jeżeli jego rozszerzenie jest zawarte w parametrze<code>picture_ext</code>
+.</li>
+
+  <li>Obrazy muszą mieć powiązane z nimi miniatury (patrze sekcja miniatury poniżej)</li>
+
+  <li>Obrazy mogą mieć odpowiadające im pliki wysokiej rozdzielczości. Jak np
+  dla zdjęcia wedding.jpg w przykładzie powyżej. Dla obrazów wysokiej jakości nie jest wymagany żaden prefix.</li>
+
+  <li>Elementy nie będące obrazami (video, dźwięki, pliki tekstowe, cokolwiek zechcesz...) są domyślnie reprezentowane jako ikona powiązana z danym plikiem. Opcjonalnie możesz powiązać miniaturę i plik reprezentujący (zobacz video.avi w przykładzie powyżej).</li>
+
+  <li><em>Ostrzeżenie</em> : nazwy plików oraz katalogów muszą składać się wyłącznie z
+liter cyfr, znaków "-", "_" lub ".". Nie mogą zawierać spacji oraz pozostałych znaków.</li>
+
+  <li>Po umieszczeniu plików, miniatur oraz reprezentanów, przejdź do : <span class="pwgScreen">Administracja &raquo; Kategorie &raquo;
+  Synchronizacja</span></li>
+
+</ul>
+
+<h3>Miniatury</h3>
+<ul>
+
+  <li>Tak jak wspomniano wcześniej każdy element typu obraz musi posiadać swoją miniaturę.</li>
+
+  <li>Miniatury są zapisywane w podkatalogu "thumbnail" danej kategorii. Miniatura jest obrazem o takiej samej nazwie pliku jak jak dany obraz i posiada prefix <em>TN-</em>.</li>
+
+  <li><em>Rada</em>: do tworzenia miniatur używaj zewnętrznego modułu.</li>
+
+  <li>Do tworzenia miniatur możesz także wykorzystać stronę do ich tworzenia <span
+  class="pwgScreen">Administracja &raquo; Obrazy &raquo; Miniatury</span> , natomiast nie jest to zalecane, ze względu na to, że jakość miniatur może być kiepska oraz jest wysokie wykorzystanie procesora.</li>
+
+  <li>Musisz dać prawa zapisu na katalogach i podkatalogach kategorii</li>
+
+</ul>
+
+  </div> <!-- FTP_content -->
+</div> <!-- instructionFTP -->
+
+<div id="instructionPermissions" class="instructionBlock">
+  <div
+    id="permissions_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('permissions_header', 'permissions_content')"
+  ><span>
+    Uprawnienia
+  </span></div>
+  <div
+    id="permissions_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+<ul>
+
+  <li>Do poszczególnych kategorii można zabronić dostępu. Kategorie mogą być "publiczne" lub
+  "prywatne". Uprawnienia (dla grup i użytkowników) mogą być ustawione tylko dla kategorii "prywatnych".</li>
+
+  <li>Możesz ustawić kategorię jako "prywatna" dla pojedynczej kategorii (<span
+  class="pwgScreen">Administracja &raquo; Kategorie &raquo; Zarządzaj &raquo; edycja</span>) lub przez ustawienie opcji dla całego drzewa (<span
+  class="pwgScreen">Administracja &raquo; Kategories &raquo; Właściwości &raquo; Publiczna / Prywatna</span>).</li>
+
+  <li>
+
+    <p>Po ustawieniu kateogrii kako prywatna, możesz zarządzać uprawnieniami dla grup i użytkowników przy pomocy następujących 3 ekranów :</p>
+
+    <ul>
+
+      <li><span class="pwgScreen">Administracja &raquo; Uprawnienia &raquo; Użytkownicy &raquo;
+      akcja uprawnienia</span> (jeden link per użytkownik)</li>
+
+      <li><span class="pwgScreen">Administracja &raquo; Uprawnienia &raquo; Grupy &raquo;
+      akcja uprawnienia</span> (jeden link per grupa)</li>
+
+      <li><span class="pwgScreen">Administracja &raquo; Kategorie &raquo; Zarządzaj &raquo; akcja edycja
+      uprawnień kategorii</span> (jeden link per kategoria)</li>
+
+    </ul>
+
+  </li>
+
+</ul>
+  </div> <!-- permissions_content --> 
+</div> <!-- instructionPermissions -->
+
+<div id="instructionGroups" class="instructionBlock">
+  <div
+    id="groups_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('groups_header', 'groups_content')"
+  ><span>
+    Grupy
+  </span></div>
+  <div
+    id="groups_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+<ul>
+
+  <li>Grupy są dobrym sposobem do zarządzania uprawnieniami dla okreslonej listy użytkowników.</li>
+
+  <li>Możesz tworzyć grupy w <span class="pwgScreen">Administracja &raquo;
+  Uprawnienia &raquo; Grupy</span> i przypisywać użytkowników do tych grup w <span
+  class="pwgScreen">Administracja &raquo; Uprawnienia &raquo; Użytkownicy</span>.</li>
+
+  <li>Użytkownik może należeć do wielu grup. Przyznanie dostępu jest ważniejsze niż zabronienie : jezeli użytkownik "jack" należy do grup "family" i "friends", i tylko grupa "family" może oglądać kategorię "Christmas 2003",
+  "jack" będzie mógł oglądać kategorię "Christmas 2003".</li>
+
+</ul>
+  </div> <!-- groups_content --> 
+</div> <!-- instructionGroups -->
+
+<div id="instructionUpload" class="instructionBlock">
+  <div
+    id="upload_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('upload_header', 'upload_content')"
+  ><span>
+    Upload plików przez użytkowników
+  </span></div>
+  <div
+    id="upload_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+<p>Piwigo oferuje mozliwość wgrywania plików przez użytkowników..</p>
+
+<ol>
+
+  <li>Aby włączyć upload na kategorii (<span
+  class="pwgScreen">Administracja &raquo; Kategorie &raquo; Zarządzaj &raquo; edit</span> or <span
+  class="pwgScreen">Administracja &raquo; Kategorie &raquo; Properties &raquo; Upload</span>). Nie ma możliwości wgrywania plików do kategorii wirtualnych.</li>
+
+  <li>Musisz nadać uprawnienia do zapisu na odpowiednich katalogach.</li>
+
+</ol>
+
+<p>Pliki wgrane przez użytkowników nie są od razu widoczne na stronie, ale oczekują na zatwierdzenie przez administratora. W tym celu, administrator musi przejść do <span class="pwgScreen">Administracja &raquo; Obrazy &raquo; Oczekujące</span>.</p>
+  </div> <!-- upload_content --> 
+</div> <!-- instructionUpload -->
+
+<div id="instructionCategoryLinks" class="instructionBlock">
+  <div
+    id="categoryLinks_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('categoryLinks_header', 'categoryLinks_content')"
+  ><span>
+    Linki pomiędzy elementami, kategoriami oraz wirtualnymi kategoriami
+  </span></div>
+  <div
+    id="categoryLinks_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+<ul>
+
+  <li>Zdjęcia są wyświetlane w kategoriach odpowiadających katalogom, w których dane pliki się znajdują.</li>
+
+  <li>Możesz także wyświetlać zdjęcia w wielu kategoriach bez duplikowania plików na serwerze www. By podlinkowac link do kategorii, wystarczy utworzyć powiązanie na stronie edycji zdjęcia (do której ma dostęp każdy administrator ze strony danego zdjęcia w galerii).</li>
+
+  <li>Kategorie wirtualne bazują na nastepującym założeniu : nie mają odpowiadających katalogów. Kategorię wirtualną możesz stworzyć w <span class="pwgScreen">Administracja &raquo; Kategorie &raquo; Zarządzaj</span>.</li>
+
+</ul>
+  </div> <!-- categoryLinks_content --> 
+</div> <!-- instructionCategoryLinks -->
+
+<div id="instructionMisc" class="instructionBlock">
+  <div
+    id="misc_header"
+    class="instructionBlockHeaderCollapsed"
+    onclick="blockToggleDisplay('misc_header', 'misc_content')"
+  ><span>
+    Informacje różne
+  </span></div>
+  <div
+    id="misc_content"
+    class="instructionBlockContent"
+    style="display:none"
+  >
+<ul>
+
+  <li>ak tylko utworzysz galerię, zmień domyślne wyświetlanie w <span class="pwgScreen">Administracja &raquo; Konfigracja &raquo;
+  Domyślne</span>. Jeżeli tak zrobisz każdy nowy użytkownik będzie miał taki sam domyślny wygląd stron galerii.</li>
+
+  <li>Jeżeli masz pytania, społeczność Piwigo zaprasza Cię na forum <a
+  href="http://forum.phpwebgallery.net"></a>.</li>
+
+</ul>
+  </div> <!-- misc_content --> 
+</div> <!-- instructionMisc -->
+
+</div>
Index: /tags/2.0.2/language/pl_PL/help/advanced_feature.html
===================================================================
--- /tags/2.0.2/language/pl_PL/help/advanced_feature.html	(revision 3278)
+++ /tags/2.0.2/language/pl_PL/help/advanced_feature.html	(revision 3278)
@@ -0,0 +1,16 @@
+<h2>Zaawansowane</h2>
+
+<p>Lista specjalnych funkcjonalności dla zaawansowanego administratora PWG:</p>
+
+<ul>
+
+  <li>
+    <strong>Nie powiązane elementy:</strong>
+    Wyświetla obrazy, któe nie są powiązane z żadną wirtualną kategorią.
+  </li>
+  <li>
+    <strong>Pliki o tej samej nazwie w jednej lub wielu kategoriach:</strong>
+    Wyświtla obrazy lub pliki o tej samej nazwie znalezione w jednej lub wielu kategoriach.
+  </li>
+
+</ul>
Index: /tags/2.0.2/language/pl_PL/help/cat_modify.html
===================================================================
--- /tags/2.0.2/language/pl_PL/help/cat_modify.html	(revision 3278)
+++ /tags/2.0.2/language/pl_PL/help/cat_modify.html	(revision 3278)
@@ -0,0 +1,118 @@
+<h2>Edycja kategorii</h2>
+
+<h3>Informacje</h3>
+
+<ul>
+
+  <li><strong>nazwa</strong>: zmień nazwę kategorii (wirtualna zmiana nazwy dla fizycznie istniejącej kategorii).</li>
+
+  <li><strong>opis</strong>: daje ogólny obraz zawartości,
+  ten tekst będzie wyświetlany pod stroną miniaturami.</li>
+
+</ul>
+
+<h3>Przenieś</h3>
+
+<p>Jeżeli dana kategoria jest wirtualna, to można ją przenieść. Przeniesienie kategorii oznacza zmianę kategorii nadrzędnej.</p>
+
+<h3>Opcje</h3>
+
+<ul>
+
+  <li><strong>Typ dostępu</strong>: Zarządzanie uprawnieniami. Jeżeli ustawisz kategorię jako prywatną, to wszystkie jej podkategorie będą prywatne. Jeżeli ustawisz kategorię jako publiczną, to wszystkie jej podkategorie będą publiczne.</li>
+
+  <li><strong>Blokada</strong>: Kategoria i podkategorie są tymczasowo zablokowane na czas prac konserwacyjnych.</li>
+
+  <li><strong>Komentarze</strong>: Zautoryzowani użytkownicy mogą dodawać komentarze doelementów kategorii.</li>
+
+  <li><strong>Autoryzuj upload</strong>: Zautoryzowani użytkownicy mogą wgrywać pliki. Ta opcja jest możliwa tylko dla kategorii fizyczniej (nie wirtualnej).</li>
+
+</ul>
+
+<p>Możesz także zarządzać tymi opcjami poprzez ekran "Właściwości"
+(ekrany <span class="pwgScreen">Upload</span>, <span
+class="pwgScreen">Komentarze</span>, <span class="pwgScreen">Blokada</span>,
+<span class="pwgScreen">Publiczny/Prywatny</span>, <span
+class="pwgScreen">Reprezentacyjny</span> dostępne z <span
+class="pwgScreen">Administracja, Kategorie, Właściwości</span>).</p>
+
+<h3>Kolejnośćsortowania</h3>
+
+<p>Wybierz czy ma być sortowanie domyślne.</p>
+
+<p>Oznacza, że sortowanie będzie także dla podkategorii.</p>
+
+<p>Wybierz okreslony rodzaj sortowania dla kategorii.</p>
+<ul>
+<li><strong>Data utworzenia</strong>: Data utworzenia obrazu</li>
+<li><strong>Data wysłania</strong>: Data synchronizacji</li>
+<li><strong>Średnie oceny (*)</strong>: Średnie oceny mogą zostać zmienione przez odwiedzających</li>
+<li><strong>Najczęściej odwiedzane (*)</strong>: Aktualne odwiedziny zmieniają kolejność najczęściej odwiedzanych</li>
+<li><strong>Nazwa pliku</strong>: Nazwa nada w informacji o pliku</li>
+<li><strong>Id</strong>: Wewnętrzne Id (aktualnie wgrane elementy mają wyższe niż wgrane poprzednio).</li>
+
+</ul>
+<p><strong>(*)</strong>Przetestuj sam ponieważ opcja ma nieprzewidzialne rezultaty.</p>
+
+
+<h3>Reprezentant</h3>
+
+<p>Reprezantant kategorii to miniatura, która jest wyświetlana na stronie głównej kategorii (<span class="pwgScreen">category.php</span>) jeżeli kategoria zawiera podkategorie (w tym przypadku tylko głównej kategorii).</p>
+
+<p>Są 4 sposoby ustawienia reprezentanta kategorii :</p>
+
+<ul>
+
+  <li><span class="pwgScreen">Strona obrazy</span>: w pasku przycisków akcji,
+  jeden z nich pozwoli ustawić Ci reprezentanta danej kategorii. Przycisk ten ejst dostępny dla administratorów.</li>
+
+  <li><span class="pwgScreen">Edycja informacji o obrazie</span> w panelu administracyjnym. Ekran ten jest dostępny z poziomu <span
+  class="pwgScreen">picture.php</span> lub <span class="pwgScreen">Zarządzanie batch</span> w <em>trybie jednostkowym</em>. Aby dowiedzić się więcej zobacz pomoc dlatego ekranu.</li>
+
+  <li><span class="pwgScreen">Administracja, Kategorie, Właściwości,
+  Reprezentujący</span>. Aby dowiedzić się więcej zobacz pomoc dlatego ekranu.</li>
+
+  <li><span class="pwgScreen">Edycja kategorii</span> (ten ekran).</li>
+
+</ul>
+
+<p>Reprezentacja zależy od ustawienia parametru konfiguracyjnego
+<code>allow_random_representative</code> (zobacz <span
+class="filename">include/config_default.inc.php</span>).</p>
+
+<p>W trybie domyślnym (<code>allow_random_representative</code> jest ustawiony na false)
+każda kategoria zawiera jeden element ustawiony jako ją reprezentujący. Raz ustawiony (przy tworzeniu kategorii), reprezentant może zostać zmieniony tylko przez administratora. Jeżeli dany obrac nie odpowiada Ci jako reprezentujący kategorię,
+możesz wybrać <strong>Znajdź reprezentanta losowo</strong>.</p>
+
+<p>Jeżeli natomiast parametr konfiguracyjny <code>allow_random_representative</code> ma wartość true, kategoria zwierająca elementy nie może mieć ustawionego jednego reprezentanta. Wtedy wystarczy użyć przycisku <strong>Usuń reprezentanta</strong> .</p>
+
+<p>JEżeli kategoria nie zawiera żacnych elementów (a tylko podkategorie) może być wtedy reprezentowana dzięki ekranowi <span class="pwgScreen">Edytuj informacje o obrazie</span>. JEdyną dostepną opcją na aktualnym ekranie jest przycisk <strong>Usuń reprezentanta</strong> . P wybraniu przycisku nie ma już możliwości wybrania nowego reprezentanta.</p>
+
+<h3>Podpięcie wszystkich elementów kategorii do nowej kategorii</h3>
+
+<ul>
+
+<li><strong>Nazwa wirtualnej kategorii</strong>: Nazwa nowo tworzonej kategorii, 
+do której będą podpięte wszystkie elementy bieżącej kategorii.</li>
+
+<li><strong>Kategoria nadrzędna</strong>: Zostaw pole puste jeżeli kategoria ma być stworzona w głównej kategorii.</li>
+
+</ul>
+
+<h3>Podpięcie wszystkich elementów kategorii do którejś z istniejących kategorii</h3>
+
+<ul>
+
+<li><strong>Kategorie</strong>: Wybierz kategorię docelową.</li>
+
+</ul>
+
+<h3>Wyślij maila informacyjnego do wszystkich członków grupy</h3>
+
+<ul>
+
+<li><strong>Grupa</strong>: adresy grup</li>
+
+<li><strong>Treść wiadomości</strong>: Dowolny tekst do wpisania.</li>
+
+</ul>  
Index: /tags/2.0.2/language/pl_PL/help/cat_move.html
===================================================================
--- /tags/2.0.2/language/pl_PL/help/cat_move.html	(revision 3278)
+++ /tags/2.0.2/language/pl_PL/help/cat_move.html	(revision 3278)
@@ -0,0 +1,14 @@
+<h2>Przenoszenie kategorii wirtualnych</h2>
+
+<p>Tylko wirtualne kategorie mogą mieć nową kategorię nadrzędną.</p>
+
+<h3>Wirtualne kategorie do przeniesienia</h3>
+
+<p>Wybierz dowolną wirtualną kategorię, którą chcesz przenieść. 
+Jeżeli lista jest pusta, to oznacza, że żadnej nie stworzyłeś.</p>
+
+<h3>Nowa kategoria nadrzędna</h3>
+
+<p>Wybierz nową kategorię nadrzędną (wirtualną lub fizyczną). 
+Jeżeli nie wybierzesz żadnej wirtualnej kategorie zostaną przeniesione do głównej kategorii nadrzędnej.
+Nie można przenieść kategorii do własnej podkategorii.</p>
Index: /tags/2.0.2/language/pl_PL/help/cat_options.html
===================================================================
--- /tags/2.0.2/language/pl_PL/help/cat_options.html	(revision 3278)
+++ /tags/2.0.2/language/pl_PL/help/cat_options.html	(revision 3278)
@@ -0,0 +1,27 @@
+<h2>Opcje kategorii</h2>
+
+<p>Ekran umożliwia administratorowi zmianę opcji dla wielu kategorii jednocześnie.</p>
+
+<dl>
+
+  <dt>Upload</dt>
+  <dd>Umożliwia odwiedzającym wgrywanie plików do kategorii. Wyświetlone są tylko kategorie nie będące wirtualnymi</dd>
+
+  <dt>Komentarze</dt>
+  <dd>Zezwala użytkownikom na dodawanie komentarzy w wybranych kategoriach.
+Wybiera kategorie, które mają już tę opcję włączoną. Obraz może być komentowany wtedy jeżeli kategoria ma tę opcję włączoną.</dd>
+
+  <dt>Zablokuj</dt>
+  <dd>Umożliwia zablokowanie wybranych kategorii np. w ramach prac prowadzonych nad daną kategorią. 
+  Jeżeli zablokujesz kategorę, zablokowane również zostaną wszystkie jej podkategorie. Podobnie jeżeli odblokujesz kategorię, wszystkie jej podkategorie zostaną odblokowane.</dd>
+
+  <dt>Publiczne / Prywatne</dt>
+  <dd>Zarządza autoryzacją wo wybranych kategorii. Wybrane kategorie są prywatne : aby użytkownicy mieli dostep do tych kategorii, będzie trzeba przyznać uprawnienia do tych kategorii grupom/użytkownikom. Jeżeli ustawisz daną kategori jako prywatną, wtedy wszystkie jej podkategorie także będą prywatne. Analogicznie, jeżeli ustawisz daną kategorią jako publiczną, wszystkie jej podkategorie będą publiczne</dd>
+
+  <dt>Reprezentant</dt>
+  <dd>Opcja jest dostępna tylko wtedy jeżeli masz skonfigurowany parametr
+  <code>allow_random_representative</code> (zobacz <span
+  class="filename">include/config_defaults.inc.php</span>) na
+  <em>true</em>. Każda kategoria może mieć reprezentanta losowego lub ustawionego (unikalny obraz).</dd>
+
+</dl>
Index: /tags/2.0.2/language/pl_PL/help/cat_perm.html
===================================================================
--- /tags/2.0.2/language/pl_PL/help/cat_perm.html	(revision 3278)
+++ /tags/2.0.2/language/pl_PL/help/cat_perm.html	(revision 3278)
@@ -0,0 +1,11 @@
+<h2>Zarządzanie uprawnieniami dla kategorii</h2>
+
+<p>Ekran ten jest dostępny tylko dla kategorii prywatnych. Możesz tutaj wybrać grupy oraz użytkowników, którzy będą posiadali dostęp do danej kategorii.</p>
+
+<h3>Grupy</h3>
+
+<p>Dla bieżącej kategorii możesz przyznać uprawnienia lub zabronić dostępu. Modyfikując grupy, zmodyfikujesz użytkowników, którzy dzięki przynależności do tych grup mają lub nie dostęp do danej kategorii.</p>
+
+<h3>Użytkownicy</h3>
+
+<p>Możesz także przyznać uprawnienia lub zabronić dostępu. Użytkownicy posiadający dostęp dzięki przynależności do grupy, mogą w tym miejscu mieć ten dostęp odebrany.</p>
Index: /tags/2.0.2/language/pl_PL/help/configuration.html
===================================================================
--- /tags/2.0.2/language/pl_PL/help/configuration.html	(revision 3278)
+++ /tags/2.0.2/language/pl_PL/help/configuration.html	(revision 3278)
@@ -0,0 +1,109 @@
+<h2>Konfiguracja</h2>
+
+<p>Ekran umożliwia administratorom podstawową administrację. Pomimo małej ilości parametrów konfiguracyjnych, powinna ona być wystarczająca dla większości administratorów. Jeżeli chciałbyś zmienić więcej parametrów zajrzyj do pliku <span
+class="filename">include/config_default.inc.php</span>.</p>
+
+<p>Ekran jest podzielony na sekcje grupujące parametry tematycznie.</p>
+
+
+<h3>Główna</h3>
+<ul>
+  <li><strong>Tytuł galerii</strong>: używany w RSS oraz powiadomieniach mailowych.</li>
+
+  <li><strong>Baner strony</strong>: wyświetlany na górze kazdej strony.</li>
+
+  <li><strong>Adres URL galerii</strong>: wykorzystywany w RSS.</li>
+
+  <li><strong>Blokada galerii</strong>: Blokuje całą galerię do celów serwisowych. Tylko użytkownicy posiadający uprawnienia administracyjne będą mogli korzystać z galerii.</li>
+
+  <li><strong>Oceny</strong>: Włączone oceny obrazów.</li>
+
+  <li><strong>Oceny przez gości</strong>: Opcja umożliwiająca oceny obrazów także przez niezalogowanych użytkowników.</li>
+
+  <li><strong>Zezwól na rejestrację użytkowników</strong>: Pozwala na rejestrację użytkowników w galerii.</li>
+
+  <li><strong>Adres email jest obowiązkowy dla wszystkich użytkowników</strong>: Adres email będzie sprawdzany podczas rejestracji lub podczas aktualizacji profilu (jezeli akcja jest wykonywana przez administratora).</li>
+
+  <li><strong>Wyslij wiadomość do administratora gdy zarejestruje się nowy użytkownik </strong>: Administrator będzie powiadamiany o każdej rejestracji nowego użytkownika.</li>
+
+</ul>
+
+<h3>Historia</h3>
+
+  <p>Odwiedziny na stronach <span
+  class="pwgScreen">category.php</span> i <span
+  class="pwgScreen">picture.php</span> będą zapisane w tabeli
+  <code>historia</code> .</p>
+  
+  <p>Odwiedziny będą wyświetlane w <span
+  class="pwgScreen">Administracja, Specjalne, Historia</span>.</p>
+
+<ul>
+  <li><strong>Zapisuj odwiedziny strony przez  gości</strong>: zapisywane będą odwiedziny niezalogowanych użytkowników.</li>
+
+  <li><strong>Zapisuj odwiedziny strony przez  użytkowników</strong>: zapisywane będą odwiedziny zarejestrowanych użytkowników.</li>
+
+  <li><strong>Zapisuj odwiedziny strony przez administratorów</strong>: zapisywane będą odwiedziny administratorów.</li>
+
+</ul>
+
+<h3>Komentarze</h3>
+<ul>
+
+  <li><strong>Komentarze dla wszystkich</strong>: umożliwia dodawanie komentarzy przez niezarejestrowanych użytkowników.</li>
+
+  <li><strong>Liczba komentarzy na stronę</strong>.</li>
+
+  <li><strong>Zatwierdzanie</strong>: administrator zatwierdz komentarze pojawiające się w galerii. Zatwierdzanie komentarzy jest możliwe z  <span class="pwgScreen">Administracja, Obrazy,
+  Komentarze</span>.</li>
+
+  <li><strong>Wyślij wiadomość do administratora gdy zostanie wprowadzony poprawny komentarz</strong>:
+Wysyła wiadomość do administratora w przypadku dodania komentarza i gde ten komentarz zostanie zatwierdzony.</li>
+
+  <li><strong>Wyślij wiadomość do administratora gdy komentarz wymaga weryfikacji</strong>:
+Wysyła wiadomośćdo administratora w przypadku dodania komentarza, który wymaga zatwierdzenia przez administratora.
+Zatwierdzanie komentarzy jest możliwe z  <span class="pwgScreen">Administracja, Obrazy, Komentarze</span>.</li>
+
+</ul>
+
+<!--TODO --><h3>Upload</h3>
+<ul>
+<!--TODO -->  <li><strong>Zawsze pokazuj link upload</strong>: Jeżeli istnieją kategorie mające włączoną opcję wgrywania plików, odpowiedni link będzie widoczny przy każdej kategorii.</li>
+<!--TODO -->  <li><strong>Poziom uprawnień użytkoników dla upload'u</strong>: Pozwala na zabronienie użytkownikom wgrywania plików</li>
+  <li><strong>Wyślij wiadomość do administratora gdy został wgrany nowy obraz</strong>: Administrator otrzyma wiadomość o każdym wgranym pliku.</li>
+</ul>
+
+<h3>Wyświetlanie domyślne</h3>
+
+<p>W tym miejscu można zmienić domyslne wyświetlanie, dla użytkownika gość (niezalogowanego). Po zalogowaniu opcje są nadpisywane przez preferencje użytkownika(edycja w <span class="pwgScreen">profil</span>).</p>
+
+<p>Możliwa jest zmiana dla wszystkich użytkowników, natomiast opcja ta jest dostępna z poziomu <span class="pwgScreen">Administracja,
+Uprawnienia, Użytkownicy</span>, gdzie opcje mżna zmienić dla wybranych użytkowników.</p>
+
+<ul>
+
+  <li><strong>Język</strong>: dotyczy tylko labelek Piwigo. Nazwy kategorii, obrazów oraz wszystkie opisy nie podlegją tłumaczeniu.</li>
+
+  <li><strong>Liczba obrazów w wierszu</strong></li>
+
+  <li><strong>Liczba wierszy na stronę</strong></li>
+
+  <li><strong>Interfejs użytkownika</strong></li>
+
+  <li><strong>Aktualny okres</strong>: W dniach. Okres oznaczający, że elementy są wyświetlane jako nowe. Musi być większe od 1 dnia.</li>
+
+  <li><strong>Rozwiń wszystkie kategorie</strong>: Rozwija wszystkie kategorie w menu <em>Ostrzeżenie</em>: opcja ta wymaga dużo zasobów i może wygenerować bardzo duże menu jeżeli liczba kategorii jest duża..</li>
+
+  <li><strong>Pokazuj liczbę komentarzy</strong>: wyświetla liczbę komentarzy na stronie z miniaturami. Wymaga dużych zasobów.</li>
+
+  <li><strong>Pokazuj liczbę wejść</strong>: wyświetla liczbę wyświetleń danego obrazu na stronei z miniaturami. 
+  Tylko gdy zaawansowany parametr jest ustawiony na: <br />
+  $conf['show_nb_hits'] = true; <br />
+  Notka: domyślne ustawienie to false.</li>
+
+  <li><strong>Maksymalna szerokość obrazu</strong>: maksymalna wyświetlana szerokość. Jeżeli obraz jest większy, to wtedy zostanie pomniejszony (do wyświetlenia). Jeżeli chcesz zaznaczyć tę opcję, lepiej jest rozważyć zmianę rozmiarów obrazów.</li>
+
+  <li><strong>Maksymalna wysokość obrazu</strong>: jak wyżej (ale odnośnie szerokości).</li>
+
+</ul>
+
Index: /tags/2.0.2/language/pl_PL/help/extend_for_templates.html
===================================================================
--- /tags/2.0.2/language/pl_PL/help/extend_for_templates.html	(revision 3278)
+++ /tags/2.0.2/language/pl_PL/help/extend_for_templates.html	(revision 3278)
@@ -0,0 +1,87 @@
+<h2>Rozszerzenie dla konfiguracji szablonów</h2>
+
+<h3>Cel</h3>
+<p>Definiuje warunki zamiany szablonu z template-extension
+(szablon zwany "zamiennikiem").</p>
+
+<p>"Oryginalny szablon" z ./template/yoga (lub inny niż yoga)
+ będzie zamieniony przez "zamiennik" jeżeli zamiennik jest podpięty do "szablonu oryginalnego"
+ (lub opcjonalnie, jeżeli żądany adres URL zawiera "opcjonalne słowo klucz dla URL").</p>
+
+<p>"Opcjonalne słowa klucze dla URL" mogą zostać odnalezione w module URLs.</p>
+
+<p>"Opcjonalne słowa klucze dla URL" może być także "linkiem permanentnym" 
+(zobacz opis linków permanentnych w naszej dokumentacji).</p>
+
+<p>Czytaj: `<a href="#warnings">Ostrzeżenie</a>` warunki użycia.</p>
+
+<h3>Czym są rozszerzenia szablonów?</h3>
+
+<p>Narzędzie konfiguracyjne zarówno dla użytkowników początkujących jak i zaawansowanych.
+Webmaster może powielić wiele dostarczanych plików (.tpl) szablonów ("szablony oryginalne") przez FTP do folderu template-extensions nadając im inne nazwy.
+ 
+ "Szablony oryginalne", aktualnie szablony oryginalne są wspierane dla:</p>
+<ul>
+  <li><span class="filename">index.tpl</span></li>
+  <li><span class="filename">mainpage_categories.tpl</span> i/lub <span class="filename">thumbnails.tpl</span></li>
+  <li><span class="filename">menubar.tpl</span></li>
+  <li><span class="filename">header.tpl</span> i/lub <span class="filename">footer.tpl</span></li>
+  <li><span class="filename">picture_content.tpl</span> i/lub <span class="filename">picture.tpl</span></li>
+  <!-- <li><span class="filename">slideshow.tpl</span></li> -->
+  <li><span class="filename">profile.tpl</span> i/lub <span class="filename">profile_content.tpl</span></li>
+  <li><span class="filename">tags.tpl</span></li>
+  <li><span class="filename">upload.tpl</span></li>
+  <li><span class="filename">about.tpl</span></li>
+  <li><span class="filename">popuphelp.tpl</span></li>
+  <li><span class="filename">search.tpl</span> i/lub <span class="filename">search_rules.tpl</span></li>
+  <li><span class="filename">nbm.tpl</span> i/lub <span class="filename">notification.tpl</span></li>
+  <li><span class="filename">identification.tpl</span> i/lub <span class="filename">register.tpl</span></li>
+  <li><span class="filename">redirect.tpl</span></li>
+</ul>
+
+<h3>Gdzie mogę znaleźć  "szablony oryginalne"?</h3>
+
+<p>Szablony oryginalne znajdują się w katalogu template/yoga/ 
+(nie należy ich edytować z powodów aktualizacji). Z "szablonów oryginalnych", 
+dowolny administrator może stworzyć ich "zamienniki (spersonalizowane szablony)".</p>
+
+<h3>Gdzie należy zapisać "zamienniki"?</h3>
+
+<p><strong>Zamienniki (szablony spersonalizowane)</strong> muszą być umieszczone w katalogu template-exension (lub jego podkatalogach).
+Nazwy plików zaminników mogą mieć dowolne nazwy oraz rozszerzenie .tpl. Na przykład: <span
+class="filename">template-extension/moje-rozszerzenia/wideo.tpl</span>.</p>
+
+
+<h3>Jak mogę aktywować "zamienniki"?</h3>
+<p>Aby aktywować powiązane zamienniki<strong>szablon oryginalny</strong> powinien być przypisany do każdego
+ <strong>zamiennika (szablonu spersonalizowanego)</strong>.
+ Do tego służy funkcja "Rozszerz szablony" w menu Konfiguracja/Administracja.</p>
+
+<p>Jezeli zostanie wybrane <strong>opcjonalne słowo klucz dla adresu URL</strong> zamienniki będą funkcjonować tylko dla stron zawierających te słowa. Na przykład: <span
+  class="pwgScreen">index.php?/<strong>najszesciej_odwiedzane</strong></span></p>
+  
+<p>Zaawansowani użytkownicy mogą używać linków permanentnych jako <strong>opcjonalnego słowa klucz dla adresu URL</strong>. </p>
+<h3>Jak mogę deaktywować "zamienniki"?</h3>
+<ul>
+<li>Odznacz powiązane "Szablony oryginalne".</li>
+<li>Usuń "zamienniki" przez FTP.</li>
+</ul>
+<a name="warnings"></a>
+<h3>Ostrzeżenia</h3>
+<ul>
+
+  <li><strong>Szablon oryginalny</strong> musi być "oryginalnym" szablonem, w przeciwnym przypadku mogą wystąpić nieprzewidziane problemy!</li>
+
+  <li>Dla wielu <strong>zamienników (szablonów spersonalizowanych)</strong> z takim samym<strong>Szablonem oryginalnym</strong> i takim samym <strong>kluczowym słowem dla adresu URL</strong> aktywny jest ylko ostatni zamiennik.</li>
+
+  <li>Odznaczenie <strong>opcjonalnego słowa klucz dla adresu URL</strong> aktywuje zamiennik dla dowolnego uzycia szablonu. Jak już wspomniano wcześniej, kolejność może nadpisać poprzednio wybrane zamienniki.</li>
+
+  <li>Podkatalogi:
+Podkatalogi są ignorowane, ale są przydatne aby zmienić kolejność.<br />
+distributed-samples: rozpowszechniane dla celów testowych! 
+<strong>Nie edytuj ich</strong>, ale stwórz własne.
+</li>
+
+  <li>Po usunięciu zamiennika natychmiastowo jest aktywowany <strong>Szablon oryginalny</strong>.</li>
+
+</ul>
Index: /tags/2.0.2/language/pl_PL/help/group_list.html
===================================================================
--- /tags/2.0.2/language/pl_PL/help/group_list.html	(revision 3278)
+++ /tags/2.0.2/language/pl_PL/help/group_list.html	(revision 3278)
@@ -0,0 +1,22 @@
+<h2>Lista grup</h2>
+
+<p>To jest miejsce, w którym mozesz zarządzać zdefiniowanymi grupami.</p>
+
+<h3>Dodaj grupę</h3>
+
+<p>Grupu może dodawać administrator.</p>
+
+<h3>Lista grup</h3>
+
+<p>Lista dla każdego elementu umożliwia:</p>
+
+
+<ul>
+  <li>przejście do listy członków</li>
+  <li>przejście do uprawnień</li>
+  <li>usunięcie grupy (wymaga zaznaczenia potwierdzającego checkbox'a)</li>
+  <li>zmiana statusu "default" (wymaga zaznaczenia potwierdzającego checkbox'a)</li>
+</ul>
+
+<h3>Grupy domyślne</h3>
+<p>Grupy domyślne są grupami przypisywanymi do nowych użytkowików.</p>
Index: /tags/2.0.2/language/pl_PL/help/history.html
===================================================================
--- /tags/2.0.2/language/pl_PL/help/history.html	(revision 3278)
+++ /tags/2.0.2/language/pl_PL/help/history.html	(revision 3278)
@@ -0,0 +1,38 @@
+<h2>Historia</h2>
+
+<p>Ekran umożliwia śledzenie historii odwiedzin stron galerii Piwigo w nawiązaniu do wybranych opcji w Administracja, Ogólne, Historia.</p>
+	
+<h3>Statystyki</h3>
+<ul>
+  <p>Jeżeli wybrałeś opcję zapisywania odwiedzin stron(<span
+class="pwgScreen">index.php</span> i <span
+class="pwgScreen">picture.php</span>) w tabeli <code>historii. </code>
+Index pozwala na prześledzenie odwiedzonych stron.</p>
+	
+	<li><strong>Statystyki ogólne</strong> : wizualizacja roczna. </li>
+	
+	<li><strong>Statystyki roczne</strong> : wizualizacja miesięczna dla wybranego roku.</li>
+	
+	<li><strong>Statystyki miesięczne</strong> : wizualizacja dzienna dla wybranego miesiąca.</li>
+	
+	<li><strong>Statystyki dzienne</strong> :wizualizacja dzienna dla wybranego dnia.</li>
+	
+</ul>
+
+<h3>Wyszukiwanie</h3>
+<ul>
+  <p>Jeżeli wybrałeś opcję zapisywania odwiedzin stron (<span
+class="pwgScreen">index.php</span> i <span
+class="pwgScreen">picture.php</span>) w tabeli <code>historii. </code>
+Index pozwala na prześledzenie odwiedzonych stron z wykorzystaniem różnych filtrów.</p>
+ 
+	<li><strong>Filtrowanie po dacie</strong> : wybierz interwał dat, które Cię interesują.</li>
+	
+	<li><strong>Filtrowanie po typie elementu</strong> : wybierz typ elementu, którego statystyki chcesz zobaczyć.</li>
+	
+	<li><strong>Filtrowanie po użytkowniku</strong> : wybierz użytkownika, którego statystyki chcesz zobaczyć.</li>
+	
+	<li><strong>Filtrowanie po nazwie pliku</strong> : wybierz nazwe pliku, dla której chcesz zobaczyś statystyki.</li>
+	
+	<li><strong>Filtrowanie po idenyfikacyjny obrazie</strong> : wybierz identyfikacyjny obraz, dla którego statystyki chcesz zobaczyć.</li>
+</ul>
Index: /tags/2.0.2/language/pl_PL/help/index.php
===================================================================
--- /tags/2.0.2/language/pl_PL/help/index.php	(revision 3278)
+++ /tags/2.0.2/language/pl_PL/help/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008      Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/language/pl_PL/help/maintenance.html
===================================================================
--- /tags/2.0.2/language/pl_PL/help/maintenance.html	(revision 3278)
+++ /tags/2.0.2/language/pl_PL/help/maintenance.html	(revision 3278)
@@ -0,0 +1,30 @@
+<h2>Maintenance</h2>
+
+<p>W elu optymalizacji czasu generowania strony Piwigo wykorzystuje informacje umieszczone w cache'u. Dla przykładu zamiast przeliczać za każdym razem liczbę elementów w kategorii, informacja ta jest zapisana w bazie danych. Teoretycznie informacja ta powinna być zawsze prawdziwa, ale czasami występują błędy i informacja wyświetlana jest niepoprawna.</p>
+
+<p>Niektóre informacje stają się wtedy bezużyteczne. Usuwanie tych bezużytecznych informacji pozwala zaoszczędzić przestrzeń na dysku.</p>
+
+<ul>
+
+  <li><strong>Aktualizuj informacje o kategoriach:</strong> Informacje dla każdej kategorii : lista kategorii nadrzędnych, liczba obrazów, data dodania ostatniego obrazu, pozycja względem sąsiednich kategorii, pozycja względem wszystkich kategorii. Akcja ta sprawda także istnienie reprezentanta dla kategorii.</li>
+
+  <li><strong>Aktualizuj informacje o obrazach:</strong> Dla każdego obrazu są to informacje : pełna ścieżka do pliku, średnie oceny. <em>Ostrzeżenie</em>: nie należy mylić tych informacji z metadanymi, które są dostepne z poziomu <span class="pwgScreen">Administracja,
+  Kategorie, Synchronizacja</span> lub dostępne z poziomu ekranu edycji dla każdego elementu (np. przez <span class="pwgScreen">Obraz</span>  ).</li>
+
+  <li><strong>Napraw i optymalizuj bazę danych:</strong>
+  Dla każdej tabeli moze być wykonana, re-organizacja, naprawa i optymalizacja.
+  </li>
+</ul>
+
+<ul>
+  <li><strong>Usuń szczegóły historii:</strong> Usuwa wszystkie linie z tabeli
+  <code>histori</code> . Ekran <span class="pwgScreen">Administracja,
+  Specjalne, Historia</span> nie będzie wyświetlał żadnej historii. <em>Ostrzeżenie</em>: wszystkie dane zostaną utracone bez możliwości ich odzyskania.</li>
+
+  <li><strong>Usuń podsumowanie historii:</strong> Usuwa informacje podsumowujące liczbę odwiedzin historii. Podsumowanie to jest wyliczne na podstawie szczegółowych informacji zawartych w historii.</li>
+
+  <li><strong>Wyczyść sesje:</strong> Usuwa wygaśnięte sesje użytkowników.</li>
+
+  <li><strong>Wyczyść nigdy nie używane RSS feed</strong></li>
+
+</ul>
Index: /tags/2.0.2/language/pl_PL/help/notification_by_mail.html
===================================================================
--- /tags/2.0.2/language/pl_PL/help/notification_by_mail.html	(revision 3278)
+++ /tags/2.0.2/language/pl_PL/help/notification_by_mail.html	(revision 3278)
@@ -0,0 +1,15 @@
+<h2>Powiadamianie mailowe</h2>
+
+<p>Ekran umo¿liwia konfiguracjê oraz zarz¹dzanie powiadomieniami u¿ytkowników o nowociach na stronie.</p>
+
+<p>Ekran sk³ada siê z 3 zak³adek:</p>
+
+<h3>Parametry</h3>
+<p>Dostêpna tylko dla webmaster'a, umo¿liwia zmianê parametrów powiadomieñ mailowych.</p>
+
+<h3>Zapisy</h3>
+<p>Dostêpna tylko dla webmaster'a, umo¿liwia zapisywanie/wypisywanie u¿ytkowników z powiadomieñ.</p>
+
+<h3>Wylij</h3>
+<p>Dostêpna tylko dla webmaster'ów i administratorów, umo¿liwia wys³anie wiadomoci do u¿ytkowników.</p>
+
Index: /tags/2.0.2/language/pl_PL/help/permalinks.html
===================================================================
--- /tags/2.0.2/language/pl_PL/help/permalinks.html	(revision 3278)
+++ /tags/2.0.2/language/pl_PL/help/permalinks.html	(revision 3278)
@@ -0,0 +1,7 @@
+<h2>Linki permanentne</h2>
+
+<p>Linki permanentne są wykorzystywane po to, aby adres URL danej kategorii był łatwiejszy do zapamiętania i ładniej wyglądał. Jeżeli kategoria posiada taki link, nie jest już potrzebne zapamiętywanie jej ID.</p>
+
+<p>Podczas usuwania linku, istnieje możliwość zapisania go w historii, po to, żeby w dalszym ciągu działały adresy zewnętrzne. W historii linków permanentnych można zobaczyć kiedy dany link został usunięty jak również czas kiedy był ostatnio używany oraz liczbę jego użyć.</p>
+
+<p>Link permanentny musi być unikalny w obrębie kategorii. Również w historii linków permanentnych dana nazwa może być użyta tylko raz.</p>
Index: /tags/2.0.2/language/pl_PL/help/search.html
===================================================================
--- /tags/2.0.2/language/pl_PL/help/search.html	(revision 3278)
+++ /tags/2.0.2/language/pl_PL/help/search.html	(revision 3278)
@@ -0,0 +1,19 @@
+<h2>Wyszukiwanie</h2>
+
+<p>Funkcja umożliwia wyszukiwanie obrazów w całej galerii.</p>
+
+<dl>
+
+  <dt>Wyszukiwanie słów</dt>
+  <dd>Szuka danego słowa we wszystkich atrybutach obrazów umieszczonych w galerii. Użyj znaku * aby wyszukać obrazy, do których słowo częściowo pasuje (np. wycieczk*).</dd>
+
+  <dt>Wyszukiwanie autora</dt>
+  <dd>Użyj znaku * aby wyszukać słowo które częściowo pasuje (np. jac*).</dd>
+
+  <dt>Wyszukiwanie po dacie</dt>
+  <dd>Wybierz datę i/lub datę końcową dla wyszukiwania. Zostaw datę pustą jeżeli chcesz wyszukać obrazy "sprzed" danej daty. Rok musi być wpisany w ostatnim polu w formacie : 0000 (np. 2004)</dd>
+
+  <dt>Wyszukiwanie w kategoriach</dt>
+  <dd>Wybierz kategorię lub kategorie, w których chcesz wyszukiwać. Dla przyśpieszenia wyszukiwania w podkategoriach, można zaznaczyć główną kategorię oraz opcję szukania w podkategoriach.</dd>
+
+</dl>
Index: /tags/2.0.2/language/pl_PL/help/site_manager.html
===================================================================
--- /tags/2.0.2/language/pl_PL/help/site_manager.html	(revision 3278)
+++ /tags/2.0.2/language/pl_PL/help/site_manager.html	(revision 3278)
@@ -0,0 +1,41 @@
+<h2>Zdalne strony</h2>
+
+<p>Piwigo oferuje możliwość wykorzystania wielu serwerów do przechowywania zawartości galerii. Może to być przydatne gdy na serwerze masz mało miejsca lub posiadasz dużo obrazów.</p>
+
+<ol>
+
+  <li>edytuj następujące parametry w pliku <span class="filename">tools/create_listing_file.php</span>,
+  <code>$conf['prefix_thumbnail']</code> lub
+  <code>$conf['use_exif']</code>.</li>
+
+  <li>umieść przy pomocy ftp zmodyfikowany plik <span class="filename">tools/create_listing_file.php</span>
+  na zdalnym serwerze, w tym samym katalogu co katalog kategorii (tak jak katalog <span class="filename">galleries</span> . Dla przykładu może to być <span
+  class="filename">http://example.com/galleries/create_listing_file.php</span>.</li>
+
+  <li>przejdź do <span class="pwgScreen">panelu administracyjnego, Kategorie, Menadżer strony</span>. Stwórz nową stronę np. <span
+  class="filename">http://example.com/galleries</span>.</li>
+
+  <li>zostanie stworzona nowa zdalna strona. Możesz na niej wykonać 4 akcje :
+
+    <ol>
+
+      <li><strong>generuj listę</strong> : uruchamia zdalnie żądanie generacji listy plików</li>
+
+      <li><strong>synchronizuj</strong> : odczytuje zdalny plik <span
+      class="filename">listing.xml</span> i synchronizuje informacje z bazą danych.</li>
+
+      <li><strong>wyczyść</strong> : usuwa dalny plik <span
+      class="filename">listing.xml</span> .</li>
+
+      <li><strong>usuń</strong> : usuwa zdalną stronę (oraz wszystkie z nią powiązane kategorie i elementy) z bazy danych.</li>
+
+    </ol>
+  </li>
+</ol>
+
+<!-- <p>You can do all this by hand by generating yourself the <span
+class="filename">listing.xml</span> file, moving it from your distant server
+to you local Piwigo root directory and opening the remote site
+management screen : Piwigo will propose you to use the found
+listing.xml file.</p>-->
+
Index: /tags/2.0.2/language/pl_PL/help/synchronize.html
===================================================================
--- /tags/2.0.2/language/pl_PL/help/synchronize.html	(revision 3278)
+++ /tags/2.0.2/language/pl_PL/help/synchronize.html	(revision 3278)
@@ -0,0 +1,8 @@
+<h2>Synchronizuj</h2>
+
+<p>Możliwe są 2 sposoby synchronizacji : katalogi/pliki oraz metadane plików. Tryb katalogi/pliki służy do synchronizacji struktury katalogów oraz plików kategorii z bazą danych. Tryb metadane plikówaktualizuje informacje o elementach takie jak rozmiar pliku, rozmiar w pixelach, EXIF czy IPTC.</p>
+
+<p>Najpierw musi zostać wykonana synchronizacja katalogi/pliki.</p>
+
+<p>Proces synchronizacji może trwać długo (zależny jest np od obciążenia serwera oraz ilości elementów, które mają zostać zsynchronizowane) dlatego możliwa jest synchronizacja krok po kroku:
+kategoria po kategorii.</p>
Index: /tags/2.0.2/language/pl_PL/help/thumbnail.html
===================================================================
--- /tags/2.0.2/language/pl_PL/help/thumbnail.html	(revision 3278)
+++ /tags/2.0.2/language/pl_PL/help/thumbnail.html	(revision 3278)
@@ -0,0 +1,23 @@
+<h2>Tworzenie miniatur</h2>
+
+<p>Strona ta umożliwia stworzenie brakujących miniatur.</p>
+
+<dl>
+
+  <dt>Wersja GD</dt>
+
+  <dd>GD jest biblioteką służącą do manipulacji obrazami dla PHP. NAleży wybrać wersję zainstalowaną na serwerze. Jeżeli zostanie wybrana zła, zostaną wyświetlone komunikaty o błędach, należy wtedy wrócić do konfiguracji wersji GD i wybrać inną. Jeżeli nie zadziała żadna wersja, oznacza to, że serwer nie posiada wsparcia dla biblioteki GD.</dd>
+
+  <dt>Szerokość i wysokość</dt>
+
+  <dd>Maksymalne rozmiary jakie mogą posiadać miniatury. Zachowane jest aspect ratio.</dd>
+
+  <dt>Liczba miniatur do utworzenia</dt>
+
+  <dd>Nie próbuj wykonywać miniatur dla zbyt wielu obrazów w tym samym czasie, ponieważ proces ten obciąża mocno procesor. Jeżeli masz zainstalowane Piwigoo w ramach darmowego hostingu, zbyt wysokie wykorzystanie procesora może prowadzić nawet do usunięcia strony.</dd>
+
+  <dt>Typ pliku</dt>
+
+  <dd>Miniatury mogą być tworzone tylko jako JPEG. Natomiast miniatury mogą być tworzone z plików GIF oraz JPEG.</dd>
+
+</dl>
Index: /tags/2.0.2/language/pl_PL/help/user_list.html
===================================================================
--- /tags/2.0.2/language/pl_PL/help/user_list.html	(revision 3278)
+++ /tags/2.0.2/language/pl_PL/help/user_list.html	(revision 3278)
@@ -0,0 +1,39 @@
+<h2>Lista użytkowników</h2>
+
+<p>W tym miejscu można zarządzać zarejestrowanymi użytkownikami. Tylko uprawnienia znajdują się na kilku innych ekranach.</p>
+
+<h3>Dodawanie użytkownika</h3>
+
+<p>Administrator może dodawać użytkowników ręcznie.</p>
+
+<h3>Lista użytkowników</h3>
+
+<p>Lista użytkowników może być filtrowana po nazwie użytkownika (użyj znaku * jako wildcard), grupie lub statusie. Lista może być sortowana po dacie rejestracji, nazwie użytkownika w kolejności roznącej lub malejącej.</p>
+
+<p>Ekran ten umożliwia wykonywanie w tym samym czasie danej akcji na kilku użytkonwikach
+:</p>
+
+<ul>
+
+  <li>usuwanie użytkowników (wymaga potwierdzenia przez zaznaczenie checkbox)</li>
+
+  <li>zmiana statusu</li>
+
+  <li>dodanie lub usuięcie z grup</li>
+
+  <li>edycja właściwości wyświetlania</li>
+
+  <li>edycja dodatkowych właściwości</li>
+
+</ul>
+
+<p>Domyślnie można wykonać taką akcję np. dla użytkowników zaznaczonych lub wszystkich użytkowników.</p>
+<h3>Rada</h3>
+<p>Definicja użytkownika adviser:</p>
+<ul>
+  <li>zezwól na dostęp do wszystkich ekranów dla tego statusu</li>
+  <li>dostęp tylko do odczytu lub symulacja</li>
+</ul>
+
+<p>Możliwość dodania takiego użytkownika określa się w pliku konfiguracyjnym przez następujący parametr $conf['allow_adviser'].</p>
+<p>Jeżeli ustawiony jest na 'true', to będize możliwe zdefiniowanie użytkonika typu adviser</p>
Index: /tags/2.0.2/language/pl_PL/index.php
===================================================================
--- /tags/2.0.2/language/pl_PL/index.php	(revision 3278)
+++ /tags/2.0.2/language/pl_PL/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008      Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/language/pl_PL/install.lang.php
===================================================================
--- /tags/2.0.2/language/pl_PL/install.lang.php	(revision 3278)
+++ /tags/2.0.2/language/pl_PL/install.lang.php	(revision 3278)
@@ -0,0 +1,76 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008      Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+$lang['Installation'] = 'Instalacja';
+$lang['Initial_config'] = 'Podstawowa konfiguracja';
+$lang['Default_lang'] = 'Domyślny język galerii';
+$lang['step1_title'] = 'Konfiguracja bazy danych';
+$lang['step2_title'] = 'Konfiguracja administratora';
+$lang['Start_Install'] = 'Rozpoczęcie instalacji';
+$lang['reg_err_mail_address'] = 'adres email musi być w postaci xxx@yyy.eee (np : jack@altern.org)';
+
+$lang['install_webmaster'] = 'Logowanie Webmastera';
+$lang['install_webmaster_info'] = 'To będize wyświetlone dla odwiedzających i jest konieczne do celów administracyjnych ';
+
+$lang['step1_confirmation'] = 'Parametry są poprawne';
+$lang['step1_err_db'] = 'Połączenie do serwera powiodło się, ale nie było możliwe połączenie do bazy danych';
+$lang['step1_err_server'] = 'Nie można połączyć sie do serwera';
+$lang['step1_err_copy_2'] = 'Teraz mozliwy jest następny krok instalacji';
+$lang['step1_err_copy_next'] = 'następny krok';
+$lang['step1_err_copy'] = 'Skopiuj tekst zaznaczony na różowo pomiędzy cudzysłowiami i wklej do pliku "include/mysql.inc.php"(Uwaga : mysql.inc.php musi zawierać tylko to co jest na różowo bez żadnych znaków końca linii czy spacji)';
+
+$lang['step1_host'] = 'MySQL host';
+$lang['step1_host_info'] = 'localhost, sql.multimania.com, toto.freesurf.fr';
+$lang['step1_user'] = 'Uzytkownik';
+$lang['step1_user_info'] = 'login użytkownika dostarczona przez provider\'a';
+$lang['step1_pass'] = 'Hasło';
+$lang['step1_pass_info'] = 'hasło użytkownika dostarczona przez provider\'a';
+$lang['step1_database'] = 'NAzwa bazy danych';
+$lang['step1_database_info'] = 'także dostarczona przez provider\'a';
+$lang['step1_prefix'] = 'Prefix tabel bazy danych';
+$lang['step1_prefix_info'] = 'tabele w bazie dnaych będą miały taki prefix (ułatwia to zarządzanie tabelami)';
+$lang['step2_err_login1'] = 'wprowadź nazwę użytkownika posiadającego uprawnienia Webmaster';
+$lang['step2_err_login3'] = 'login nie może zawierać nastepujących znaków \' lub "';
+$lang['step2_err_pass'] = 'wprowadź hasło jeszcze raz';
+$lang['install_end_title'] = 'Instalacja zakończona';
+$lang['step2_pwd'] = 'Hasło użytkownika Webmaster';
+$lang['step2_pwd_info'] = 'Zachowaj hasło, umożliwia ono dostep do panelu administracyjnego';
+$lang['step2_pwd_conf'] = 'Hasło [potwierdź]';
+$lang['step2_pwd_conf_info'] = 'weryfikacja';
+$lang['install_help'] = 'Potrzebujesz pomocy ? Zadaj pytanie na <a href="%s">Forum Piwigo</a>.';
+$lang['install_end_message'] = 'Konfiguracja Piwigo została zakończona, następny krok to<br /><br />
+* przejdź do strony logowania : [ <a href="identification.php">logowanie</a> ] i wprowadź użytkownika/hasło będącego webmaster\'em<br />
+* logowanie to umożliwi Ci dostęp do panelu administracyjnego oraz instrukcji jak umieszczaćzdjęcia w katalogach';
+$lang['conf_mail_webmaster'] = 'Adres email Webmaster\'a';
+$lang['conf_mail_webmaster_info'] = 'Z jego pomocą odwiedzający będą mogli się skontaktować z administratorem strony';
+
+$lang['PHP 5 is required'] = 'PHP 5 jest wymagane';
+$lang['It appears your webhost is currently running PHP %s.'] = 'Twój serwer aktualnie używa PHP w wersji %s.';
+$lang['Piwigo may try to switch your configuration to PHP 5 by creating or modifying a .htaccess file.'] = 'Piwigo może spróbować przełączyć Twoją konfigurację do PHP 5 poprzez modyfikację pliku .htaccess.';
+$lang['Note you can change your configuration by yourself and restart Piwigo after that.'] = 'Możesz również zmienić tę konfigurację sam, a następnie uruchomić ponownie Piwigo.';
+$lang['Try to configure PHP 5'] = 'Spróbuj skonfigurować PHP 5';
+$lang['Sorry!'] = 'Niestety!';
+$lang['Piwigo was not able to configure PHP 5.'] = 'Piwigo nie mógł skonfigurować Twojego PHP 5.';
+$lang["You may referer to your hosting provider's support and see how you could switch to PHP 5 by yourself."] = "Możesz skontaktować się z działem wsparcia Twojego providera aby dowiedzieć się jak włączyć PHP 5.";
+$lang['Hope to see you back soon.'] = 'Do zobaczenia wkrótce.';
+?>
Index: /tags/2.0.2/language/pl_PL/iso.txt
===================================================================
--- /tags/2.0.2/language/pl_PL/iso.txt	(revision 3278)
+++ /tags/2.0.2/language/pl_PL/iso.txt	(revision 3278)
@@ -0,0 +1,1 @@
+Polski [PL]
Index: /tags/2.0.2/language/pl_PL/upgrade.lang.php
===================================================================
--- /tags/2.0.2/language/pl_PL/upgrade.lang.php	(revision 3278)
+++ /tags/2.0.2/language/pl_PL/upgrade.lang.php	(revision 3278)
@@ -0,0 +1,44 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008      Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+$lang['Upgrade'] = 'Upgrade';
+$lang['introduction message'] = 'Strona służy do wykonania aktualizacji bazy danych Piwigo do aktualnej wersji.
+Asystent aktualizacji odgadł, że aktualnie używasz <strong>wersji %s</strong> (lub podobnej).';
+$lang['Upgrade from %s to %s'] = 'Aktualizacja z wersji %s do %s';
+$lang['Statistics'] = 'Statystyki';
+$lang['total upgrade time'] = 'sumaryczny czas aktualizacji';
+$lang['total SQL time'] = 'symaryczny czas SQL';
+$lang['SQL queries'] = 'zapytań SQL';
+$lang['Upgrade informations'] = 'Informacje o aktualizacji';
+$lang['perform a maintenance check'] = 'Jeżeli napotkasz jakiś problem wykonaj weryfikację przez [Administracja>Specjalne>Maintenance].';
+$lang['deactivated plugins'] = 'W ramach zabezpieczenia zostąły deaktywowane następujące wtyczki. Przed ich ponowną aktywacją musisz sprawdzić dostępność aktualizacji dla nich:';
+$lang['upgrade login message'] = 'Tylko administrator może wykonać aktualizację: zaloguj się poniżej.';
+$lang['You do not have access rights to run upgrade'] = 'Nie masz uprawnień do wykonania aktualizacji';
+$lang['in include/mysql.inc.php, before ?>, insert:'] = 'W pliku <i>include/mysql.inc.php</i>, przed <b>?></b>, wstaw:';
+
+// Upgrade informations from upgrade_1.3.1.php
+$lang['all sub-categories of private categories become private'] = 'Wszystkie podkategorie kategorii prywatnych staną się prywatne';
+$lang['user permissions and group permissions have been erased'] = 'Uprawnienia użytkowników oraz grup zostały usunięte';
+$lang['only thumbnails prefix and webmaster mail saved'] = 'Z poprzedniej konfiguracji zostały zapisane tylko prefixy miniatur oraz adres email administratora.';
+
+?>
Index: /tags/2.0.2/language/pt_PT/about.html
===================================================================
--- /tags/2.0.2/language/pt_PT/about.html	(revision 3278)
+++ /tags/2.0.2/language/pt_PT/about.html	(revision 3278)
@@ -0,0 +1,6 @@
+  <li>Piwigo é uma aplicação web permitindo de criar facilemente uma galeria de imagens em linha.</li>
+
+  <li>Tecnicamente, Piwigo é desenvolevido em PHP com uma base de dados MySQL.</li>
+
+  <li>Se tiver sugestões ou comentários visite o <a
+  href="http://piwigo.org">sitio oficial</a> e <a href="http://piwigo.org/forum">seu forum</a>.</li>
Index: /tags/2.0.2/language/pt_PT/common.lang.php
===================================================================
--- /tags/2.0.2/language/pt_PT/common.lang.php	(revision 3278)
+++ /tags/2.0.2/language/pt_PT/common.lang.php	(revision 3278)
@@ -0,0 +1,368 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Langage informations
+$lang_info['language_name'] = 'Português';
+$lang_info['country'] = 'Portugal';
+$lang_info['direction'] = 'ltr';
+$lang_info['code'] = 'pt';
+$lang_info['zero_plural'] = false;
+
+$lang['%.2f (rated %d times, standard deviation = %.2f)'] = '%.2f (noté %d fois, écart type = %.2f)';
+$lang['%d Kb'] = '%d Ko';
+$lang['%d category updated'] = '%d categoria actualizada';
+$lang['%d categories updated'] = '%d categorias actualizadas';
+$lang['%d comment to validate'] = '%d comentário usário para vaidar';
+$lang['%d comments to validate'] = '%d comentários usários para validar';
+$lang['%d new comment'] = '%d novo comentário';
+$lang['%d new comments'] = '%d novos comentários';
+$lang['%d comment'] = '%d comentário';
+$lang['%d comments'] = '%d comentários';
+$lang['%d hit'] = 'visto %d vêz';
+$lang['%d hits'] = 'vista %d vêzes';
+$lang['%d new element'] = '%d novo elemento';
+$lang['%d new elements'] = '%d novos elementos';
+$lang['%d new user'] = '%d novo usário';
+$lang['%d new users'] = '%d novos usários';
+$lang['%d waiting element'] = '%d elemento a espera';
+$lang['%d waiting elements'] = '%d elementos a espera';
+$lang['About'] = 'A prepósito de';
+$lang['All tags must match'] = 'Todos os tags devem corresponder';
+$lang['All tags'] = 'Todos os tags';
+$lang['Any tag'] = 'qualquer tag';
+$lang['At least one listed rule must be satisfied.'] = 'Ao menos um dos criterios deve ser satisfeito.';
+$lang['At least one tag must match'] = 'Ao menos um dos tags deve corresponder';
+$lang['Author'] = 'Autor';
+$lang['Average rate'] = 'Nota media';
+$lang['Categories'] = 'Categorias';
+$lang['Category'] = 'Categoria';
+$lang['Close this window'] = 'Fechar esta janela';
+$lang['Complete RSS feed'] = 'Fluxo RSS completo (imagems, comentarios)';
+$lang['Confirm Password'] = 'Confirmar a palavra passe';
+$lang['Connection settings'] = 'Ajustes de conexão';
+$lang['Connection'] = 'Conexão';
+$lang['Contact webmaster'] = 'Contactar o webmaster';
+$lang['Create a new account'] = 'Criar uma nova conta';
+$lang['Created on'] = 'Criada em';
+$lang['Creation date'] = 'Data de criação';
+$lang['Current password is wrong'] = 'A palavra passe esta errada';
+$lang['Dimensions'] = 'Dimenções';
+$lang['Display'] = 'Afixação';
+$lang['Each listed rule must be satisfied.'] = 'Todos os criterios devem ser satisfeitos';
+$lang['Email address is missing'] = 'O endereço E-mail está ausente';
+$lang['Email address'] = 'Endereço E-mail';
+$lang['Enter your personnal informations'] = 'Introduza as suas informações pessoais';
+$lang['Error sending email'] = 'Erro durante o envio do E-mail';
+$lang['File name'] = 'Nome do ficheiro';
+$lang['File'] = 'Ficheiro';
+$lang['Filesize'] = 'Peso';
+$lang['Filter and display'] = 'Filtrar e afixar';
+$lang['Filter'] = 'Filtro';
+$lang['Forgot your password?'] = 'Palavra passe perdida ?';
+$lang['Go through the gallery as a visitor'] = 'Percorer a galeria como visitor';
+$lang['Help'] = 'Ajuda';
+$lang['Identification'] = 'Identificação';
+$lang['Image only RSS feed'] = 'Fluxo RSS das imagens';
+$lang['Keyword'] = 'Palavra chave';
+$lang['Links'] = 'Ligação';
+$lang['Mail address'] = $lang['Email address'];
+$lang['N/A'] = 'Não disponível';
+$lang['New on %s'] = 'Novo em %s';
+$lang['New password confirmation does not correspond'] = 'Erro de confirmação da palavra passe';
+$lang['New password sent by email'] = 'Nova palavra passe enviada por E-mail';
+$lang['No email address'] = 'Falta o endereço E-mail';
+$lang['No user matches this email address'] = 'O endereço E-mail não corresponde à nenhum usário';
+$lang['Notification'] = 'Notificação';
+$lang['Number of items'] = 'Número de elementos';
+$lang['Original dimensions'] = 'Dimenção original';
+$lang['Password forgotten'] = 'Palavra passe perdida';
+$lang['Password'] = 'Palavra passe';
+$lang['Post date'] = 'data de adição';
+$lang['Posted on'] = 'Adido em';
+$lang['Profile'] = 'Perfil';
+$lang['Quick connect'] = 'Coneção rápida';
+$lang['RSS feed'] = 'fluxo RSS';
+$lang['Rate'] = 'Nota';
+$lang['Register'] = 'Registar-se';
+$lang['Registration'] = 'Registro';
+$lang['Related tags'] = 'Tags ligados';
+$lang['Reset'] = 'Cancelar';
+$lang['Retrieve password'] = 'Recuperar uma palavra passe';
+$lang['Search rules'] = 'Critérios de busca';
+$lang['Search tags'] = 'Pesquisar os tags';
+$lang['Search'] = 'Pesquisar';
+$lang['See available tags'] = 'Ver os tags disponíveis';
+$lang['Send new password'] = 'Enviar a nova palavra passe';
+$lang['Since'] = 'desde ';
+$lang['Sort by'] = 'Classificação pelo(a)';
+$lang['Sort order'] = 'Ordem de classificação';
+$lang['Tag'] = 'Tag';
+$lang['Tags'] = 'Tags';
+$lang['The RSS notification feed provides notification on news from this website : new pictures, updated categories, new comments. Use a RSS feed reader.'] = 'O fluxo RSS notifica dos eventos da galeria : novas imagens, categorias actualizadas, Novos comentários usários. Para utilizar com um leitor de fluxos RSS.';
+$lang['Unknown feed identifier'] = 'identificador de fluxo desconhecido';
+$lang['User comments'] = 'Comentarios utilizador';
+$lang['Username'] = 'utilizador';
+$lang['Visits'] = 'Visitas';
+$lang['Webmaster'] = 'Webmaster';
+$lang['Week %d'] = 'Semana %d';
+$lang['about_page_title'] = 'A proposito de Piwigo';
+$lang['access_forbiden'] = 'Acesso proibido';
+$lang['add to caddie'] = 'Acrescentar ao carrinho';
+$lang['add_favorites_hint'] = 'Acrescentar aos favoritos';
+$lang['admin'] = 'Administração';
+$lang['adviser_mode_enabled'] = 'Modo conselheiro activo';
+$lang['all'] = 'tudo';
+$lang['ascending'] = 'crescente';
+$lang['author(s) : %s'] = 'autor(es) : %s';
+$lang['auto_expand'] = 'Desenvolver todas as categorias';
+$lang['became available after %s (%s)'] = 'posto a disposição depios do %s (%s)';
+$lang['became available before %s (%s)'] = 'posto a disposição antes do %s (%s)';
+$lang['became available between %s (%s) and %s (%s)'] = 'posto a disposição entre o %s (%s) e o %s (%s)';
+$lang['became available on %s'] = 'posto a disposição em %s';
+$lang['best_rated_cat'] = 'Mais notadas';
+$lang['best_rated_cat_hint'] = 'Afixar as imagens mais notadas';
+$lang['caddie'] = 'carrinho';
+$lang['calendar'] = 'Calendário';
+$lang['calendar_any'] = 'Tudo';
+$lang['calendar_hint'] = 'afixar ano por ano, mes por mes, dia por dia';
+$lang['calendar_picture_hint'] = 'afixar as imagens do ';
+$lang['calendar_view'] = 'Vista';
+$lang['chronology_monthly_calendar'] = 'Calendário mensual';
+$lang['chronology_monthly_list'] = 'Lista mensual';
+$lang['chronology_weekly_list'] = 'Lista semanal';
+$lang['click_to_redirect'] = 'Clique aqui se o navegador não vos recaminha.';
+$lang['comment date'] = 'data do comentário';
+$lang['comment'] = 'comentário';
+$lang['comment_added'] = 'O seu comentário foi registado';
+$lang['comment_anti-flood'] = 'Sistema conta abuso : Pedimos por favor de esperar antes de escrever um novo comentario';
+$lang['comment_not_added'] = 'O seu comentário não pôde ser registado porque não se conforma às regras de validação';
+$lang['comment_to_validate'] = 'Par ser visível, o seu comentário deve ser validado pelo administrador.';
+$lang['comment_user_exists'] = 'Este utilizador já existe';
+$lang['comments'] = 'Comentários';
+$lang['comments_add'] = 'deixar um comentário';
+$lang['created after %s (%s)'] = 'Criada depois do %s (%s)';
+$lang['created before %s (%s)'] = 'Criada antes do %s (%s)';
+$lang['created between %s (%s) and %s (%s)'] = 'Criada entre o %s (%s) e o %s (%s)';
+$lang['created on %s'] = 'criada em %s';
+$lang['customize'] = 'Personalizar';
+$lang['customize_page_title'] = 'Personalização da sua afixagem ';
+$lang['day'][0] = 'Domingo';
+$lang['day'][1] = 'Segunda-feira';
+$lang['day'][2] = 'Terça-feira';
+$lang['day'][3] = 'Quarta-feira';
+$lang['day'][4] = 'Quinta-eira';
+$lang['day'][5] = 'Seixta-feira';
+$lang['day'][6] = 'Sábado';
+$lang['default_sort'] = 'Por defeito';
+$lang['del_favorites_hint'] = 'suprimir esta fotografia das favoritas';
+$lang['delete'] = 'Suprimir';
+$lang['descending'] = 'decrescente';
+$lang['download'] = 'carregar';
+$lang['download_hint'] = 'carregar este ficheiro';
+$lang['edit'] = 'editar';
+$lang['err_date'] = 'data errada';
+$lang['excluded'] = 'excluído';
+$lang['favorite_cat'] = 'Minhas favoritas';
+$lang['favorite_cat_hint'] = 'afixar as minhas imagens favoritas';
+$lang['favorites'] = 'Favorita';
+$lang['first_page'] = 'Premeira';
+$lang['gallery_locked_message'] = 'A galeria esta bloqueada por causa de manutenção. Volte mais tarde.';
+$lang['generation_time'] = 'Página gerida em';
+$lang['guest'] = 'visitante';
+$lang['hello'] = 'Bom dia';
+$lang['hint_admin'] = 'disponível unicamente para os administradores';
+$lang['hint_category'] = 'afixa as imagens à raíz desta categoria';
+$lang['hint_comments'] = 'Ver os últimos comentarios utilizadores';
+$lang['hint_customize'] = 'personalisar a aparência da galeria';
+$lang['hint_search'] = 'pesquisar';
+$lang['home'] = 'página principal do sitio';
+$lang['identification'] = 'Identificação';
+$lang['images_available_cpl'] = 'nesta categoria';
+$lang['images_available_cat'] = 'em %d subcategoria';
+$lang['images_available_cats'] = 'em %d subcategorias';
+$lang['included'] = 'incluido';
+$lang['invalid_pwd'] = 'Palavra passe inválida!';
+$lang['language'] = 'Lingua';
+$lang['last %d days'] = '%d ultimos dias';
+$lang['last_page'] = 'Ultima';
+$lang['logout'] = 'Deconeção';
+$lang['mail_address'] = $lang['Email address'];
+$lang['mandatory'] = 'obrigatário';
+$lang['maxheight'] = 'Altura máxima das imágens';
+$lang['maxheight_error'] = 'A altura máxima das imágens deve ser superior a 50';
+$lang['maxwidth'] = 'Largura máxima das imágens';
+$lang['maxwidth_error'] = 'A largura máxima das imágens deve ser superior a 50';
+$lang['mode_created_hint'] = 'afixar um calendário por data de criação';
+$lang['mode_flat_hint'] = 'afixar a lista de todos os elementos das categorias e subcategorias';
+$lang['mode_normal_hint'] = 'voltar à afixagem normal';
+$lang['mode_posted_hint'] = 'afixar um calendário por data de adição';
+$lang['month'][10] = 'Outubro';
+$lang['month'][11] = 'Novembro';
+$lang['month'][12] = 'Dezembro';
+$lang['month'][1] = 'Janeiro';
+$lang['month'][2] = 'Fevereiro';
+$lang['month'][3] = 'Março';
+$lang['month'][4] = 'Abril';
+$lang['month'][5] = 'Maio';
+$lang['month'][6] = 'Junho';
+$lang['month'][7] = 'Julho';
+$lang['month'][8] = 'Agosto';
+$lang['month'][9] = 'Setembro';
+$lang['most_visited_cat'] = 'Mais vistas';
+$lang['most_visited_cat_hint'] = 'Afixar as imagens mais vistas';
+$lang['nb_image_line_error'] = 'O número de imagens por linha deve ser inteiro e não nulo';
+$lang['nb_image_per_row'] = 'Número de miniaturas por linha';
+$lang['nb_line_page_error'] = 'O número de linhas por página deve ser inteiro e não nulo';
+$lang['nb_row_per_page'] = 'Número de linhas por página';
+$lang['nbm_unknown_identifier'] = 'Identificador desconhecido';
+$lang['new_password'] = 'Nova palavra passe';
+$lang['new_rate'] = 'Vote para esta imagem';
+$lang['next_page'] = 'Seguinte';
+$lang['no_category'] = 'Página principal';
+$lang['no_rate'] = 'nenhuma nota';
+$lang['note_filter_day'] = 'Os elementos estão filtrados para afixar uniquamente os recentes de menos de %d dia.';
+$lang['note_filter_days'] = 'Os elementos estão filtrados para afixar uniquamente os recentes de menos de %d dias.';
+$lang['password updated'] = 'Palavra passe posta em dia';
+$lang['periods_error'] = 'O periode de novidade deve ser um inteiro positivo';
+$lang['picture'] = 'imagem';
+$lang['picture_high'] = 'Clique na imagem para vizualisa-la em alta definição';
+$lang['picture_show_metadata'] = 'Afixar as metadatas do ficheiro';
+$lang['powered_by'] = 'Propulsado por';
+$lang['preferences'] = 'Preferencia';
+$lang['previous_page'] = 'Anterior';
+$lang['random_cat'] = 'Imagem ao acaso ';
+$lang['random_cat_hint'] = 'afixar um conjunto aleatório de imagens';
+$lang['recent_cats_cat'] = 'Categorias recentes';
+$lang['recent_cats_cat_hint'] = 'afixar as categorias recentemente postas em dia ou criadas';
+$lang['recent_period'] = 'Período recente';  
+$lang['recent_pics_cat'] = 'Imagens recentes';
+$lang['recent_pics_cat_hint'] = 'afixar as imagens mais recentes';
+$lang['redirect_msg'] = 'Redirecção...';
+$lang['reg_err_login1'] = 'Faça favor introduzir um nome de utilizador';
+$lang['reg_err_login2'] = 'O nome de utilizador não deve terminar-se por um espaço';
+$lang['reg_err_login3'] = 'O nome de utilizador não deve começar por um espaço';
+$lang['reg_err_login5'] = 'Este nomede utilizador já existe';
+$lang['reg_err_mail_address'] = 'O endresso email deve ser da forma xxx@yyy.eee (exemplo : jack@altern.org)';
+$lang['reg_err_pass'] = 'Faça favor introduzir uma nova palavra passe';
+$lang['remember_me'] = 'Conecção automática';
+$lang['remove this tag'] = 'retirar este tag da lista';
+$lang['representative'] = 'Representente';
+$lang['return to homepage'] = 'regresso à página principal';
+$lang['search_author'] = 'Pesquisar um autor';
+$lang['search_categories'] = 'Pesquisar nas categorias';
+$lang['search_date'] = 'Pesquisar por data';
+$lang['search_date_from'] = 'Data';
+$lang['search_date_to'] = 'Data de fim';
+$lang['search_date_type'] = 'Tipo de data';
+$lang['search_keywords'] = 'Pesquisar uma palavra';
+$lang['search_mode_and'] = 'Pesquisar todas as palavras';
+$lang['search_mode_or'] = 'Pesquisar uma das palavras';
+$lang['search_one_clause_at_least'] = 'Pesquisa vazia. nenhum critério fornecido.';
+$lang['search_options'] = 'Opções de pesquisa';
+$lang['search_result'] = 'Resultados da pesquisa';
+$lang['search_subcats_included'] = 'Pesquisar nas subcategorias';
+$lang['search_title'] = 'Pesquisar';
+$lang['searched words : %s'] = 'Palavras pesquisadas : %s';
+$lang['send_mail'] = 'Contactar';
+$lang['set as category representative'] = 'Escolher como representante desta categoria';
+$lang['show_nb_comments'] = 'Afixar o número de comentarios';
+$lang['show_nb_hits'] = 'Afixar o número de vizualisações';
+$lang['slideshow'] = 'Diaporama';
+$lang['slideshow_stop'] = 'interromper o diaporama';
+$lang['special_categories'] = 'Espciais';
+$lang['sql_queries_in'] = 'Pesquisa SQL em';
+$lang['start_filter_hint'] = 'afixar uniquamente os elementos recentes';
+$lang['stop_filter_hint'] = 'regresar à afixagem de todos os elementos';
+$lang['the beginning'] = 'O principio';
+$lang['theme'] = 'Tema da interface';
+$lang['thumbnails'] = 'Miniaturas';
+$lang['title_menu'] = 'Menu';
+$lang['title_send_mail'] = 'Um comentário sobre o sítio';
+$lang['today'] = 'hoje';
+$lang['update_rate'] = 'Por em dia a sua nota';
+$lang['update_wrong_dirname'] = 'nome de repertório errado';
+$lang['upload_advise_filesize'] = 'o peso da imagem não deve exceder : ';
+$lang['upload_advise_filetype'] = 'o formato da imagem deve ser jpg, png ou gif';
+$lang['upload_advise_height'] = 'a altura da imagem não deve exceder : ';
+$lang['upload_advise_thumbnail'] = 'Optional, mas recomendado : escolher uma miniatura a associar';
+$lang['upload_advise_width'] = 'a largura da imagem não deve exceder : ';
+$lang['upload_author'] = 'Autor';
+$lang['upload_cannot_upload'] = 'impossível de transferir o ficheiro no servidor';
+$lang['upload_err_username'] = 'nome de utilizador ausente';
+$lang['upload_file_exists'] = 'este ficheiro já existe';
+$lang['upload_filenotfound'] = 'o formato do ficheiro não é um formato de imagem';
+$lang['upload_forbidden'] = 'impossível de inserir uma imagem nesta categoria';
+$lang['upload_name'] = 'Nome da imagem';
+$lang['upload_picture'] = 'Adir uma imagem';
+$lang['upload_successful'] = 'Imagem adida com succeso, um administrador deve validar para que ela seja visível';
+$lang['upload_title'] = 'Adir uma imagem';
+$lang['useful when password forgotten'] = 'útil em caso de palavra passe esquecida';
+$lang['qsearch'] = 'pesquisa rápida';
+$lang['Connected user: %s'] = 'Utilizador conectado: %s';
+$lang['IP: %s'] = 'IP: %s';
+$lang['Browser: %s'] = 'Navegador: %s';
+$lang['Author: %s'] = 'Autor: %s';
+$lang['Comment: %s'] = 'Comentario: %s';
+$lang['Delete: %s'] = 'Supressão: %s';
+$lang['Validate: %s'] = 'Validação: %s';
+$lang['Comment by %s'] = 'Comentario de %s';
+$lang['User: %s'] = 'Utilizador: %s';
+$lang['Email: %s'] = 'Email: %s';
+$lang['Admin: %s'] = 'Administração: %s';
+$lang['Registration of %s'] = 'Registro de %s';
+$lang['Category: %s'] = 'Catégoria: %s';
+$lang['Picture name: %s'] = 'Nome da imagem: %s';
+$lang['Creation date: %s'] = 'Data de criação: %d';
+$lang['Waiting page: %s'] = 'Página em espera: %s';
+$lang['Picture uploaded by %s'] = 'Imagem telecarregada por %s';
+// --------- Starting below: New or revised $lang ---- from version 1.7.1
+$lang['guest_must_be_guest'] = 'Estatuto do utilizador "guest" não conforme, utilização do estatuto por defeito. Faça favor avisar o awebmaster.';
+// --------- Starting below: New or revised $lang ---- from Butterfly (2.0)
+$lang['Administrator, webmaster and special user cannot use this method'] = 'Administrador, webmaster e utilizador especial não pódem utilizar este método';
+$lang['reg_err_mail_address_dbl'] = 'um utilizador já utiliza este endresso email';
+$lang['Category results for'] = 'Resultados das categorias para';
+$lang['Tag results for'] = 'Resultados dos tags para';
+$lang['from %s to %s'] = 'du %s ao %s';
+$lang['start_play'] = 'Leitura du diaporama';
+$lang['stop_play'] = 'Pausa do diaporama';
+$lang['start_repeat'] = 'Repetir o diaporama';
+$lang['stop_repeat'] = 'Não repetir o diaporama';
+$lang['inc_period'] = 'Reduzir a velocidade do diaporama';
+$lang['dec_period'] = 'Aumentar a velocidade do diaporama';
+$lang['Submit'] = 'Validar';
+$lang['Yes'] = 'sim';
+$lang['No'] = 'Não';
+$lang['%d element']='%d imagem';
+$lang['%d elements']='%d imagens';
+$lang['%d element are also linked to current tags'] = '%d imagem esta também ligada aos tags correntes';
+$lang['%d elements are also linked to current tags'] = '%d imagens estão também ligadas aos tags correntes';
+$lang['See elements linked to this tag only'] = 'Ver as imagens ligadas uniquamente a este tag';
+$lang['elements posted during the last %d days'] = 'imagens adidas nos %d ultimos dias';
+$lang['Choose an image'] = 'Escolher uma imagem para adir';
+$lang['Piwigo Help'] = 'Ajuda de Piwigo';
+$lang['Rank'] = 'Posição';
+$lang['group by letters'] = 'grupar por letras';
+$lang['letters'] = 'letras';
+$lang['show tag cloud'] = 'mostar a nuvem de tags';
+$lang['cloud'] = 'nuvem';
+?>
Index: /tags/2.0.2/language/pt_PT/install.lang.php
===================================================================
--- /tags/2.0.2/language/pt_PT/install.lang.php	(revision 3278)
+++ /tags/2.0.2/language/pt_PT/install.lang.php	(revision 3278)
@@ -0,0 +1,74 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+$lang['Installation'] = 'Instalação ';
+$lang['Initial_config'] = 'Configuração de base';
+$lang['Default_lang'] = 'Lingua por defeito da galeria';
+$lang['step1_title'] = 'Configuração da base de dados';
+$lang['step2_title'] = 'Configuração da conta administrador';
+$lang['Start_Install'] = 'Iniciar a instalação';
+$lang['reg_err_mail_address'] = 'O endresso email deve ser da forma xxx@yyy.eee (exemplo : jack@altern.org)';
+
+$lang['install_webmaster'] = 'Administrador';
+$lang['install_webmaster_info'] = 'Este identificante aparcerá a todos os visitantes.Vos servirá para administrar o sitio';
+
+$lang['step1_confirmation'] = 'Os parâmetros entardos estão correctos';
+$lang['step1_err_db'] = 'A conecção ao servidor esta OK, mas impossível de conectar-se a esta base de dados.';
+$lang['step1_err_server'] = 'Impossível de conectar-se ao servidor';
+
+$lang['step1_host'] = 'Hóspede MySQL';
+$lang['step1_host_info'] = 'localhost, sql.multimania.com, toto.freesurf.fr';
+$lang['step1_user'] = 'Utilizador';
+$lang['step1_user_info'] = 'nome de utilizador por seu Hóspede';
+$lang['step1_pass'] = 'Palavra passe';
+$lang['step1_pass_info'] = 'fornecido pelo seu Hóspede';
+$lang['step1_database'] = 'Nome da base';
+$lang['step1_database_info'] = 'fornecido pelo seu Hóspede';
+$lang['step1_prefix'] = 'Prefixo dos nomes das tabelas';
+$lang['step1_prefix_info'] = 'O nome das tabelas aparcerá com este prefixo.(Permite de gerir melhor a sua base de dados)';
+$lang['step2_err_login1'] = 'Faça favor escolher um pseudónimo para o webmaster';
+$lang['step2_err_login3'] = 'O pseudónimo do webmasterle nao deve conter os carácters " et \'';
+$lang['step2_err_pass'] = 'Faça favor escrever de novo a sua palavra passe';
+$lang['install_end_title'] = 'Instalação acabada';
+$lang['step2_pwd'] = 'Palavra passe';
+$lang['step2_pwd_info'] = 'Deve ficar confidencial, permite de acedir ao panel de administração.';
+$lang['step2_pwd_conf'] = 'Palavra passe [ Confirmar ]';
+$lang['step2_pwd_conf_info'] = 'Verificação';
+$lang['step1_err_copy'] = 'Copais o texto core de rosa entre os tracinhos e colais-o no ficheiro mysql.inc.php no repertorio "include" à raiz de onde instalou Piwigo (O ficheiro mysql.inc.php só deve compter o que é core de rose entre os tracinhos, nenhum retorno de linha ou esapço são autorizados)';
+$lang['install_help'] = 'precisa de ajuda ? faça a sua pergunta <a href="%s">forum de Piwigo</a>.';
+$lang['install_end_message'] = 'A configuração da aplicação correu bem, vamos a proxima fase<br /><br />
+* Ide à página de indentificação e conecte-se com o pseudónimo escolhido para o webmaster<br />
+* Perite-vos acedir à parte de administração e as instruções para meter as imagens nos repertorios.';
+$lang['conf_mail_webmaster'] = 'Endresso Email do administrador';
+$lang['conf_mail_webmaster_info'] = 'Os visitantes poderam contactar-vos pelo este Email';
+
+$lang['PHP 5 is required'] = 'PHP 5 é requerido';
+$lang['It appears your webhost is currently running PHP %s.'] = 'Aparentemente, a versão PHP do seu  Apparemment, a versão PHP do seu hospede é PHP %s.';
+$lang['Piwigo may try to switch your configuration to PHP 5 by creating or modifying a .htaccess file.'] = 'Piwigo vai tentar passar em PHP 5 criando ou modificando o ficheiro .htaccess.';
+$lang['Note you can change your configuration by yourself and restart Piwigo after that.'] = 'notei que pode modificar a configuração PHP e lançar de novo Pigiwo depois.';
+$lang['Try to configure PHP 5'] = 'Tente configurar PHP 5Essayer de configurer PHP 5';
+$lang['Sorry!'] = 'Infelizmente!';
+$lang['Piwigo was not able to configure PHP 5.'] = 'Piwigo não pôde configurar PHP 5.';
+$lang["You may referer to your hosting provider's support and see how you could switch to PHP 5 by yourself."] = 'Deve contactar seu hospede afins de saber como configurar PHP 5.';
+$lang['Hope to see you back soon.'] = 'Eperando vê-lo de novo em breve...';
+?>
Index: /tags/2.0.2/language/pt_PT/iso.txt
===================================================================
--- /tags/2.0.2/language/pt_PT/iso.txt	(revision 3278)
+++ /tags/2.0.2/language/pt_PT/iso.txt	(revision 3278)
@@ -0,0 +1,1 @@
+Português [PT]
Index: /tags/2.0.2/language/ru_RU/about.html
===================================================================
--- /tags/2.0.2/language/ru_RU/about.html	(revision 3278)
+++ /tags/2.0.2/language/ru_RU/about.html	(revision 3278)
@@ -0,0 +1,7 @@
+  <li>Piwigo - это скрипт, позволяющий легко создать онлайн галерею фотографий.</li>
+
+  <li>Галерея Piwigo создана с помощью PHP (elePHPant) с использованием базы данных MySQL (SQuirreL).</li>
+
+  <li>Если у Вас есть какие-либо пожелания или комментарии по скрипту, оставьте их на официальном сайте <a
+  href="http://piwigo.org">Piwigo</a>, и его <a href="http://piwigo.org/forum">форуме</a>.</li>
+
Index: /tags/2.0.2/language/ru_RU/admin.lang.php
===================================================================
--- /tags/2.0.2/language/ru_RU/admin.lang.php	(revision 3278)
+++ /tags/2.0.2/language/ru_RU/admin.lang.php	(revision 3278)
@@ -0,0 +1,650 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008      Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+$lang['%d association'] = '%d связь';
+$lang['%d associations'] = '%d связей';
+$lang['cat_inclu_part1_S'] = '%d категория добавлена ';
+$lang['cat_inclu_part1_P'] = 'категорий добавлено: %d';
+$lang['cat_inclu_part2_S'] = '%d реальная';
+$lang['cat_inclu_part2_P'] = '%d реальных';
+$lang['cat_inclu_part3_S'] = ' и %d виртуальная';
+$lang['cat_inclu_part3_P'] = ' и %d виртуальных';
+$lang['%d category moved'] = '%d категория перемещена';
+$lang['%d categories moved'] = '%d категорий перемещено';
+$lang['%d group'] = '%d группа';
+$lang['%d groups'] = '%d групп';
+$lang['%d member'] = '%d участник';
+$lang['%d members'] = '%d участников';
+$lang['%d tag'] = '%d слово';
+$lang['%d tags'] = '%d слов';
+$lang['%d user comment rejected'] = '%d комментарий посетителя отклонен';
+$lang['%d user comments rejected'] = '%d комментариев посетителей отклонено';
+$lang['%d user comment validated'] = '%d комментарий посетителя принят';
+$lang['%d user comments validated'] = '%d комментариев посетителей принято';
+$lang['%d user deleted'] = '%d пользователь удален';
+$lang['%d users deleted'] = '%d пользователей удалено';
+$lang['%d user'] = '%d пользователь';
+$lang['%d users'] = '%d пользователей';
+$lang['%d waiting for validation'] = '%d ожидает проверки';
+$lang['%d waiting pictures rejected'] = '%d проверяемых картинок отклонено';
+$lang['%d waiting pictures validated'] = '%d проверяемых картинок принято';
+$lang['Actions'] = 'Действия';
+$lang['Activate'] = 'Активировать';
+$lang['Add/delete a permalink'] = 'Добавить/удалить постоянную ссылку';
+$lang['Add a tag'] = 'Добавить слово';
+$lang['Add a user'] = 'Добавить пользователя';
+$lang['Add group'] = 'Добавить группу';
+$lang['Add selected elements to caddie'] = 'Добавить выбранные элементы в корзину';
+$lang['Add'] = 'Добавить';
+$lang['Allow user registration'] = 'Разрешить регистрацию пользователей';
+$lang['Apply to subcategories'] = 'Применить к подкатегориям';
+$lang['Are you sure?'] = 'Уверены?';
+$lang['Associated'] = 'Связаны';
+$lang['Association to categories'] = 'Связь с категориями';
+$lang['Batch management'] = 'Пакетная обработка';
+$lang['Caddie management'] = 'Управление корзиной';
+$lang['Caddie'] = 'Корзина';
+$lang['Categories authorized thanks to group associations'] = 'Категории, разрешенные благодаря связи с группой';
+$lang['Categories manual order was saved'] = 'Особый порядок категорий сохранен';
+$lang['Categories ordered alphanumerically'] = 'Категории отсортированы по алфавиту';
+$lang['Category elements associated to the following categories: %s'] = 'Фотографии категории, связаны со следующими категориями: %s';
+$lang['Check for upgrade failed for unknown reasons.'] = 'Проверка обновлений не удалась по неизвестным причинам.';
+$lang['Check for upgrade'] = 'Проверить обновления';
+$lang['Comments for all'] = 'Комментарии для всех';
+$lang['Controversy'] = 'Противоречие';
+$lang['Current name'] = 'Текущее название';
+$lang['Database'] = 'База данных';
+$lang['Deactivate'] = 'Выключить';
+$lang['Delete Representant'] = 'Удалить представителя';
+$lang['Delete selected tags'] = 'Удалить выбранные слова';
+$lang['Delete selected users'] = 'Удалить выбранных пользователей';
+$lang['Deletions'] = 'Удаления';
+$lang['Deny selected groups'] = 'Отмена выбора групп';
+$lang['Deny selected users'] = 'Отмена выбора пользователей';
+$lang['Description'] = 'Описание';
+$lang['Display options'] = 'Варианты показа';
+$lang['Dissociated'] = 'Не связанные';
+$lang['Does not represent'] = 'Нет представителя';
+$lang['Edit all picture informations'] = 'Редактировать всю информацию о фотографии';
+$lang['Edit selected tags'] = 'Редактировать выделенные слова';
+$lang['Edit tags'] = 'Редактировать слова';
+$lang['Elements'] = 'Элементы';
+$lang['Email administrators when a new user registers'] = 'Сообщать администратору когда зарегистрировался новый посетитель';
+$lang['Email administrators when a valid comment is entered'] = 'Сообщать администратору когда появился комментарий';
+$lang['Email administrators when a comment requires validation'] = 'Сообщать администратору когда появился комментарий для проверки';
+$lang['Email administrators when a picture is uploaded'] = 'Сообщать администратору когда загружена фотография';
+$lang['Empty caddie'] = 'Очистить корзину';
+$lang['Environment'] = 'Окружение';
+$lang['Form'] = 'Действия';
+$lang['Gallery URL'] = 'Адрес галереи';
+$lang['Gallery description'] = 'Описание галереи';
+$lang['Gallery title'] = 'Название галереи';
+$lang['Grant selected groups'] = 'Разрешить доступ выбранным группам';
+$lang['Grant selected users'] = 'Разрешить доступ выбранным пользователям';
+$lang['Group name'] = 'Название группы';
+$lang['Groups'] = 'Группы';
+$lang['Guests'] = 'Гости';
+$lang['History'] = 'История';
+$lang['Informations'] = 'Информация';
+$lang['Install'] = 'Установить';
+$lang['Link all category elements to a new category'] = 'Привязать все элементы этой категории к новой';
+$lang['Link all category elements to some existing categories'] = 'Привязать все элементы этой категории к одной из существующих';
+$lang['Linked categories'] = 'Привязанные категории';
+$lang['Lock gallery'] = 'Заблокировать галерею';
+$lang['Maintenance'] = 'Обслуживание';
+$lang['Manage permissions for a category'] = 'Управление разрешениями для категории';
+$lang['Manage permissions for group "%s"'] = 'Управление разрешениями для группы "%s"';
+$lang['Manage permissions for user "%s"'] = 'Управление разрешениями для пользователя "%s"';
+$lang['Manage tags'] = 'Управление словами';
+$lang['Members'] = 'Участники';
+$lang['Metadata synchronized from file'] = 'Метаданные синхронизированы с файлом';
+$lang['Move categories'] = 'Перемещение категорий';
+$lang['Move'] = 'Перемещение';
+$lang['Name'] = 'Название';
+$lang['New name'] = 'Новое название';
+$lang['New parent category'] = 'Новая родительская категория';
+$lang['New tag'] = 'Новое слово';
+$lang['No tag defined. Use Administration>Pictures>Tags'] = 'Слова не определены. Используйте Администрирование>Фотографии>Ключевые слова';
+$lang['Number of comments per page'] = 'Количество комментариев на странице';
+$lang['Number of rates'] = 'Количество оценок';
+$lang['Number of thumbnails to create'] = 'Количество создаваемых миниатюр';
+$lang['Only private categories are listed'] = 'Показ только скрытых категорий';
+$lang['Operating system'] = 'Операционная система';
+$lang['Options'] = 'Опции';
+$lang['Order alphanumerically'] = 'По алфавиту';
+$lang['Other private categories'] = 'Доступ к приватным категориям';
+$lang['Page banner'] = 'Надпись на баннере';
+$lang['Parent category'] = 'Родительская категория';
+$lang['Path'] = 'Путь';
+$lang['Permalink'] = 'Постоянная ссылка';
+$lang['Permalink_%s_histo_used_by_%s'] = 'Постоянная ссылка %s была ранее использована для категории %s. Удалите ее сначала из истории постоянных ссылок';
+$lang['Permalink_name_rule'] = 'Имя постоянной ссылки должно состоять из a-z, A-Z, 0-9, "-" или "_". Оно не должно быть числовым или начинаться с числа с "-"';
+$lang['Permalink %s is already used by category %s'] = 'Постоянная ссылка %s уже используется для категории %s';
+$lang['Permalink history'] = 'История постоянных ссылок';
+$lang['Permalinks'] = 'Постоянные ссылки';
+$lang['Permission denied'] = 'Доступ запрещен';
+$lang['Permission granted thanks to a group'] = 'Доступ для группы разрешен';
+$lang['Permission granted'] = 'Доступ разрешен';
+$lang['Picture informations updated'] = 'Информация об изображении обновлена';
+$lang['Plugins'] = 'Плагины';
+$lang['Position'] = 'Номер';
+$lang['Preferences'] = 'Настройки';
+$lang['Properties'] = 'Свойства';
+$lang['Random picture'] = 'Случайное изображение';
+$lang['Rate date'] = 'Rate date';
+$lang['Rating by guests'] = 'Оценки от гостей';
+$lang['Rating'] = 'Оценки';
+$lang['Reject All'] = 'Отклонить все';
+$lang['Reject'] = 'Отклонить';
+$lang['Representant'] = 'Представитель';
+$lang['Representation of categories'] = 'Представление категорий';
+$lang['Representative'] = 'Представитель';
+$lang['Represents'] = 'Представляет';
+$lang['Save order'] = 'Сохранить порядок';
+$lang['Save to permalink history'] = 'Сохранить историю постоянных ссылок';
+$lang['Select at least one category'] = 'Выберите хотя бы одну категорию';
+$lang['Select at least one picture'] = 'Выберите хотя бы одно изображение';
+$lang['Select at least one user'] = 'Выберите хотя бы одного пользователя';
+$lang['Show info'] = 'Показать информацию';
+$lang['Site manager'] = 'Управление сайтами';
+$lang['Status'] = 'Статус';
+$lang['Statistics'] = 'Статистика';
+$lang['Storage category'] = 'Категория хранения';
+$lang['Sum of rates'] = 'Суммарная оценка';
+$lang['Tag "%s" already exists'] = 'Слово "%s" уже есть';
+$lang['Tag "%s" was added'] = 'Слово "%s" добавлено';
+$lang['Tag selection'] = 'Выбор слов';
+$lang['Take selected elements out of caddie'] = 'Убрать выбранные элементы из корзины';
+$lang['The %d following tag were deleted'] = 'Указанное слово удалено';
+$lang['The %d following tags were deleted'] = '%d указанных слов удалено';
+$lang['Unable to check for upgrade since allow_url_fopen is disabled.'] = 'Невозможно проверить обновления пока %allow_url_fopen недоступен.';
+$lang['Uninstall'] = 'Деинсталляция';
+$lang['Use default sort order']='Сортировка изображений по умолчанию (как определено в файле конфигурации)';
+$lang['User comments validation'] = 'Проверка комментариев посетителей';
+$lang['Users'] = 'Пользователи';
+$lang['Validate All'] = 'Принять все';
+$lang['Validate'] = 'Принять';
+$lang['Validation'] = 'Проверка';
+$lang['Version'] = 'Версия';
+$lang['Virtual categories movement'] = 'Перемещение виртуальных категорий';
+$lang['Virtual categories to move'] = 'Виртуальные категории для перемещения';
+$lang['Virtual category name'] = 'Название виртуальной категории';
+$lang['Webmaster cannot be deleted'] = 'Нельзя удалить Вебмастера';
+$lang['You are running on development sources, no check possible.'] = 'Выполняется в режиме разработки, проверка невозможна.';
+$lang['You cannot delete your account'] = "Вы не можете удалить свой аккаунт";
+$lang['You cannot move a category in its own sub category'] = 'Вы не можете переместить категорию в ее собственную подкатегорию';
+$lang['You need to confirm deletion'] = 'Вам нужно подтвердить удаление';
+$lang['add tags'] = 'добавить слова';
+$lang['adviser'] = 'Помощник';
+$lang['associate to category'] = 'привязать к категории';
+$lang['associate to group'] = 'привязать к группе';
+$lang['authorized'] = 'Разрешено';
+$lang['cat_add'] = 'Добавить виртуальную категорию';
+$lang['cat_comments_title'] = 'Позволить пользователям добавлять комментарии к выбранным категориям';
+$lang['cat_error_name'] = 'Название категории не должно быть пустым';
+$lang['cat_lock_title'] = 'Заблокировать категории';
+$lang['cat_private'] = 'Приватная категория';
+$lang['cat_public'] = 'Общедоступная категория';
+$lang['cat_representant'] = 'Найти нового представителя случайным образом';
+$lang['cat_security'] = 'Общедоступные / Приватные';
+$lang['cat_status_title'] = 'Управление авторизацией для выбранных категорий';
+$lang['cat_upload_title'] = 'Выбор категорий в которые возможна загрузка';
+$lang['cat_virtual_added'] = 'Виртуальная категория добавлена';
+$lang['cat_virtual_deleted'] = 'Виртуальная категория удалена';
+$lang['category'] = 'категория';
+$lang['conf_access'] = 'Тип доступа';
+$lang['conf_comments_title'] = 'Комментарии';
+$lang['conf_confirmation'] = 'Информация зарегистрирована в базе данных';
+$lang['conf_display'] = 'Вид по умолчанию';
+$lang['conf_history_title'] = 'История';
+$lang['conf_gallery_url_error'] = 'Некорректный URL галереи';
+$lang['conf_main_title'] = 'Главная';
+$lang['conf_nb_comment_page_error'] = 'На странице может быть от 5 до 50 комментариев.';
+$lang['config'] = 'Настройки';
+$lang['confirm'] = 'подтверждение';
+$lang['date'] = 'дата';
+$lang['delete category'] = 'удалить категорию';
+$lang['dissociate from category'] = 'отвязать от категории';
+$lang['dissociate from group'] = 'отвязать от группы';
+$lang['edit category permissions'] = 'редактировать права для категории';
+$lang['editcat_confirm'] = 'Информация о категории обновлена успешно.';
+$lang['editcat_uploadable'] = 'Разрешить загрузку';
+$lang['elements per page'] = 'миниатюр на странице';
+$lang['elements'] = 'элементы';
+$lang['enabled_high'] = 'Доступно высокое разрешение';
+$lang['file'] = 'файл';
+$lang['filesize'] = 'размер файла';
+$lang['first element added on %s'] = 'первый элемент добавлен %s';
+$lang['forbidden'] = 'Запрещено';
+$lang['conf_general'] = 'Основные';
+$lang['global mode'] = 'групповой режим';
+$lang['group "%s" added'] = 'группа "%s" добавлена';
+$lang['group "%s" deleted'] = 'группа "%s" удалена';
+$lang['group "%s" updated'] = 'группа "%s" обновлена';
+$lang['group'] = 'группа';
+$lang['group_add_error1'] = 'Название группы не должно содержать " и \' или быть пустым.';
+$lang['group_add_error2'] = 'Это название уже используется для другой группы.';
+$lang['groups'] = 'Группы';
+$lang['instructions'] = 'Инструкции';
+$lang['is_high_disabled'] = '';
+$lang['is_high_enabled'] = 'Большое разрешение';
+$lang['jump to category'] = 'перейти в категорию';
+$lang['jump to image'] = 'перейти к фотографии';
+$lang['leave'] = 'оставить';
+$lang['lock'] = 'Блокировка';
+$lang['locked'] = 'Заблокировано';
+$lang['manage category elements'] = 'управление фотографиями категории';
+$lang['manage sub-categories'] = 'управление подкатегориями';
+$lang['manage'] = 'Управление';
+$lang['maximum height'] = 'максимальная высота';
+$lang['maximum width'] = 'максимальная ширина';
+$lang['nbm_background_treatment_redirect_second'] = 'Время выполнения превышено, обработка должна быть продолжена [Рассчетное время: %d сек].';
+$lang['nbm_background_treatment_redirect_seconds'] = 'Время выполнения превышено, обработка должна быть продолжена [Рассчетное время: %d сек].';
+$lang['nbm_break_timeout_list_user'] = 'Время подготовки списка пользователей для рассылки ограничено. Остальные пользователи не выведены.';
+$lang['nbm_break_timeout_send_mail'] = 'Время для отправки почты ограничено. Другие письма пропущены.';
+$lang['nbm_col_check_user_send_mail'] = 'Отправить?';
+$lang['nbm_col_last_send'] = 'Последнее отправленное';
+$lang['nbm_col_mail'] = 'email';
+$lang['nbm_col_user'] = 'Пользователь';
+$lang['nbm_complementary_mail_content'] = 'Содержание письма';
+$lang['nbm_content_byebye'] = 'Пока,';
+$lang['nbm_content_goto_1'] = 'Перейти к ';
+$lang['nbm_content_goto_2'] = '.';
+$lang['nbm_content_hello_1'] = 'Привет ';
+$lang['nbm_content_hello_2'] = ',';
+$lang['nbm_content_new_elements'] = 'Новые элементы добавлены ';
+$lang['nbm_content_new_elements_single'] = ' в ';
+$lang['nbm_content_new_elements_between_1'] = 'между ';
+$lang['nbm_content_new_elements_between_2'] = ' и ';
+$lang['nbm_content_subscribe_by_admin'] = 'Вебмастер подписал Вас на получение уведомлений по почте.';
+$lang['nbm_content_subscribe_by_himself'] = 'Вы подписались на получение уведомлений по почте.';
+$lang['nbm_content_subscribe_link'] = 'Для подписки';
+$lang['nbm_content_problem_contact'] = 'Если у Вас возникнут проблемы или вопросы, пожалуйста, напишите ';
+$lang['nbm_content_pb_contact_object'] = 'Проблемы и вопросы';
+$lang['nbm_content_unsubscribe_by_admin'] = 'Вебмастер удалил подписку на получение уведомлений по почте.';
+$lang['nbm_content_unsubscribe_by_himself'] = 'Вы удалили подписку на получение уведомлений по почте.';
+$lang['nbm_content_click_on'] = ', щелкните на ';
+$lang['nbm_content_unsubscribe_link'] = 'Чтобы отменить подписку';
+$lang['nbm_info_send_mail_as'] = 'Если не заполнено, будет использовано название галереи';
+$lang['nbm_item_notification'] = 'Уведомления';
+$lang['nbm_msg_error_sending_email_to'] = 'Ошибка отправки почты для %s [%s].';
+$lang['nbm_msg_mail_sent_to'] = 'Письмо отправлено для %s [%s].';
+$lang['nbm_msg_n_mail_sent'] = 'Отправлено письмо: %d.';
+$lang['nbm_msg_n_mails_sent'] = 'Отправлено писем: %d.';
+$lang['nbm_msg_n_mail_not_send'] = 'Не отправлено письмо: %d.';
+$lang['nbm_msg_n_mails_not_send'] = 'Не отправлено писем: %d.';
+$lang['nbm_no_mail_to_send'] = 'Нет писем для отправки.';
+$lang['nbm_no_user_available_to_send_L1'] = 'Нет пользователей, которым можно было бы отправить почту.';
+$lang['nbm_no_user_available_to_send_L2'] = 'Пользователи доступны, если есть новые элементы уведомлений.';
+$lang['nbm_no_user_available_to_send_L3'] = 'Возможно, нет подписанных пользователей (только webmaster может видеть это).';
+$lang['nbm_no_user_to send_notifications_by_mail'] = 'Нет пользователей, чтобы послать уведомления почтой.';
+$lang['nbm_object_news'] = 'Добавлен новый элемент';
+$lang['nbm_object_subscribe'] = 'Подписаться на уведомления по почте';
+$lang['nbm_object_unsubscribe'] = 'Отписаться от уведомлений по почте';
+$lang['nbm_param_mode'] = 'Параметры';
+$lang['nbm_redirect_msg'] = 'Обработка обращения.'."\n\n".'Пожалуйста, подождите ...';
+$lang['nbm_repost_submit'] = 'Продолжить обработку обращения';
+$lang['nbm_send_complementary_mail_content'] = 'Дополнительное содержание письма';
+$lang['nbm_send_detailed_content'] = 'Добавить дополнительное содержание';
+$lang['nbm_send_mail_as'] = 'Отправить письмо от';
+$lang['nbm_send_mail_to_users'] = 'Отправить письмо пользователю';
+$lang['nbm_send_mode'] = 'Отправка';
+$lang['nbm_send_options'] = 'Параметры';
+$lang['nbm_send_submit'] = 'Отправить';
+$lang['nbm_subscribe_col'] = 'В списке рассылки';
+$lang['nbm_subscribe_mode'] = 'Список рассылки';
+$lang['nbm_title_param'] = 'Параметры';
+$lang['nbm_title_send'] = 'Выбрать получателей';
+$lang['nbm_title_subscribe'] = 'Добавление/удаление пользователей в список рассылки';
+$lang['nbm_unsubscribe_col'] = 'Не в списке рассылки';
+$lang['nbm_updated_param_count'] = '%d параметр обновлен.';
+$lang['nbm_updated_params_count'] = '%d параметров обновлено.';
+$lang['nbm_user_change_enabled_error_on_updated_data_count'] = '%d пользователь не обновлен.';
+$lang['nbm_users_change_enabled_error_on_updated_data_count'] = '%d пользователей не обновлено.';
+$lang['nbm_user_change_enabled_false'] = 'Пользователь %s [%s] удален из списка рассылки.';
+$lang['nbm_user_change_enabled_true'] = 'Пользователь %s [%s] добавлен в список рассылки.';
+$lang['nbm_user_change_enabled_updated_data_count'] = '%d пользователь изменен.';
+$lang['nbm_users_change_enabled_updated_data_count'] = '%d пользователей изменено.';
+$lang['nbm_user_not_change_enabled_false'] = 'Пользователь %s [%s] не удален из списка рассылки.';
+$lang['nbm_user_not_change_enabled_true'] = 'Пользователь %s [%s] не добавлен в список рассылки.';
+$lang['nbm_user_x_added'] = 'Пользователь %s [%s] добавлен.';
+$lang['nbm_warning_subscribe_unsubscribe'] = 'Внимание: при добавлении/удалении в список рассылки будет отправлено уведомление пользователям';
+$lang['nbm_send_html_mail'] = 'Отправить письмо в HTML формате';
+$lang['nbm_send_recent_post_dates'] = 'Включить отображение последних фотографий сгруппированных по дате';
+$lang['nbm_info_send_recent_post_dates'] = 'Возможно только в HTML формате';
+$lang['no_write_access'] = 'нет доступа на запись';
+$lang['path'] = 'путь';
+$lang['permissions'] = 'Разрешения';
+$lang['private'] = 'приватная';
+$lang['properties'] = 'Свойства';
+$lang['public'] = 'общедоступная';
+$lang['purge never used notification feeds'] = 'очистить неиспользуемые каналы уведомлений';
+$lang['purge sessions'] = 'очистить сессии';
+$lang['randomly represented'] = 'случайный представитель';
+$lang['registration_date'] = 'дата регистрации';
+$lang['remote_site'] = 'Удаленный сайт';
+$lang['remote_site_clean'] = 'очистить';
+$lang['remote_site_clean_hint'] = 'удалить удаленный файл listing.xml';
+$lang['remote_site_generate'] = 'создать листинг';
+$lang['remote_site_generate_hint'] = 'создать файл listing.xml на удаленном сайте';
+$lang['remote_site_local_create'] = 'Создать этот сайт';
+$lang['remote_site_local_found'] = 'Локальный файл listing.xml file был найден ';
+$lang['remote_site_local_update'] = 'читать локальный файл listing.xml и обновить';
+$lang['remote_site_test'] = 'тест';
+$lang['remote_site_test_hint'] = 'тестировать этот удаленный сайт';
+$lang['remote_site_uncorrect_url'] = 'Url удаленного сайта должен начинаться с http или https и должен содержать символы "/", "a-zA-Z0-9", "-" или "_"';
+$lang['remove tags'] = 'удалить слова';
+$lang['repair and optimize database'] = 'исправить и оптимизировать базу данных';
+$lang['selection'] = 'отмеченные';
+$lang['set to'] = 'изменить на';
+$lang['singly represented'] = 'выбранный представитель';
+$lang['site_already_exists'] = 'Такой сайт уже есть';
+$lang['site_create'] = 'Создать новый сайт: (введите URL в create_listing_file.php)';
+$lang['site_created'] = 'создан';
+$lang['site_delete'] = 'удален';
+$lang['site_delete_hint'] = 'удалить этот сайт и все прикрепленные элементы';
+$lang['site_deleted'] = 'удален';
+$lang['site_err'] = 'произошла ошибка';
+$lang['site_err_remote_file_not_found'] = 'файл create_listing_file.php не найден на удаленном сайте';
+$lang['site_local'] = 'Локальный';
+$lang['site_remote'] = 'Удаленный';
+$lang['site_synchronize'] = 'синхронизировать';
+$lang['site_synchronize_hint'] = 'обновить базу данных из файлов';
+$lang['status'] = 'статус';
+$lang['storage'] = 'Папка';
+$lang['sub-categories'] = 'подкатегории';
+$lang['synchronize metadata'] = 'синхронизировать метаданные';
+$lang['synchronize'] = 'синхронизировать';
+$lang['target'] = 'изменить';
+$lang['thumbnail'] = 'миниатюра';
+$lang['title'] = 'Название';
+$lang['title_categories'] = 'Управление категориями';
+$lang['title_configuration'] = 'Настройка PhpWebGallery';
+$lang['title_default'] = 'Администрирование PhpWebGallery';
+$lang['title_edit_cat'] = 'Редактирование категории';
+$lang['title_groups'] = 'Управление группами';
+$lang['title_liste_users'] = 'Список пользователей';
+$lang['title_picmod'] = 'Изменить информацию об изображении';
+$lang['title_thumbnails'] = 'Создание миниатюр';
+$lang['title_update'] = 'Синхронизация базы данных с файлами';
+$lang['title_upload'] = 'Проверка присланных фотографий';
+$lang['tn_all'] = 'все';
+$lang['tn_alone_title'] = 'изображения без миниатюр (только jpeg и png)';
+$lang['tn_err_height'] = 'высота должна быть числом больше';
+$lang['tn_err_width'] = 'ширина должна быть числом больше';
+$lang['tn_format'] = 'для файла формата';
+$lang['tn_no_missing'] = 'Миниатюры есть у всех изображений';
+$lang['tn_no_support'] = 'Изображение недоступно или не поддерживается';
+$lang['tn_params_GD'] = 'версия GD';
+$lang['tn_params_title'] = 'Параметры миниатюризации';
+$lang['tn_results_gen_time'] = 'создано за';
+$lang['tn_results_title'] = 'Результаты миниатюризации';
+$lang['tn_stats'] = 'Общая статистика';
+$lang['tn_stats_max'] = 'максимальное время';
+$lang['tn_stats_mean'] = 'среднее время';
+$lang['tn_stats_min'] = 'минимальное время';
+$lang['tn_stats_nb'] = 'количество уменьшенных изображений';
+$lang['tn_stats_total'] = 'общее время';
+$lang['tn_thisformat'] = 'для этого формата файла';
+$lang['unit mode'] = 'одиночный режим';
+$lang['unlocked'] = 'Разблокировать';
+$lang['unset'] = 'очистить';
+$lang['up'] = 'Переместить вверх';
+$lang['update categories informations'] = 'обновить информацию о категориях';
+$lang['update images informations'] = 'обновить информацию о фотографиях';
+$lang['update'] = 'Синхронизация';
+$lang['update_cats_subset'] = 'проверить только категорию';
+$lang['update_default_title'] = 'Выберите параметры';
+$lang['update_display_info'] = 'показать максимум информации (добавленные категории и фотографии, удаленные категории и элементы)';
+$lang['update_err_pwg_version_differs'] = 'версия PhpWebGallery отличается на удаленном сайте';
+$lang['update_err_pwg_version_differs_info'] = 'Версии create_listing_file.php на удаленном сайте и PhpWebGallery должны быть одинаковыми';
+$lang['update_err_remote_listing_not_found'] = 'файл listing.xml не найден';
+$lang['update_err_remote_listing_not_found_info'] = 'файл listing.xml не найден на удаленном сайте. Этот файл создается при выборе команды "создать листинг" в Управлении сайтами';
+$lang['update_error_list_title'] = 'Список ошибок';
+$lang['update_errors_caption'] = 'Обозначение ошибки';
+$lang['update_infos_title'] = 'Детальная информация';
+$lang['update_missing_file_or_dir'] = 'Ошибка чтения файла/папки';
+$lang['update_missing_file_or_dir_info'] = 'Нет доступа к файлу или папке (возможно они отсутствуют или доступ к ним запрещен)';
+$lang['update_missing_tn_info'] = 'для этого типа файлов нужна миниатюра. Миниатюры должны находиться в подпапке "thumbnail" папки категории. Имя файла миниатюры должно начинаться с указанного в конфигурации префикса, расширение должно быть одним из нижеперечисленных:';
+$lang['update_missing_tn_short'] = 'отсутствуют миниатюры';
+$lang['update_nb_del_categories'] = 'категорий удалено из базы данных';
+$lang['update_nb_del_elements'] = 'элементов удалено из базы данных';
+$lang['update_nb_elements_metadata_available'] = 'изображений для синхронизации метаданных';
+$lang['update_nb_elements_metadata_sync'] = 'информация об элементах синхронизирована с метаданными файлов';
+$lang['update_nb_errors'] = 'ошибок синхронизации';
+$lang['update_nb_new_categories'] = 'категорий добавлено в базу данных';
+$lang['update_nb_new_elements'] = 'элементов добавлено в базу данных';
+$lang['update_nb_upd_elements'] = 'элементов обновлено в базе данных';
+$lang['update_part_research'] = 'Поиск новых изображений в папках';
+$lang['update_research_added'] = 'добавлена';
+$lang['update_research_deleted'] = 'удалена';
+$lang['update_result_metadata'] = 'Результаты синхронизации метаданных';
+$lang['update_simulate'] = 'только тестировать (не вносить изменения в базу данных)';
+$lang['update_simulation_title'] = '[Тест]';
+$lang['update_sync_all'] = 'папки и файлы';
+$lang['update_sync_dirs'] = 'только папки';
+$lang['update_sync_files'] = 'синхронизировать файловую структуру с базой данных';
+$lang['update_sync_metadata'] = 'синхронизировать метаданные файлов с информацией в базе данных';
+$lang['update_sync_metadata_all'] = 'все, включая синхронизированные ранее';
+$lang['update_used_metadata'] = 'Используемые метаданные';
+$lang['update_wrong_dirname_info'] = 'Название папки и файла должно состоять из букв, цифр, "-", "_" и "."';
+$lang['update_wrong_dirname_short'] = 'неверное имя файла';
+$lang['upload'] = 'Загрузка';
+$lang['user "%s" added'] = 'пользователь "%s" added';
+$lang['user_status'] = 'Статус пользователя';
+$lang['user_status_admin'] = 'Администратор';
+$lang['user_status_generic'] = 'Общий';
+$lang['user_status_guest'] = 'Гость';
+$lang['user_status_normal'] = 'Пользователь';
+$lang['user_status_webmaster'] = 'Вебмастер';
+$lang['username'] = 'ник';
+$lang['users'] = 'Пользователи';
+$lang['virtual_category'] = 'Виртуальная категория';
+$lang['waiting'] = 'Ожидающие';
+$lang['is_default_group'] = 'по умолчанию';
+$lang['toggle_is_default_group'] = 'Сделать/убрать \'по умолчанию\'';
+$lang['Advanced_features'] = 'Расширенные функции';
+$lang['Elements_not_linked'] = 'Не привязанные элементы';
+$lang['special_admin_menu'] = 'Спец функции';
+$lang['Duplicates'] = 'Файлы с одинаковыми именами в разных папках';
+
+$lang['Overall'] = 'Вся';
+$lang['Year'] = 'Год';
+$lang['Month'] = 'Месяц';
+$lang['Day'] = 'День';
+$lang['Pages seen'] = 'Страниц просмотрено';
+$lang['Pictures'] = 'Фотографии';
+$lang['time'] = 'время';
+$lang['user'] = 'пользователь';
+$lang['IP'] = 'IP';
+$lang['image'] = '';
+$lang['section'] = 'раздел';
+$lang['tags'] = 'слова';
+$lang['conf_history_guest'] = 'Сохранять страницы посещенные гостями';
+$lang['conf_history_user'] = 'Сохранять страницы посещенные пользователями';
+$lang['conf_history_admin'] = 'Сохранить страницы посещенные администраторами';
+$lang['cat_options_title'] = 'Свойства';
+$lang['An information email was sent to group "%s"'] = 'Информационное письмо отправлено для группы "%s"';
+$lang['Send an information email to group members'] = 'Отправить информационное письмо для группы';
+$lang['Group'] = 'Группа';
+$lang['[%s] Come to visit the category %s'] = '[%s] Приглашаю в категорию %s';
+$lang['Hello,'] = 'Привет,';
+$lang['See you soon.'] = 'До встречи.';
+$lang['Come to discover the category:'] = 'Приходите в категорию:';
+$lang['mail_content'] = 'Содержание';
+$lang['none'] = 'нет';
+$lang['high'] = 'большой';
+$lang['other'] = 'другой';
+$lang['Element type'] = 'Тип элемента';
+$lang['User'] = 'Пользователь';
+$lang['Image id'] = 'id изображения';
+$lang['Summary'] = 'Суммарно';
+$lang['%d line filtered'] = '%d линия отфильтрована';
+$lang['%d lines filtered'] = '%d линий отфильтровано';
+$lang['%d guest'] = '%d гость';
+$lang['%d guests'] = '%d гостей';
+$lang['Hour'] = 'Час';
+$lang['is_the_guest'] = 'гость';
+$lang['is_the_default'] = 'значение по умолчанию';
+$lang['High filesize'] = 'Большой размер файла';
+// --------- Starting below: New or revised $lang ---- from version 1.7.1
+$lang['Guest cannot be deleted'] = 'Гость не может быть удален';
+$lang['Default user cannot be deleted'] = 'Пользователь по умолчанию не может быть удален';
+$lang['purge history detail'] = 'очистить историю';
+$lang['purge history summary'] = 'очистить всю историю';
+$lang['c13y_title'] = 'Проверка совместимости';
+$lang['c13y_Anomaly'] = 'Неисправность';
+$lang['c13y_Correction'] = 'Корректировка';
+$lang['c13y_Automatic_correction'] = 'Автоматическая коррекция';
+$lang['c13y_Impossible_automatic_correction'] = 'Автоматическая коррекция невозможна';
+$lang['c13y_Correction_applied_success'] = 'Коррекция успешно применена';
+$lang['c13y_Correction_applied_error'] = 'Коррекция применена с ошибками';
+$lang['c13y_anomaly_count'] = 'Обнаружена %d неисправность.';
+$lang['c13y_anomalies_count'] = 'Обнаружено %d неисправностей.';
+$lang['c13y_anomaly_corrected_count'] = 'Скорректирована %d неисправность.';
+$lang['c13y_anomalies_corrected_count'] = 'Скорректировано %d неисправностей.';
+$lang['c13y_anomaly_not_corrected_count'] = 'Не скорректирована %d неисправность.';
+$lang['c13y_anomalies_not_corrected_count'] = 'Не скорректировано %d неисправностей.';
+$lang['c13y_more_info'] = 'Смотрите %s или %s для получения дополнительной информации';
+$lang['c13y_more_info_forum'] = 'форум';
+$lang['c13y_more_info_wiki'] = 'wiki';
+$lang['c13y_exif_anomaly'] = 'значение %s в файле не верно, так как exif не поддерживается';
+$lang['c13y_exif_correction'] = '%s нужно отключить в файле config_local.inc.php';
+$lang['c13y_guest_non_existent'] = 'Статус пользователя "гость" больше не существует';
+$lang['c13y_bad_guest_status'] = 'Статус пользователя "гость" некорректен';
+$lang['c13y_default_non_existent'] = 'Пользователь по умолчанию больше не существует';
+$lang['c13y_webmaster_non_existent'] = 'Пользователь "webmaster" больше не существует';
+$lang['c13y_bad_webmaster_status'] = 'Статус пользователя "webmaster" некорректен';
+$lang['c13y_user_created'] = 'Пользователь "%s" создан с паролем "%s"';
+$lang['c13y_user_status_updated'] = 'Статус пользователя "%s" обновлен';
+$lang['add new elements to caddie'] = 'добавить новые фотографии в корзину';
+// --------- Starting below: New or revised $lang ---- from Butterfly
+$lang['no_display_thumbnail'] = 'Не показывать';
+$lang['display_thumbnail_classic'] = 'Классический вид';
+$lang['display_thumbnail_hoverbox'] = 'Вид Hoverbox';
+$lang['Thumbnails'] = 'Миниатюры';
+$lang['obligatory_user_mail_address'] = 'Адрес электронной почты обязателен для всех пользователей';
+$lang['Minimum privacy level'] = 'Минимальный уровень защиты';
+$lang['Privacy level'] = 'Уровень защиты';
+$lang['Level 0'] = '---';
+$lang['Level 1'] = 'Контакты';
+$lang['Level 2'] = 'Друзья';
+$lang['Level 4'] = 'Семья';
+$lang['Level 8'] = 'Администрация';
+$lang['c13y_maintenance'] = 'Повторить проверку целостности';
+$lang['Check all'] = 'Отметить все';
+$lang['Uncheck all'] = 'Снять все отметки';
+$lang['c13y_check_auto'] = 'Отметить автокоррекцию';
+$lang['c13y_submit_correction'] = 'Применить выбранные корректировки';
+$lang['c13y_submit_ignore'] = 'Игнорировать отмеченные неисправности';
+$lang['c13y_submit_refresh'] = 'Обновить';
+$lang['c13y_ignore_msg1'] = 'Неисправности будут игнорироваться до установки следующей версии скрипта';
+$lang['c13y_ignore_msg2'] = 'Корректировка неисправностей отменит факт их игнора';
+$lang['c13y_anomaly_ignored_count'] = '%d неисправность была проигнорирована.';
+$lang['c13y_anomalies_ignored_count'] = 'Было проигнорировано неисправностей: %d';
+$lang['plugins_need_update'] = 'Плагины, требующие обновлений';
+$lang['plugins_dontneed_update'] = 'Обновленные плагины';
+$lang['plugins_cant_check'] = 'Плагины, обновление которых не получается отследить';
+$lang['plugins_actual_version'] = 'Текущая<br>версия';
+$lang['plugins_new_version'] = 'Доступная<br>версия';
+$lang['plugins_auto_update'] = 'Автоматическое обновление';
+$lang['plugins_auto_install'] = 'Автоматическая установка';
+$lang['plugins_download'] = 'Скачать файл';
+$lang['plugins_tab_list'] = 'Список плагинов';
+$lang['plugins_tab_update'] = 'Проверка обновлений';
+$lang['plugins_tab_new'] = 'Другие плагины';
+$lang['plugins_revisions'] = 'Последние изменения';
+$lang['plugins_delete'] = 'Удалить';
+$lang['plugins_confirm_delete'] = 'Уверены, что хотите удалить этот плагин?';
+$lang['plugins_confirm_install'] = 'Уверены, что хотите установить этот плагин?';
+$lang['plugins_confirm_upgrade'] = 'Уверены, что хотите обновить? Проверьте, не нужна ли этой версии деинсталляция.';
+$lang['plugins_upgrade_ok'] = '%s успешно обновлен.';
+$lang['plugins_install_ok'] = 'Плагин успешно скопирован';
+$lang['plugins_install_need_activate'] = 'Вы можете перейти к списку плагинов для его установки и активации.';
+$lang['plugins_temp_path_error'] = 'Невозможно создать временный файл.';
+$lang['plugins_dl_archive_error'] = 'Невозможно скачать архив.';
+$lang['plugins_archive_error'] = 'Невозможно прочитать или распаковать архив.';
+$lang['plugins_extract_error'] = 'Ошибка в процессе распаковки (%s).';
+$lang['plugins_check_chmod'] = 'Пожалуйста, проверьте права папки "plugins" и подпапок (CHMOD).';
+$lang['plugins_server_error'] = 'Невозможно соединиться с сервером.';
+$lang['Purge compiled templates'] = 'Очистить созданные шаблоны';
+$lang['Caddie is currently empty'] = 'Корзина сейчас пуста';
+$lang['conf_upload_title'] = 'Загрузки';
+$lang['Show upload link every time'] = 'Показывать ссылку на загрузку постоянно';
+$lang['User access level to upload'] = 'Уровень доступа пользователя для загрузки';
+$lang['ACCESS_0'] = 'Свободный доступ';
+$lang['ACCESS_1'] = 'Доступно для всех';
+$lang['ACCESS_2'] = 'Доступно для избранных';
+$lang['ACCESS_3'] = 'Доступно для администраторов';
+$lang['ACCESS_4'] = 'Доступно для вебмастера';
+$lang['ACCESS_5'] = 'Недоступно';
+$lang['DEMO'] = 'Демо';
+$lang['HOME'] = 'Piwigo home';
+$lang['FORUM'] = 'Поддержка';
+$lang['BUGS'] = 'Ошибки';
+$lang['EXTENSIONS'] = 'Расширения';
+$lang['WIKI / DOC'] = 'Документация';
+$lang['A new version of Piwigo is available.'] = 'Доступна новая версия Piwigo.';
+$lang['Piwigo Administration'] = 'Администрация Piwigo';
+$lang['Piwigo version'] = 'Версия Piwigo';
+$lang['You are running the latest version of Piwigo.'] = 'Запущена последняя версия Piwigo.';
+$lang['c13y_version_anomaly'] = 'Установленная версия %s [%s] не совместима с версией [%s]';
+$lang['c13y_version_correction'] = 'Чтобы воспользоваться всеми возможностями скрипта, обновите систему, иначе скрипт может работать некорректно';
+$lang['Deleted on'] = 'Удалено';
+$lang['Last hit'] =  'Последние просмотренные';
+$lang['Hits'] = 'Просмотры';
+$lang['GD library is missing'] = 'Библиотека GD отсутствует';
+$lang['conf_extents'] = 'Шаблоны';
+$lang['extend_for_templates'] = 'Расширение для шаблонов';
+$lang['Replacement of original templates'] =
+ 'Заменить исходные шаблоны на пользовательские из подпапки template-extension';
+$lang['Replacers'] = 'Заменяющий (пользовательский шаблон)';
+$lang['Original templates'] = 'Исходный шаблон';
+$lang['Optional URL keyword'] = 'Опциональное ключевое слово URL';
+$lang['Templates recorded.'] = 'Templates configuration has been recorded.';
+$lang['Optimizations completed'] = 'Все оптимизации успешно завершены.';
+$lang['Optimizations errors'] = 'Оптимизации завершены с ошибками.';
+$lang['delete this comment'] = 'удалить комментарий';
+$lang['link_info_image'] = 'Modify information';
+$lang['edit category informations'] = 'редактировать категорию';
+$lang['nothing'] = 'ничего';
+$lang['overrides existing values with empty ones'] = 'замена существующих значений пустыми';
+$lang['manage image ranks'] = 'управление порядком изображений';
+$lang['Manage image ranks'] = 'Управление порядком изображений';
+$lang['Edit ranks'] = 'Изменить порядок';
+$lang['No element in this category'] = 'Пустая категория';
+$lang['Images manual order was saved'] = 'Указанный порядок изображений сохранен';
+$lang['ranks'] = 'порядок';
+$lang['Drag to re-order'] = 'Перетащите чтобы изменить порядок';
+$lang['Unable to retrieve server informations since allow_url_fopen is disabled.'] = 'Невозможно получить информацию от сервера пока allow_url_fopen недоступен.';
+$lang['Quick Local Synchronization'] = 'Быстрая синхронизация';
+$lang['No photo can be deleted'] = 'Нет фото для удаления';
+$lang['Note: Only deletes photos added with pLoader'] = 'Заметьте: Удаление только фото добавленных с помощью pLoader';
+$lang['Delete selected photos'] = 'Удалить выбранные фото';
+$lang['%d photo was deleted'] = '%d фото удалено';
+$lang['%d photos were deleted'] = '%d фото удалено';
+/* TODO */ $lang['Bound template'] = 'Bound template';
+/* TODO */ $lang['Downloads'] = 'Downloads';
+/* TODO */ $lang['Released on'] = 'Released on';
+/* TODO */ $lang['Number of downloads'] = 'Number of downloads';
+?>
Index: /tags/2.0.2/language/ru_RU/common.lang.php
===================================================================
--- /tags/2.0.2/language/ru_RU/common.lang.php	(revision 3278)
+++ /tags/2.0.2/language/ru_RU/common.lang.php	(revision 3278)
@@ -0,0 +1,368 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008      Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Langage informations
+$lang_info['language_name'] = 'Russian';
+$lang_info['country'] = 'Russia';
+$lang_info['direction'] = 'ltr';
+$lang_info['code'] = 'ru';
+$lang_info['zero_plural'] = true;
+
+$lang['%.2f (rated %d times, standard deviation = %.2f)'] = '%.2f (%d оценок, разброс = %.2f)';
+$lang['%d Kb'] = '%d Kb';
+$lang['%d category updated'] = '%d категория дополнена';
+$lang['%d categories updated'] = 'категорий дополнено: %d';
+$lang['%d comment to validate'] = '%d комментарий на проверке';
+$lang['%d comments to validate'] = 'комментариев на проверке: %d';
+$lang['%d new comment'] = '%d новый комментарий';
+$lang['%d new comments'] = 'новых комментариев: %d';
+$lang['%d comment'] = '%d комментарий';
+$lang['%d comments'] = 'комментариев: %d';
+$lang['%d hit'] = '%d просмотр';
+$lang['%d hits'] = 'просмотров: %d';
+$lang['%d new element'] = '%d новый элемент';
+$lang['%d new elements'] = '%d новых элементов';
+$lang['%d new user'] = '%d новый посетитель';
+$lang['%d new users'] = '%d новые посетители';
+$lang['%d waiting element'] = '%d элемент в очереди';
+$lang['%d waiting elements'] = '%d элементов в очереди';
+$lang['About'] = 'О движке';
+$lang['All tags must match'] = 'Все слова должны присутствовать';
+$lang['All tags'] = 'Все слова';
+$lang['Any tag'] = 'Любое из слов';
+$lang['At least one listed rule must be satisfied.'] = 'Хотя бы одно правило должно выполняться.';
+$lang['At least one tag must match'] = 'Хотя бы одно слово должно присутствовать';
+$lang['Author'] = 'Автор';
+$lang['Average rate'] = 'Средний балл';
+$lang['Categories'] = 'Галереи';
+$lang['Category'] = 'Галерея';
+$lang['Close this window'] = 'Закрыть это окно';
+$lang['Complete RSS feed'] = 'Полная RSS лента (фотографии, комментарии)';
+$lang['Confirm Password'] = 'Повторите пароль';
+$lang['Connection settings'] = 'Настройки соединения';
+$lang['Connection'] = 'Авторизация';
+$lang['Contact webmaster'] = 'Техподдержка';
+$lang['Create a new account'] = 'Создать новый аккаунт';
+$lang['Created on'] = 'Дата съемки';
+$lang['Creation date'] = 'Дата съемки';
+$lang['Current password is wrong'] = 'Введен неправильный пароль';
+$lang['Dimensions'] = 'Размеры';
+$lang['Display'] = 'Порядок';
+$lang['Each listed rule must be satisfied.'] = 'Все перечисленные правила должны выполняться';
+$lang['Email address is missing'] = 'Не указан адрес электронной почты';
+$lang['Email address'] = 'Адрес электронной почты';
+$lang['Enter your personnal informations'] = 'Укажите персональную информацию';
+$lang['Error sending email'] = 'Ошибка отправки электронной почты';
+$lang['File name'] = 'Имя файла';
+$lang['File'] = 'Файл';
+$lang['Filesize'] = 'Размер файла';
+$lang['Filter and display'] = 'Отфильтровать и показать';
+$lang['Filter'] = 'Фильтр';
+$lang['Forgot your password?'] = 'Забыли пароль?';
+$lang['Go through the gallery as a visitor'] = 'Войти в галерею как посетитель';
+$lang['Help'] = 'Помощь';
+$lang['Identification'] = 'Идентификация';
+$lang['Image only RSS feed'] = 'RSS лента только с фотографиями';
+$lang['Keyword'] = 'Ключевые слова';
+$lang['Links'] = 'Ссылки';
+$lang['Mail address'] = 'Почтовый адрес';
+$lang['N/A'] = 'N/A';
+$lang['New on %s'] = 'Новое в %s';
+$lang['New password confirmation does not correspond'] = 'New password confirmation does not correspond';
+$lang['New password sent by email'] = 'Новый пароль отправлен по электронной почте';
+$lang['No email address'] = 'Не указан email';
+$lang['No user matches this email address'] = 'Нет пользователей с таким адресом электронной почты';
+$lang['Notification'] = 'RSS-уведомления';
+$lang['Number of items'] = 'Кол-во на странице';
+$lang['Original dimensions'] = 'Исходный размер';
+$lang['Password forgotten'] = 'Пароль утерян';
+$lang['Password'] = 'Пароль';
+$lang['Post date'] = 'Дата публикации';
+$lang['Posted on'] = 'Дата публикации';
+$lang['Profile'] = 'Профиль';
+$lang['Quick connect'] = 'Быстрый вход';
+$lang['RSS feed'] = 'RSS ленты';
+$lang['Rate'] = 'Оценка';
+$lang['Register'] = 'Регистрирация';
+$lang['Registration'] = 'Регистрация';
+$lang['Related tags'] = 'Связанные слова';
+$lang['Reset'] = 'Отмена';
+$lang['Retrieve password'] = 'Напомнить пароль';
+$lang['Search rules'] = 'Условия для поиска';
+$lang['Search tags'] = 'Тэги для поиска';
+$lang['Search'] = 'Поиск';
+$lang['See available tags'] = 'Просмотр доступных тэгов';
+$lang['Send new password'] = 'Потребовать новый пароль';
+$lang['Since'] = 'За период';
+$lang['Sort by'] = 'Признак сортировки';
+$lang['Sort order'] = 'Порядок сортировки';
+$lang['Tag'] = 'Слово';
+$lang['Tags'] = 'Ключевые слова';
+$lang['The RSS notification feed provides notification on news from this website : new pictures, updated categories, new comments. Use a RSS feed reader.'] = 'Уведомления RSS рассказывают о новом на этом сайте: новых фотографиях, обновленных галереях, новых комментариях. Для этого пользуйтесь RSS-читалкой.';
+$lang['Unknown feed identifier'] = 'Неизвестный идентификатор ленты';
+$lang['User comments'] = 'Комментарии посетителей';
+$lang['Username'] = 'Имя пользователя';
+$lang['Visits'] = 'Посещения';
+$lang['Webmaster'] = 'Техподдержка';
+$lang['Week %d'] = 'Неделя %d';
+$lang['about_page_title'] = 'О PhpWebGallery';
+$lang['access_forbiden'] = 'Вы не можете получить доступ к запрашиваемой странице без авторизации';
+$lang['add to caddie'] = 'добавить в корзину';
+$lang['add_favorites_hint'] = 'Добавить эту фотографию в избранные';
+$lang['admin'] = 'Администрирование';
+$lang['adviser_mode_enabled'] = 'Включить подсказки';
+$lang['all'] = 'все';
+$lang['ascending'] = 'по возрастанию';
+$lang['author(s) : %s'] = 'автор(ы) : %s';
+$lang['auto_expand'] = 'Раскрыть все категории';
+$lang['became available after %s (%s)'] = 'опубликовано после %s (%s)';
+$lang['became available before %s (%s)'] = 'опубликовано до %s (%s)';
+$lang['became available between %s (%s) and %s (%s)'] = 'опубликовано между %s (%s) и %s (%s)';
+$lang['became available on %s'] = 'опубликовано %s';
+$lang['best_rated_cat'] = 'По оценкам';
+$lang['best_rated_cat_hint'] = 'показать высоко оцененные';
+$lang['caddie'] = 'корзина';
+$lang['calendar'] = 'Календарь';
+$lang['calendar_any'] = 'Все';
+$lang['calendar_hint'] = 'показать каждый день с фотографией, месяц за месяцем';
+$lang['calendar_picture_hint'] = 'показать фотографии добавленные ';
+$lang['calendar_view'] = 'Просмотр';
+$lang['chronology_monthly_calendar'] = 'Месяц';
+$lang['chronology_monthly_list'] = 'Число';
+$lang['chronology_weekly_list'] = 'День недели';
+$lang['click_to_redirect'] = 'Пройдите по этой ссылке, если браузер не перенаправляет Вас автоматически';
+$lang['comment date'] = 'дата комментария';
+$lang['comment'] = 'Комментарий';
+$lang['comment_added'] = 'Ваш комментарий отправлен';
+$lang['comment_anti-flood'] = 'Антифлуд: пожалуйста, подождите немного, прежде чем отправить следующий комментарий';
+$lang['comment_not_added'] = 'Ваш комментарий НЕ отправлен, так как не соответствует правилам';
+$lang['comment_to_validate'] = 'Адимнмстратор должен проверить ваш комментарий, прежде чем он будет показан.';
+$lang['comment_user_exists'] = 'Этот логин уже используется другим посетителем';
+$lang['comments'] = 'Комментарии';
+$lang['comments_add'] = 'Добавить комментарий';
+$lang['created after %s (%s)'] = 'созданы после %s (%s)';
+$lang['created before %s (%s)'] = 'созданы до %s (%s)';
+$lang['created between %s (%s) and %s (%s)'] = 'созданы между %s (%s) и %s (%s)';
+$lang['created on %s'] = 'созданы %s';
+$lang['customize'] = 'Настройка';
+$lang['customize_page_title'] = 'Настройка галереи ';
+$lang['day'][0] = 'Вс';
+$lang['day'][1] = 'Пн';
+$lang['day'][2] = 'Вт';
+$lang['day'][3] = 'Ср';
+$lang['day'][4] = 'Чт';
+$lang['day'][5] = 'Пт';
+$lang['day'][6] = 'Сб';
+$lang['default_sort'] = 'По умолчанию';
+$lang['del_favorites_hint'] = 'Убрать эту фотографию из избранного';
+$lang['delete'] = 'Удалить';
+$lang['descending'] = 'по убыванию';
+$lang['download'] = 'загрузка';
+$lang['download_hint'] = 'загрузить этот файл';
+$lang['edit'] = 'редактировать';
+$lang['err_date'] = 'ошибка в дате';
+$lang['excluded'] = 'исключенный';
+$lang['favorite_cat'] = 'Избранное';
+$lang['favorite_cat_hint'] = 'показать мои избранные фотографии';
+$lang['favorites'] = 'Избранное';
+$lang['first_page'] = 'Первая';
+$lang['gallery_locked_message'] = 'Галерея закрыта для обслуживания. Пожалуйста, заходите попозже.';
+$lang['generation_time'] = 'Страница сгенерирована за';
+$lang['guest'] = 'гость';
+$lang['hello'] = 'Привет';
+$lang['hint_admin'] = 'доступно только для администратора';
+$lang['hint_category'] = 'показать фотографии из корня категории';
+$lang['hint_comments'] = 'Просмотр последних пользовательский комментариев';
+$lang['hint_customize'] = 'настройка оформления';
+$lang['hint_search'] = 'поиск';
+$lang['home'] = 'Home';
+$lang['identification'] = 'Вход';
+$lang['images_available_cpl'] = 'в этой категории';
+$lang['images_available_cat'] = 'в %d подкатегории';
+$lang['images_available_cats'] = '(в %d подкатегориях)';
+$lang['included'] = 'включено';
+$lang['invalid_pwd'] = 'Неверный пароль!';
+$lang['language']='Язык';
+$lang['last %d days'] = 'послеедние %d дней';
+$lang['last_page'] = 'Последняя';
+$lang['logout'] = 'Выход';
+$lang['mail_address'] = 'E-mail адрес';
+$lang['mandatory'] = 'обязательный';
+$lang['maxheight'] = 'Максимальная высота изображения';
+$lang['maxheight_error'] = 'Максимальная высота изображения должна быть больше 50';
+$lang['maxwidth'] = 'Максимальная ширина изображения';
+$lang['maxwidth_error'] = 'Максимальная ширина изображения должна быть больше 50';
+$lang['mode_created_hint'] = 'показывает календарь по дате создания';
+$lang['mode_flat_hint'] = 'показывает все фотографии во всех подкатегориях';
+$lang['mode_normal_hint'] = 'возвращение к нормальному режиму';
+$lang['mode_posted_hint'] = 'показывает календарь по дате отправления';
+$lang['month'][10] = 'Октябрь';
+$lang['month'][11] = 'Ноябрь';
+$lang['month'][12] = 'Декабрь';
+$lang['month'][1] = 'Январь';
+$lang['month'][2] = 'Февраль';
+$lang['month'][3] = 'Март';
+$lang['month'][4] = 'Апрель';
+$lang['month'][5] = 'Май';
+$lang['month'][6] = 'Июнь';
+$lang['month'][7] = 'Июль';
+$lang['month'][8] = 'Август';
+$lang['month'][9] = 'Сентябрь';
+$lang['most_visited_cat'] = 'По популярности';
+$lang['most_visited_cat_hint'] = 'показать наиболее популярные фотографии';
+$lang['nb_image_line_error'] = 'Число фотографий в строке должно быть не нулевым целым положительным';
+$lang['nb_image_per_row'] = 'Число фотографий в строке';
+$lang['nb_line_page_error'] = 'Число строк на странице должно быть не нулевым целым положительным';
+$lang['nb_row_per_page'] = 'Число строк на странице';
+$lang['nbm_unknown_identifier'] = 'Неизвестный идентификатор';
+$lang['new_password'] = 'Новый пароль';
+$lang['new_rate'] = 'Оцените это изображение';
+$lang['next_page'] = 'Следующая';
+$lang['no_category'] = 'Начало';
+$lang['no_rate'] = 'не оценено';
+$lang['note_filter_day'] = 'Показывает только фотографии, опубликованные за последние %s дня.';
+$lang['note_filter_days'] = 'Показывает только фотографии, опубликованные за последние %s дней.';
+$lang['password updated'] = 'пароль изменен';
+$lang['periods_error'] = 'Последний период должен быть положительным целым числом';
+/* DEPRECATED USED IN comments.php FOR image_id ? */ $lang['picture'] = 'изображение';
+$lang['picture_high'] = 'Нажмите на изображение, чтобы увидеть его в большом разрешении';
+$lang['picture_show_metadata'] = 'Показать метаданные';
+$lang['powered_by'] = 'Скрипт';
+$lang['preferences'] = 'Предпочтение';
+$lang['previous_page'] = 'Предыдущая';
+$lang['random_cat'] = 'Случайные';
+$lang['random_cat_hint'] = 'несколько случайных фотографий';
+$lang['recent_cats_cat'] = 'Новые галереи';
+$lang['recent_cats_cat_hint'] = 'показать обновленные галереи';
+$lang['recent_period'] = 'Срок "новых"';
+$lang['recent_pics_cat'] = 'Новые фотографии';
+$lang['recent_pics_cat_hint'] = 'показывает новые фотографии';
+$lang['redirect_msg'] = 'Перенаправляем...';
+$lang['reg_err_login1'] = 'Пожалуйста, введите логин';
+$lang['reg_err_login2'] = 'логин не должен оканчиваться на пробел';
+$lang['reg_err_login3'] = 'логин не должен начинаться с пробела';
+$lang['reg_err_login5'] = 'такой логин уже есть';
+$lang['reg_err_mail_address'] = 'адрес электронной почты должен выглядеть как-то типа xxx@yyy.eee (например: jack@altern.org)';
+$lang['reg_err_pass'] = 'введите пароль еще раз';
+$lang['remember_me'] = 'Запомнить меня';
+$lang['remove this tag'] = 'удалить этот тэг из списка';
+$lang['representative'] = 'представитель';
+$lang['return to homepage'] = 'вернуться на главную';
+$lang['search_author'] = 'Поиск по автору';
+$lang['search_categories'] = 'Поиск в Категориях';
+$lang['search_date'] = 'Поиск по дате';
+$lang['search_date_from'] = 'Начальная дата';
+$lang['search_date_to'] = 'Конечная дата';
+$lang['search_date_type'] = 'Тип даты';
+$lang['search_keywords'] = 'Поиск по словам';
+$lang['search_mode_and'] = 'Поиск по всем критериям ';
+$lang['search_mode_or'] = 'Поиск по любому критерию';
+$lang['search_one_clause_at_least'] = 'Пустой запрос. Нет критериев для поиска.';
+$lang['search_options'] = 'Варианты поиска';
+$lang['search_result'] = 'Результаты поиска';
+$lang['search_subcats_included'] = 'и в подкатегориях';
+$lang['search_title'] = 'Поиск';
+$lang['searched words : %s'] = 'искомые слова: %s';
+$lang['send_mail'] = 'Контакты';
+$lang['set as category representative'] = 'сделать представителем категории';
+$lang['show_nb_comments'] = 'Показывать количество комментариев';
+$lang['show_nb_hits'] = 'Показывать количество просмотров';
+$lang['slideshow'] = 'слайдшоу';
+$lang['slideshow_stop'] = 'остановить слайдшоу';
+$lang['special_categories'] = 'Избранное';
+$lang['sql_queries_in'] = 'SQL-запрос в';
+$lang['start_filter_hint'] = 'показать только недавно опубликованные фотографии';
+$lang['stop_filter_hint'] = 'возврат к показу всех фотографий';
+$lang['the beginning'] = 'с начала';
+$lang['theme'] = 'Оформление';
+$lang['thumbnails'] = 'Миниатюры';
+$lang['title_menu'] = 'Меню';
+$lang['title_send_mail'] = 'Комментарий с вашего сайта';
+$lang['today'] = 'сегодня';
+$lang['update_rate'] = 'Обновить оценку';
+$lang['update_wrong_dirname'] = 'неверное имя файла';
+$lang['upload_advise_filesize'] = 'размер файла не должен превышать: ';
+$lang['upload_advise_filetype'] = 'фотография должна быть в формате jpg, gif или png';
+$lang['upload_advise_height'] = 'высота фотографии не должна превышать: ';
+$lang['upload_advise_thumbnail'] = 'Рекомендуется определить миниатюры для ';
+$lang['upload_advise_width'] = 'ширина фотографии не должна превышать: ';
+$lang['upload_author'] = 'Автор (например, Вася Пупкин)';
+$lang['upload_cannot_upload'] = 'невозможно загрузить фотографию на сервер';
+$lang['upload_err_username'] = 'должно присутствовать имя пользователя';
+$lang['upload_file_exists'] = 'Такое наименование фотографии уже есть';
+$lang['upload_filenotfound'] = 'Вы должны выбрать формат файла для изображения';
+$lang['upload_forbidden'] = 'Вы не можете загрузить фотографии в этой категории';
+$lang['upload_name'] = 'Название фотографии';
+$lang['upload_picture'] = 'Загрузка фотографии';
+$lang['upload_successful'] = 'Фотография успешно загружена, администратор утвердит это как можно скорее';
+$lang['upload_title'] = 'Загрузка фотографии';
+$lang['useful when password forgotten'] = 'для восстановления потерянного пароля';
+$lang['qsearch'] = 'Быстрый поиск';
+$lang['Connected user: %s'] = 'Подключены пользователи: %s';
+$lang['IP: %s'] = 'IP: %s';
+$lang['Browser: %s'] = 'Браузер: %s';
+$lang['Author: %s'] = 'Автор: %s';
+$lang['Comment: %s'] = 'Комментарий: %s';
+$lang['Delete: %s'] = 'Удалить: %s';
+$lang['Validate: %s'] = 'Проверка: %s';
+$lang['Comment by %s'] = 'Комментарий от %s';
+$lang['User: %s'] = 'Посетитель: %s';
+$lang['Email: %s'] = 'Email: %s';
+$lang['Admin: %s'] = 'Администратор: %s';
+$lang['Registration of %s'] = 'Регистрация %s';
+$lang['Category: %s'] = 'Категория: %s';
+$lang['Picture name: %s'] = 'Название: %s';
+$lang['Creation date: %s'] = 'Дата съемки: %s';
+$lang['Waiting page: %s'] = 'Страница ожидания: %s';
+$lang['Picture uploaded by %s'] = 'Фотография загружена %s';
+// --------- Starting below: New or revised $lang ---- from version 1.7.1
+$lang['guest_must_be_guest'] = 'Неверный статус пользователя "гость", используйте статус по умолчанию. Пожалуйста сообщите вебмастеру.';
+// --------- Starting below: New or revised $lang ---- from Butterfly (2.0)
+$lang['Administrator, webmaster and special user cannot use this method'] = 'Administrator, webmaster and special user cannot use this method';
+$lang['reg_err_mail_address_dbl'] = 'пользователь с таким адресом уже есть';
+$lang['Category results for'] = 'Результат категорий для';
+$lang['Tag results for'] = 'Слова-результаты для';
+$lang['from %s to %s'] = 'от %s до %s';
+$lang['start_play'] = 'Показать слайдшоу';
+$lang['stop_play'] = 'Остановить слайдшоу';
+$lang['start_repeat'] = 'Повторять слайдшоу';
+$lang['stop_repeat'] = 'Не повторять слайдшоу';
+$lang['inc_period'] = 'Reduce diaporama speed';
+$lang['dec_period'] = 'Accelerate diaporama speed';
+$lang['Submit'] = 'Отправить';
+$lang['Yes'] = 'Да';
+$lang['No'] = 'Нет';
+$lang['%d element']='%d фотография';
+$lang['%d elements']='фотографий: %d';
+$lang['%d element are also linked to current tags'] = '%d фотография также связаня с этими словами';
+$lang['%d elements are also linked to current tags'] = '%d фотографий также связаны с этими словами';
+$lang['See elements linked to this tag only'] = 'Показать фотографии, связанные только с этим словом';
+$lang['elements posted during the last %d days'] = 'фотографии опубликованные за последние %d дней';
+$lang['Choose an image'] = 'Выберите фотографию';
+$lang['Piwigo Help'] = 'Помощь';
+$lang['Rank'] = 'Ряд';
+$lang['group by letters'] = 'сгруппировать по буквам';
+$lang['letters'] = 'буквы';
+$lang['show tag cloud'] = 'показать облако слов';
+$lang['cloud'] = 'облако';
+?>
Index: /tags/2.0.2/language/ru_RU/help.html
===================================================================
--- /tags/2.0.2/language/ru_RU/help.html	(revision 3278)
+++ /tags/2.0.2/language/ru_RU/help.html	(revision 3278)
@@ -0,0 +1,236 @@
+<div class="instructions">
+<h2>Помощь</h2>
+
+<h3>Быстрый старт</h3>
+
+<ol>
+
+  <li>Создайте локальную папку "test_category".</li>
+
+  <li>Скопируйте фотографии в "test_category".</li>
+
+  <li>Соединитесь по FTP с галереей.</li>
+
+  <li>Загрузите локальную папку "test_category" в удаленную папку "galleries".
+  Установите права доступа 777 на папку "galleries/test_category".</li>
+
+  <li>Зайдите в Вашу галерею Piwigo как администратор.</li>
+
+  <li>Перейдите в <span class="pwgScreen">Администрирование, Фотографии,
+  Миниатюры</span>. Piwigo найдет фотографии без миниатюр в "test_category"
+  и спросит подтверждение на создание миниатюр.</li>
+
+  <li>Перейдите в <span class="pwgScreen">Администрирование, Галереи,
+  Синхронизация</span>. Отметьте "папки и файлы", снимите отметку "только тестировать
+  (не вносить изменения в базу данных)" и нажмите отправить.</li>
+
+  <li>Все. Вы создали категорию "test_category" в корне Вашей галереи.</li>
+
+</ol>
+
+<h3>Добавление фотографий</h3>
+
+<ul>
+
+  <li>
+
+    <p>Папки категорий располагаются в папке "galleries".
+    Ниже смотрите дерево небольшой галереи:</p>
+
+    <pre>
+.
+|-- admin
+|-- doc
+|-- galleries
+|   |-- category-1
+|   |   |-- category-1.1
+|   |   |   |-- category-1.1.1
+|   |   |   |   |-- category-1.1.1.1
+|   |   |   |   |   |-- pwg_high
+|   |   |   |   |   |   +-- wedding.jpg
+|   |   |   |   |   |-- thumbnail
+|   |   |   |   |   |   +-- TN-wedding.jpg
+|   |   |   |   |   +-- wedding.jpg
+|   |   |   |   +-- category-1.1.1.2
+|   |   |   +-- category-1.1.2
+|   |   |-- category-1.2
+|   |   |   |-- pookie.jpg
+|   |   |   +-- thumbnail
+|   |   |       +-- TN-pookie.jpg
+|   |   +-- category-1.3
+|   +-- category-2
+|       |-- piglet.gif
+|       |-- pwg_representative
+|       |   +-- video.jpg
+|       |-- thumbnail
+|       |   +-- TN-piglet.jpg
+|       +-- video.avi
+|-- include
+|-- install
+|-- language
+|-- template
++-- tool</pre>
+
+  </li>
+
+  <li>В простейшем случае, категории представлены как папки любого уровня в
+  папке "galleries". Каждая категория может содержать столько подкатегорий,
+  сколько хотите. В примере выше, category-1.1.1.1 находится на 4 уровне.</li>
+
+  <li>Каждый файл - это фотография. Файл может быть элементом Piwigo если его
+  тип описан в параметре <code>file_ext</code>
+  (см файл <span  class="filename">include/config_default.inc.php</span>).</li>
+
+  <li>Фотография должна иметь миниатюру (см ниже раздел о миниатюрах)</li>
+
+  <li>Фотография может иметь версию в высоком разрешении, как wedding.jpg в примере выше.
+  У файла с высоким разрешением нет префикса.</li>
+
+  <li>Элементы, не являющиеся изображениями (видео, музыка, тексты и др.) по определению
+  представлены иконками соответствующими расширению файла. Дополнительно, Вы можете
+  связать миниатюру и представительный файл (см. video.avi в примере выше).</li>
+
+  <li><em>Внимание</em>: название папок и файлов должно быть составлено из букв,
+  чисел, "-", "_" или ".". Не используйте пробелы.</li>
+
+  <li><em>Для сведения</em>: категория может содержать элементы и подкатегории одновременно.
+  Тем не менее, настоятельно рекомендуется для каждой категории выбрать, будет
+  она содержать подкатегории или элементы.</li>
+
+  <li>Когда файлы, миниатюры и представители правильно размещены в папки, выберите:
+  <span class="pwgScreen">Администрирование, Категории, Синхронизация</span></li>
+
+</ul>
+
+<h3>Миниатюры</h3>
+
+<ul>
+
+  <li>Как сказано ранее, каждое изображение должно иметь миниатюру.</li>
+
+  <li>Миниатюры располагаются в подпапке "thumbnail" папки категории.
+  Миниатюра - это картинка (с типами файлов как и изображения) в имени файла
+  имеющая префикс, который указан в настройке Префикс миниатюры" (см панель
+  администрирования, Настройки, Основные).</li>
+
+  <li>Миниатюры не обязательно должны быть с тем же расширением, как оригинальные изображения
+  (изображение с расширением .jpg может иметь миниатюру с расширением .GIF).</li>
+
+  <li>Совет: используйте внешний модуль для создания миниатюр.</li>
+
+  <li>Вы можете также использовать возможности скрипта (<span
+  class="pwgScreen">Администрирование, Фотографии, Миниатюры</span>), хотя делать
+  это не рекомендуется. К сожалению, качество миниатюр может быть не очень высоким,
+  а загрузка процессора достаточно высока, что может привести к проблемам
+  при использовании бесплатного хостинга.</li>
+
+  <li>Если все же пользоваться возможностями скрипта, нужно дать права на запись
+  для всех папок категорий и подпапок "thumbnail" для ugo (user, group, other).</li>
+
+</ul>
+
+<h3>Установка доступа</h3>
+
+<ul>
+
+  <li>Вы можете запретить доступ к категориям. Категории могут быть "публичными" или
+  "приватными". Права доступа (для групп и пользователей) могут быть установлены только для приватных категорий.</li>
+
+  <li>Вы можете сделать приватной категорию редактируя свойства каждой категории (<span
+  class="pwgScreen">Администрирование, Галереи, Управление, редактировать</span>) или просматривая дерево категорий (<span
+  class="pwgScreen">Администрирование, Галереи, Свойства, Общедоступные / Приватные</span>).</li>
+
+  <li>
+
+    <p>Если категория приватная, права доступа к ней можно установить для групп
+    и пользователей тремя способами:</p>
+
+    <ul>
+
+      <li><span class="pwgScreen">Администрирование, Идентификация, Пользователи,
+      разрешения (последний столбец в таблице с пользователем)</span></li>
+
+      <li><span class="pwgScreen">Администрирование, Идентификация, Группы,
+      разрешения (последний столбец в таблице с группой)</span></li>
+
+      <li><span class="pwgScreen">Администрирование, Галереи, Управление, редактировать
+      (ссылка для каждой категории)</span></li>
+
+    </ul>
+
+  </li>
+
+</ul>
+
+<h3>Группы пользователей</h3>
+
+<ul>
+
+  <li>Piwigo позволяет управлять группами пользователей. Это удобно для
+  установки прав доступа к приватным категориям.</li>
+
+  <li>Вы можете создать группы на странице <span class="pwgScreen">Администрирование,
+  Идентификация, Группы</span> и добавить пользователей в созданную группу на странице <span
+  class="pwgScreen">Администрирование, Идентификация, Пользователи</span>.</li>
+
+  <li>Пользователь может входить в несколько групп. Разрешение сильнее чем запрет:
+  если пользователь "jack" входит в группы "family" и "friends", и есть категория
+  "Christmas 2003", доступ к которой открыт только для группы "family",
+  пользователь "jack" будет иметь доступ к категории "Christmas 2003".</li>
+
+</ul>
+
+<h3>Загрузка файлов пользователями</h3>
+
+<p>Piwigo предлагает возможность пользователям загружать изображения. Для этого нужно:</p>
+
+<ol>
+
+  <li>разрешить загрузку для какой-либо категории (<span
+  class="pwgScreen">Администрирование, Галереи, Управление, редактировать</span> или <span
+  class="pwgScreen">Администрирование, Галереи, Свойства, Загрузка</span>)</li>
+
+  <li>дать права на запись в папку для ugo (user, group, other)</li>
+
+</ol>
+
+<p>Файлы, загруженные пользователями не видны сразу на сайте, они должны быть
+проверены администратором. Чтобы это сделать, администратор
+должен посетить <span class="pwgScreen">Администрирование, Фотографии, Ожидающие</span>
+и принять или отклонить предложенные файлы, после чего синхронизировать систему
+файлов с базой данных.</p>
+
+
+<h3>Связи между элементами и категориями, виртуальными категориями</h3>
+
+<ul>
+
+  <li>Piwigo различает категории где хранятся элементы и категории где они показаны.</li>
+
+  <li>По умолчанию, элементы показываются только в реальных категориях: тех,
+  которые связаны с папками на сервере.</li>
+
+  <li>Чтобы привязать элемент к категории, нужно только указать это на странице
+  редактирования элемента или в информации обо всех элементах категории.</li>
+
+  <li>Зная этот принцип, легко понять что такое виртуальные категории: это те,
+  которым не соответствуют папки на сервере. Виртуальные категории можно создать
+  на странице <span class="pwgScreen">Администрирование, Категории, Управление</span>.</li>
+
+</ul>
+
+<h3>Прочая информация</h3>
+
+<ul>
+
+  <li>После того, как Вы создадите галерею, измените значения по умолчанию,
+  отвечающие за отображение галереи, для чего откорректируйте значения на странице
+  <span class="pwgScreen">Администрирование, Настройки,
+  Основные</span>Каждый новый пользователь будет видеть галерею так, как описано в этих настройках. </li>
+
+  <li>Если у Вас есть вопросы, не стесняйтесь поискать ответы на <a
+  href="http://piwigo.org/forum">форуме</a> или задать их там. Для получения более развернутых сведений, прочтите <a
+  href="http://piwigo.org/doc/">официальную документация по Piwigo</a>.</li>
+
+</ul>
+</div>
Index: /tags/2.0.2/language/ru_RU/help/advanced_feature.html
===================================================================
--- /tags/2.0.2/language/ru_RU/help/advanced_feature.html	(revision 3278)
+++ /tags/2.0.2/language/ru_RU/help/advanced_feature.html	(revision 3278)
@@ -0,0 +1,16 @@
+<h2>Расширенные функции</h2>
+
+<p>Показаны специальные возможности для продвинутых администраторов PWG:</p>
+
+<ul>
+
+  <li>
+    <strong>Не привязанные элементы:</strong>
+    Показывает фотографии которые не связаны ни с одной виртуальной категорией.
+  </li>
+  <li>
+    <strong>Файлы с одинаковыми именами в разных папках:</strong>
+    Показывает фотографии или другие файлы имеющие одинаковые имена и находящиеся в разных категориях.
+  </li>
+
+</ul>
Index: /tags/2.0.2/language/ru_RU/help/cat_modify.html
===================================================================
--- /tags/2.0.2/language/ru_RU/help/cat_modify.html	(revision 3278)
+++ /tags/2.0.2/language/ru_RU/help/cat_modify.html	(revision 3278)
@@ -0,0 +1,137 @@
+<h2>Редактирование категорий</h2>
+
+<h3>Информация</h3>
+
+<ul>
+
+  <li><strong>Название</strong>: дает возможность переименовать категорию
+  (похоже на псевдоним в случае реальной категории).</li>
+
+  <li><strong>Описание</strong>: можно описать содержимое категории.
+  Этот текст будет показан внизу на странице с миниатюрами.</li>
+
+</ul>
+
+<h3>Перемещение</h3>
+
+<p>Если категория виртуальная, Вы можете ее перемещать. Перемещение категории
+   означает изменение родительской категории.</p>
+
+<h3>Опции</h3>
+
+<ul>
+
+  <li><strong>Тип доступа</strong>: Управление доступом. Если сделать категорию
+  приватной, все вложенные категории тоже станут приватными. Если сделать категорию
+  общедоступной, все вложенные категории тоже станут общедоступными.</li>
+
+  <li><strong>Блокировка</strong>: Категория и ее подкатегории временно будут
+  закрыты на обслуживание.</li>
+
+  <li><strong>Комментарии</strong>: Управление возможностью комментировать
+  элементы категории для пользователей.</li>
+
+  <li><strong>Разрешить загрузку</strong>: Управление доступом для загрузки
+  файлов пользователями. Эта опция доступна только для обычных категорий (не виртуальных).</li>
+
+</ul>
+
+<p>Также вы можете управлять этими настройками на странице "Свойства"
+ (вкладки <span class="pwgScreen">Загрузка</span>, <span
+class="pwgScreen">Комментарии</span>, <span class="pwgScreen">Блокировка</span>,
+<span class="pwgScreen">Общедоступные / Приватные</span>), все это в меню <span
+class="pwgScreen">Администрирование, Галереи, Свойства</span>.</p>
+
+<h3>Порядок сортировки</h3>
+
+<p>Первый чекбокс определяет сортировку по умолчанию.</p>
+<p>Второй чекбокс определяет распространяет правила сортировки на подкатегории.</p>
+
+<p>Выберите другую сортировку, если это необходимо.</p>
+<ul>
+<li><strong>Дата съемки</strong>: Дата создания фотографии</li>
+<li><strong>Дата публикации</strong>: Дата добавления фотографии в галерею</li>
+<li><strong>Средний балл (*)</strong>: По рейтингу, за который голосуют посетители</li>
+<li><strong>По популярности (*)</strong>: По числу посещений посетителями страниц с фотографиями</li>
+<li><strong>Имя файла</strong>: Сортировка по имени файла фотографий</li>
+<li><strong>Id</strong>: Внутренний идентификатор (недавние категории имеют более высокий идентификатор, чем более ранние).</li>
+
+</ul>
+<p><strong>(*)</strong> Попробуйте эти значения. Часто они дают непрогнозируемые
+результаты.</p>
+
+
+<h3>Представитель</h3>
+
+<p>Представитель категории - это миниатюра, которая представляет категорию на
+главной странице (<span class="pwgScreen">category.php</span>) когда категория
+содержит только подкатегории (как корнревая, например).</p>
+
+<p>Существует 4 способа назначить представителя категории:</p>
+
+<ul>
+
+  <li><span class="pwgScreen">Страница с фотографией</span>: в ряду кнопок на
+  панели есть кнопка, назначающая эту фотографию представителем отображаемой
+  категории. Эта кнопка доступна только администратору.</li>
+
+  <li><span class="pwgScreen">Редактирование информации о фотографии</span> в
+  разделе администрирования. Эта функция доступна со страницы с фотографией <span
+  class="pwgScreen">picture.php</span> или <span class="pwgScreen">Управление корзиной</span>
+  в <em>групповом режиме</em>. См. помощь этого экрана для уточнения деталей.</li>
+
+  <li><span class="pwgScreen">Администрирование, Галереи, Свойства,
+  Представитель</span>. См. помощь этого экрана для уточнения деталей.</li>
+
+  <li><span class="pwgScreen">Редактирование категории</span> (этот экран).</li>
+
+</ul>
+
+<p>Представление зависит от параметра конфигурации
+<code>allow_random_representative</code> (см. <span
+class="filename">include/config_default.inc.php</span>).</p>
+
+<p>По умолчанию (<code>allow_random_representative</code> установлен на false)
+каждая категория, содержащая по крайней мере один элемент, представлена
+фиксированным элементом. Установленный однажды (при создании категории),
+представитель изменяется только когда администратор сделает это.
+Если представительне устраивает, Вы можете выбрать <strong>Найти нового
+представителя случайным образом</strong>.</p>
+
+<p>Если параметр конфигурации <code>allow_random_representative</code> установлен на
+ true, категория, имеющая элементы не имеет фиксированного представителя. Используйте
+ кнопку <strong>Удалить представителя</strong>.</p>
+
+<p>Если категория не содержит элементов (но содердит подкатегории), она может
+быть представлеа любым элементом установленным с помощью страницы <span
+class="pwgScreen">Изменить информацию о фотографии</span>.
+
+<h3>Привязать все элементы этой категории к новой</h3>
+
+<ul>
+
+<li><strong>Название виртуальной категории</strong>: Новая категория с этим именем будет создана,
+все фотографии этой категории будут привязаны к ней.</li>
+
+<li><strong>Родительская категория</strong>: Где будет создана новая категория,
+если это должна быть верхняя категория, оставьте параметр пустым.</li>
+
+</ul>
+
+<h3>Привязать все элементы этой категории к одной из существующих</h3>
+
+<ul>
+
+<li><strong>Галереи</strong>: Выберите категорию, к которой нужно привязать элементы.</li>
+
+</ul>
+
+<h3>Отправить информационное письмо для группы</h3>
+
+<ul>
+
+<li><strong>Группа</strong>: группа-адресат</li>
+
+<li><strong>Содержание</strong>: Текст, который будет отправлен ее участникам.</li>
+
+</ul>
Index: /tags/2.0.2/language/ru_RU/help/cat_move.html
===================================================================
--- /tags/2.0.2/language/ru_RU/help/cat_move.html	(revision 3278)
+++ /tags/2.0.2/language/ru_RU/help/cat_move.html	(revision 3278)
@@ -0,0 +1,14 @@
+<h2>Перемещение виртуальных категорий</h2>
+
+<p>Только виртуальные категории могут быть перемещены в новую родительскую категорию.</p>
+
+<h3>Виртуальные категории для перемещения</h3>
+
+<p>Выберите виртуальные категории, которые хотите переместить.
+Если список пуст, то Вы еще не создавали виртуальных категорий.</p>
+
+<h3>Новая родительская категория</h3>
+
+<p>Выберите новую родительскую категорию (виртуальную или реальную).
+Если ничего не выбрать, виртуальные категории, отмеченные на предыдущем этапе, будут перемещены в корневую галерею.
+Вы не можете переместить категорию в саму себя или в одну из собственных подкатегорий.</p>
Index: /tags/2.0.2/language/ru_RU/help/cat_options.html
===================================================================
--- /tags/2.0.2/language/ru_RU/help/cat_options.html	(revision 3278)
+++ /tags/2.0.2/language/ru_RU/help/cat_options.html	(revision 3278)
@@ -0,0 +1,34 @@
+<h2>Свойства категорий</h2>
+
+<p>Этот экран позволяет администратору изменять свойства нескольких категорий одновременно.</p>
+
+<dl>
+
+  <dt>Загрузка</dt>
+  <dd>Открывает категории для загрузки файлов пользователями. Показаны только не
+  виртуальные и не удаленные категории.</dd>
+
+  <dt>Комментарии</dt>
+  <dd>Открывает категории для комментирования.
+Выберите категории, которые хотите открыть для комментирования.
+Изображение открыто для комментариев, если хотя бы одна категория открыта для
+комментариев.</dd>
+
+  <dt>Блокировка</dt>
+  <dd>Выбранные категории будут временно заблокированы для обслуживания. Все
+  подкатегории заблокированной категории также будут заблокированы. Если разблокировать
+  категорию, все ее родительские категории также разблокируются.</dd>
+
+  <dt>Общедоступные / Приватные</dt>
+  <dd>Управление доступом к выбранным категориям. Если сделать категорию приватной,
+  нужно дать права пользователям и/или группам для доступа к ним.
+  Если сделать категорию приватной, все ее подкатегории тоже станут приватными.
+  Если сделать категорию общедоступной, все родительские категории также станут общедоступными.</dd>
+
+  <dt>Представители</dt>
+  <dd>Этот раздел доступен, если параметр <code>allow_random_representative</code>
+  (см. <span class="filename">include/config_defaults.inc.php</span>) установлен в
+  <em>true</em>. Каждая категория может иметь случайно выбранного представителя
+  или единственного представителя (выбранного администратором).</dd>
+
+</dl>
Index: /tags/2.0.2/language/ru_RU/help/cat_perm.html
===================================================================
--- /tags/2.0.2/language/ru_RU/help/cat_perm.html	(revision 3278)
+++ /tags/2.0.2/language/ru_RU/help/cat_perm.html	(revision 3278)
@@ -0,0 +1,15 @@
+<h2>Управление разрешениями для категории</h2>
+
+<p>Этот экран доступен только для приватной категории. Здесь можно выбрать
+пользователей и группы, которые имеют доступ к этой категории.</p>
+
+<h3>Группы</h3>
+
+<p>Вы можете разрешить или запретить группам доступ к этой категории. Изменяя доступность для групп,
+Вы изменяете доступность для пользователей, входящих в соответствующие группы.</p>
+
+<h3>Пользователи</h3>
+
+<p>Так же как с группами, можно поступать с отдельными пользователями.
+Пользователь допущенный к категории по участию в группе, может быть ограничен в
+правах персонально с помощью доступа пользователя.</p>
Index: /tags/2.0.2/language/ru_RU/help/configuration.html
===================================================================
--- /tags/2.0.2/language/ru_RU/help/configuration.html	(revision 3278)
+++ /tags/2.0.2/language/ru_RU/help/configuration.html	(revision 3278)
@@ -0,0 +1,136 @@
+<h2>Настройка</h2>
+
+<p>Этот экран позволяет администратору делать простейшие настройки. На самом деле, этот
+экран всего лишь показывает простейшие настройки, которых будет достаточно для
+большинства администраторов. Если Вы хотите увидеть другие настройки (дополнительные),
+смотрите файл <span class="filename">include/config_default.inc.php</span>.</p>
+
+<p>Экран разбит на несколько секций, группирующих настройки по темам.</p>
+
+
+<h3>Главная</h3>
+<ul>
+  <li><strong>Название галереи</strong>: используется в ленте RSS и уведомлениях по email.</li>
+
+  <li><strong>Надпись на баннере</strong>: показывается вверху всех страниц.</li>
+
+  <li><strong>Адрес галереи</strong>: используется в ленте RSS.</li>
+
+  <li><strong>Заблокировать галерею</strong>: Закрыть галерею на обслуживание.
+  Доступ к галерее будет открыт только администратору.</li>
+
+  <li><strong>Оценки</strong>: Разрешить выставлять оценки.</li>
+
+  <li><strong>Оценки от гостей</strong>: Даже не зарегистрированные пользователи
+  смогут оценивать фотографии.</li>
+
+  <li><strong>Разрешить регистрацию пользователей</strong>: Любой может свободно
+  зарегистрироваться.</li>
+
+  <li><strong>Адрес электронной почты обязателен для всех пользователей</strong>:
+  Наличие адреса будет проверено при регистрации или изменении профиля если это
+  действие задано в административной части.</li>
+
+  <li><strong>Сообщать администратору когда зарегистрировался новый посетитель</strong>:
+  Администратор получает письмо при каждой регистрации.</li>
+
+</ul>
+
+<h3>История</h3>
+
+  <p>Посещения страниц <span class="pwgScreen">category.php</span> и
+  <span class="pwgScreen">picture.php</span> будут записываться в таблицу <code>history</code>.</p>
+
+  <p>Посещения показаны на <span class="pwgScreen">Администрирование, Спец функции, История</span>.</p>
+
+<ul>
+  <li><strong>Сохранять страницы посещенные гостями</strong>: страницы посещенные
+  гостями будут сохраняться.</li>
+
+  <li><strong>Сохранять страницы посещенные пользователями</strong>: страницы
+  посещенные зарегистрированными пользователями будут сохраняться.</li>
+
+  <li><strong>Сохранить страницы посещенные администраторами</strong>: страницы
+  посещенные администратором будут сохраняться.</li>
+
+</ul>
+
+<h3>Комментарии</h3>
+<ul>
+
+  <li><strong>Комментарии для всех</strong>: Даже не зарегистрированные
+  пользователи могут комментировать фотографии.</li>
+
+  <li><strong>Количество комментариев на странице</strong>.</li>
+
+  <li><strong>Проверка</strong>: администратор проверяет комментарии написанные
+  пользователями прежде чем они будут показаны на сайте. Проверка комментариев
+  осуществляется на странице <span class="pwgScreen">Администрирование, Фотографии,
+  Комментарии</span>.</li>
+
+  <li><strong>Сообщать администратору когда появился комментарий</strong>:
+Посылать email администратору когда пользователь внесет комментарий.</li>
+
+  <li><strong>Сообщать администратору когда появился комментарий для проверки</strong>:
+Посылать email администратору когда пользователь внесет комментарий для проверки администратором.
+Комментарии для проверки находятся на странице<span class="pwgScreen">
+Администрирование, Фотографии, Комментарии</span>.</li>
+
+</ul>
+
+<!--TODO --><h3>Загрузки</h3>
+<ul>
+<!--TODO -->  <li><strong>Показывать ссылку на загрузку постоянно</strong>: Если
+есть категории, куда разрешена загрузка, добавляется ссылка, которая показывается
+в каждой категории.</li>
+<!--TODO -->  <li><strong>Уровень доступа пользователя для загрузки</strong>:
+Позволяет ограничит загрузку для пользователей</li>
+  <li><strong>Сообщать администратору когда загружена фотография</strong>:
+  Администратор получает письмо при загрузке фотографии каждым пользователем.</li>
+</ul>
+
+<h3>Вид по умолчанию</h3>
+
+<p>Здесь можно изменить параметры отображения по умолчанию для пользователя
+Гость или не авторизованного пользователя.
+После авторизации параметры отображения изменятся на пользовательские (заданные
+на странице <span class="pwgScreen">профайла</span>).</p>
+
+<p>Параметры отображения для всех существующих пользователей можно изменить на
+странице <span class="pwgScreen">Администрирование,
+Идентификация, Пользователи</span>, где можно сделать настройки для отмеченных пользователей.</p>
+
+<ul>
+
+  <li><strong>Язык</strong>: влияет только на надписи. Названия категорий,
+  фотографий и все описания не локализуются.</li>
+
+  <li><strong>Число фотографий в строке</strong></li>
+
+  <li><strong>Число строк на странице</strong></li>
+
+  <li><strong>Оформление</strong></li>
+
+  <li><strong>Срок "новых"</strong>: В днях. Период в течение которого фотография
+  показывается как новая. Должен быть больше 1 дня.</li>
+
+  <li><strong>Раскрыть все категории</strong>: Раскрыть все категории в меню?
+  <em>Внимание</em>: этот вариант ресурсоемок и может сгенерировать очень большое
+  меню, если дерево категорий Вашей галереи содержит много категорий.</li>
+
+  <li><strong>Показывать количество комментариев</strong>: показывать количество комментариев
+  для каждой фотографии на странице миниатюр.</li>
+
+  <li><strong>Показывать количество просмотров</strong>: показывать количество
+  просмотров фотографии под миниатюрой фотографии на странице миниатюр.
+  Действует когда параметр: <br />  $conf['show_nb_hits'] = true; <br />
+  Примечание: параметр по умолчанию установлен в false.</li>
+
+  <li><strong>Максимальная ширина изображения</strong>: максимальная отображаемая
+  ширина. Если фотография больше по ширине, она будет уменьшена при показе.
+  Если Вы устанавливаете эту настройку, лучше будет изменить ширину фотографий заранее.</li>
+
+  <li><strong>Максимальная высота изображения</strong>: те же комментарии, что и у ширины.</li>
+
+</ul>
+
Index: /tags/2.0.2/language/ru_RU/help/extend_for_templates.html
===================================================================
--- /tags/2.0.2/language/ru_RU/help/extend_for_templates.html	(revision 3278)
+++ /tags/2.0.2/language/ru_RU/help/extend_for_templates.html	(revision 3278)
@@ -0,0 +1,96 @@
+<h2>Настройка расширений для шаблонов</h2>
+
+<h3>Цель</h3>
+<p>Определите условия замены каждого шаблона на шаблон-расширение (шаблон,
+названный "заменяющим").</p>
+
+<p>"Исходный шаблон" из ./template/yoga (или другой) будет заменен на
+ "заменяющий" если заменяющий связан с этим "исходным"
+ (и, опционально, если URL содержит "Опциональное ключевое слово URL").</p>
+
+<p>"Опциональное ключевое слово URL" это те, которые Вы можете найти после названия модуля в URL.</p>
+
+<p>Поэтому "Опциональные ключевые слова URL" могут быть активным "прямыми ссылками"
+(см. соответствующий раздел в нашей документации для дальнейшего объяснения).</p>
+
+<p>Читайте: `<a href="#warnings">Предупреждение</a>` условий использования.</p>
+
+<h3>Что такое шаблон-расширение?</h3>
+
+<p>Этот инструмент конфигурации - мощный для новичков и продвинутых пользователей.
+С помощью FTP, в папке template-extension, Web-мастер может дублировать много
+разных .tpl файлов ("исходный шаблон") с различным названием ("заменяющим").
+
+
+ "Исходные шаблоны", текущие оригинальные поддерживаемые шаблоны:</p>
+<ul>
+  <li><span class="filename">index.tpl</span></li>
+  <li><span class="filename">mainpage_categories.tpl</span> и/или <span class="filename">thumbnails.tpl</span></li>
+  <li><span class="filename">menubar.tpl</span></li>
+  <li><span class="filename">header.tpl</span> и/или <span class="filename">footer.tpl</span></li>
+  <li><span class="filename">picture_content.tpl</span> и/или <span class="filename">picture.tpl</span></li>
+  <!-- <li><span class="filename">slideshow.tpl</span></li> -->
+  <li><span class="filename">profile.tpl</span> и/или <span class="filename">profile_content.tpl</span></li>
+  <li><span class="filename">tags.tpl</span></li>
+  <li><span class="filename">upload.tpl</span></li>
+  <li><span class="filename">about.tpl</span></li>
+  <li><span class="filename">popuphelp.tpl</span></li>
+  <li><span class="filename">search.tpl</span> и/или <span class="filename">search_rules.tpl</span></li>
+  <li><span class="filename">nbm.tpl</span> и/или <span class="filename">notification.tpl</span></li>
+  <li><span class="filename">identification.tpl</span> и/или <span class="filename">register.tpl</span></li>
+  <li><span class="filename">redirect.tpl</span></li>
+</ul>
+
+<h3>Где мне найти "исходные шаблоны"?</h3>
+
+<p>Находятся исходные шаблоны в template/yoga/
+(не редактируйте их там для сохранения возможности обновления). Так, с "исходными шаблонами",
+любой web-мастер может создать свои "заменяющие (пользовательские шаблоны)".</p>
+
+<h3>Куда записать "заменяющие"?</h3>
+
+<p><strong>Заменяющие (пользовательские шаблоны)</strong> должны находиться в папке
+template-extension (или ее подпапке).
+Заменяющие могут иметь любые имена файлов с расширением .tpl. Например: <span
+class="filename">template-extension/my-extension/video.tpl</span>.</p>
+
+
+<h3>Как мне активировать мои "заменяющие шаблоны"?</h3>
+<p>Каждый <strong>исходный шаблон</strong> должен быть сопоставлен со своим
+ <strong>заменяющим (пользовательским шаблоном)</strong> чтобы активировать связанные замены.
+ Это является целью "Настройки расширений для шаблонов" в меню Настроек.</p>
+
+<p>Если Вы выберете <strong>Опциональное ключевое слово URL</strong> тогда замена
+будет производиться только на страницах с этим ключевым словом. Например: <span
+  class="pwgScreen">index.php?/<strong>most_visited</strong></span></p>
+
+<p>Продвинутые пользователи могут использовать прямую ссылку как <strong>Опциональное
+ключевое слово URL</strong>. </p>
+
+<h3>Как мне деактивировать мои "заменяющие шаблоны"?</h3>
+<ul>
+<li>Отмените выбранный "Исходный шаблон".</li>
+<li>Через FTP удалите "заменяющий".</li>
+</ul>
+<a name="warnings"></a>
+<h3>Предупреждение</h3>
+<ul>
+
+  <li><strong>Оригинальный шаблон</strong> должен быть "исходным" шаблоном,
+  иначе результат может быть непредсказуемым!</li>
+
+  <li>При наличии нескольких <strong>заменяющих (пользовательских шаблонов)</strong>
+  с одинаковыми <strong>исходными шаблонами</strong> и одинаковыми <strong>опциональным
+  ключевым словом URL</strong> только последний заменяющий будет активным.</li>
+
+  <li>Отмена выбора <strong>опционального ключевого слова URL</strong> сделает
+  активной заменяющий шаблон для всех. Как в предыдущем пункте, следующий выбор может
+  отменить предыдущий.</li>
+
+  <li>Подпапки:
+Подпапки игнорируются, но они удобны для смены текущих установок.<br />
+</li>
+
+  <li>При удалении замещающего <strong>Исходный шаблон</strong> будет снова активным.</li>
+
+</ul>
Index: /tags/2.0.2/language/ru_RU/help/group_list.html
===================================================================
--- /tags/2.0.2/language/ru_RU/help/group_list.html	(revision 3278)
+++ /tags/2.0.2/language/ru_RU/help/group_list.html	(revision 3278)
@@ -0,0 +1,22 @@
+<h2>Список групп</h2>
+
+<p>Здесь Вы можете управлять созданными группами.</p>
+
+<h3>Добавить группу</h3>
+
+<p>Администратор может добавлять группы.</p>
+
+<h3>Список групп</h3>
+
+<p>Из списка для каждого элемента можно сделать:</p>
+
+
+<ul>
+  <li>перейти к списку участников</li>
+  <li>перейти к разрешениям</li>
+  <li>удалить группу (require a confirmation checkbox)</li>
+  <li>toggle status "default" (выдается запрос подтверждения)</li>
+</ul>
+
+<h3>Группа по умолчанию</h3>
+<p>Новые пользователи автоматически попадают в эту группу.</p>
Index: /tags/2.0.2/language/ru_RU/help/history.html
===================================================================
--- /tags/2.0.2/language/ru_RU/help/history.html	(revision 3278)
+++ /tags/2.0.2/language/ru_RU/help/history.html	(revision 3278)
@@ -0,0 +1,45 @@
+<h2>История</h2>
+
+<p>Этот экран позволяет просматривать историю посещений согласно опциям, которые
+выбраны в Администрирование - Настройки - История.</p>
+
+<h3>Статистика</h3>
+<ul>
+  <p>Если Вы выбрали сохранение истории посещений (<span
+class="pwgScreen">index.php</span> и <span
+class="pwgScreen">picture.php</span>) в таблице <code>history. </code>
+То здесь Вы увидите статистику посещений этих страниц.</p>
+
+	<li><strong>Вся</strong>: просмотр статистики по годам. </li>
+
+	<li><strong>Годовая статистика</strong>: просмотр помесячной статистики за выбранный год.</li>
+
+	<li><strong>Статистика за месяц</strong>: просмотр статистики по дням за выбранный месяц.</li>
+
+	<li><strong>Дневная статистика</strong>: просмотр статистики по часам за выбранный день.</li>
+
+</ul>
+
+<h3>Поиск</h3>
+<ul>
+  <p>Если Вы выбрали сохранение истории посещений (<span
+class="pwgScreen">index.php</span> и <span
+class="pwgScreen">picture.php</span>) в таблице <code>history. </code>
+То здесь Вы увидите статистику посещений этих страниц сгруппированную с помощью
+фильтров.</p>
+
+	<li><strong>Фильтр на дату</strong>: выберите интервал дат для отображения
+	статистики активности.</li>
+
+	<li><strong>Фильтр на тип элемента</strong>: выберите тип элемента для
+	отображения статистики активности.</li>
+
+	<li><strong>Фильтр на пользователя</strong>: выберите пользователя для
+	отображения статистики активности.</li>
+
+	<li><strong>Фильтр на имя файла</strong>: выберите имя файла для отображения
+	статистики активности.</li>
+
+	<li><strong>Фильтр на номер изображения</strong>: выберите номер изображения
+	для отображения статистики активности.</li>
+</ul>
Index: /tags/2.0.2/language/ru_RU/help/index.php
===================================================================
--- /tags/2.0.2/language/ru_RU/help/index.php	(revision 3278)
+++ /tags/2.0.2/language/ru_RU/help/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008      Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/language/ru_RU/help/maintenance.html
===================================================================
--- /tags/2.0.2/language/ru_RU/help/maintenance.html	(revision 3278)
+++ /tags/2.0.2/language/ru_RU/help/maintenance.html	(revision 3278)
@@ -0,0 +1,43 @@
+<h2>Обслуживание</h2>
+
+<p>Чтобы оптимизировать время создания страницы, Piwigo использует кэширование
+информации. Например, вместо того, чтобы считать число фотографий, содержащихся в
+каждой категории при каждом обновлении, эту информация хранят в базе данных. В
+теории, эта информация должна быть корректной, но иногда при ошибках кэшированная
+информация становится неверной.</p>
+
+<p>Некоторая информации становится бесполезным со временем. Удаление этой бесполезной
+информации из базы данных позволит сохранить дисковое пространство.</p>
+
+<ul>
+
+  <li><strong>Обновить информацию о категориях:</strong> Для каждой категории
+  обновляется или контролируется следующая информация: список родительских категорий,
+  число фотографий, дата последней фотографии, положение среди категорий одного
+  уровня, положение среди всех категорий.</li>
+
+  <li><strong>Обновить информацию о фотографиях:</strong> Для каждой фотографии
+  обновляется или контролируется следующая информация: полный путь к файлу, рейтинг.
+  <em>Предупреждение</em>: не путайте с метаданными которые синхронизируются из
+  <span class="pwgScreen">Администрирование, Галереи, Синхронизация</span> или
+  через страницу редактирования фотографии.</li>
+
+  <li><strong>Исправить и оптимизировать базу данных:</strong>
+  Для каждой таблицы будут проведены переупорядочивание, восстановление и оптимизация.
+  </li>
+</ul>
+
+<ul>
+  <li><strong>Очистить историю:</strong> Удаляются все строки из таблицы <code>history</code>.
+  На странице <span class="pwgScreen">Администрирование, Спец. функции, История</span>
+  не будет информации относительно истории до этой операции. <em>Предупреждение</em>:
+  все данные будут потеряны и нет никакого способа вернуть информацию.</li>
+
+  <li><strong>Очистить всю историю:</strong> Удаляется вся итоговая информаци об
+  истории посещений. Эта итоговая информация вычисляется из деталей истории.</li>
+
+  <li><strong>Очистить сессии:</strong> Удаляются истекшие пользовательские сеансы.</li>
+
+  <li><strong>Очистить неиспользуемые каналы уведомлений</strong></li>
+
+</ul>
Index: /tags/2.0.2/language/ru_RU/help/notification_by_mail.html
===================================================================
--- /tags/2.0.2/language/ru_RU/help/notification_by_mail.html	(revision 3278)
+++ /tags/2.0.2/language/ru_RU/help/notification_by_mail.html	(revision 3278)
@@ -0,0 +1,16 @@
+<h2>Уведомления</h2>
+
+<p>Этот раздел создан для настройки и управления уведомлениями по электронной
+почте пользователей о новостях на сайте.</p>
+
+<p>Страница содержит три вкладки:</p>
+
+<h3>Параметры</h3>
+<p>Доступные только вебмастеру, это параметры уведомлений.</p>
+
+<h3>Список рассылки</h3>
+<p>Доступно только вебмастеру, эта вкладка управляет подпиской пользователей на уведомления.</p>
+
+<h3>Отправка</h3>
+<p>Доступно только вебмастеру и администратору, эта вкладка позволяет производить рассылку уведомлений.</p>
+
Index: /tags/2.0.2/language/ru_RU/help/permalinks.html
===================================================================
--- /tags/2.0.2/language/ru_RU/help/permalinks.html	(revision 3278)
+++ /tags/2.0.2/language/ru_RU/help/permalinks.html	(revision 3278)
@@ -0,0 +1,12 @@
+<h2>Постоянные ссылки</h2>
+
+<p>Постоянные ссылки используют чтобы сделать URL категории более удобным. Когда
+для категории определена прямая ссылка, id категории в URL более не используется.</p>
+
+<p>После удаления прямой ссылки, Вы можете сохранить ее в истории прямых ссылок,
+чтобы сохранить работоспособность внешних ссылок. В таблице истории прямых ссылок
+ можно посмотреть дату удаления прямой ссылки, когда ей последний раз пользовались,
+ сколько всего раз ей пользовались.</p>
+
+<p>Заметьте, допускается только одна прямая ссылка на каждую категорию.
+Аналогично и в истории прямых ссылок нельзя определить одну и ту же прямую ссылку несколько раз.</p>
Index: /tags/2.0.2/language/ru_RU/help/search.html
===================================================================
--- /tags/2.0.2/language/ru_RU/help/search.html	(revision 3278)
+++ /tags/2.0.2/language/ru_RU/help/search.html	(revision 3278)
@@ -0,0 +1,22 @@
+<h2>Поиск</h2>
+
+<p>Эта страница позволяет искать фотографии по всей галерее.</p>
+
+<dl>
+
+  <dt>Поиск по словам </dt>
+  <dd>Поиск по всем словам во всех атрибутах во всех изображениях галереи.
+  Используйте * как подстановочный знак для частичных соответствий.</dd>
+
+  <dt>Поиск по автору</dt>
+  <dd>Используйте * как подстановочный знак для частичных соответствий.</dd>
+
+  <dt>Поиск по дате</dt>
+  <dd>Выберите начальную и/или конечную дату запроса. Оставьте пустой начальную
+  дату для поиска "ранее". Год должен вводиться в последнее поле в формате 0000 (т.е. 2004)</dd>
+
+  <dt>Поиск в Категориях</dt>
+  <dd>Выберите категорию или категории для ограничения области поиска. Для поиска
+  во всех подкатегориях можно выбратьродительскую категорию и установить флаг поиска в подкатегориях.</dd>
+
+</dl>
Index: /tags/2.0.2/language/ru_RU/help/site_manager.html
===================================================================
--- /tags/2.0.2/language/ru_RU/help/site_manager.html	(revision 3278)
+++ /tags/2.0.2/language/ru_RU/help/site_manager.html	(revision 3278)
@@ -0,0 +1,48 @@
+<h2>Удаленные сайты</h2>
+
+<p>Piwigo предлагает возможность использовать несколько серверов, чтобы хранить
+изображения, которые составят Вашу галерею. Это может быть полезно, если Ваша
+галерея установлена на одном ограниченном пространстве и у Вас большое количество
+изображений, которые должны быть показаны.</p>
+
+<ol>
+
+  <li>отредактируйте файл <span class="filename">tools/create_listing_file.php</span>,
+  изменяя секцию параметров
+  <code>$conf['prefix_thumbnail']</code> или
+  <code>$conf['use_exif']</code>.</li>
+
+  <li>поместите измененный файл <span class="filename">tools/create_listing_file.php</span>
+  на удаленный сервер, в папку где лежат папки категорий (как папка <span class="filename">galleries</span> на
+  этом вебсайте) с помощью FTP. Для примера, скажем, что Вы можете обратиться к <span
+  class="filename">http://example.com/galleries/create_listing_file.php</span>.</li>
+
+  <li>перейдите к <span class="pwgScreen">панели администрирования, Галереи, Управление
+  сайтами</span>. Создайте новый сайт, например <span
+  class="filename">http://example.com/galleries</span>.</li>
+
+  <li>новый удаленный сайт зарегистрирован. Вы можете выполнить 4 действия:
+
+    <ol>
+
+      <li><strong>сгенерировать листинг</strong>: запускает удаленный запрос на
+      генерацию файла листинга</li>
+
+      <li><strong>синхронизация</strong>: читает удаленный файл <span
+      class="filename">listing.xml</span> и синхронизирует с информацией в базе данных.</li>
+
+      <li><strong>очистить</strong>: стирает удаленный файл <span
+      class="filename">listing.xml</span>.</li>
+
+      <li><strong>удалить</strong>: удаляет сайт (все категории и элементы) в базе данных.</li>
+
+    </ol>
+  </li>
+</ol>
+
+<!-- <p>You can do all this by hand by generating yourself the <span
+class="filename">listing.xml</span> file, moving it from your distant server
+to you local Piwigo root directory and opening the remote site
+management screen : Piwigo will propose you to use the found
+listing.xml file.</p>-->
+
Index: /tags/2.0.2/language/ru_RU/help/synchronize.html
===================================================================
--- /tags/2.0.2/language/ru_RU/help/synchronize.html	(revision 3278)
+++ /tags/2.0.2/language/ru_RU/help/synchronize.html	(revision 3278)
@@ -0,0 +1,12 @@
+<h2>Синхронизация</h2>
+
+<p>Возможны 2 типа синхронизации: папки/файлы и метаданные.
+Папки/файлы синхронизируют дерево папок с деревом категорий в базе данных.
+Метаданные синхронизируют информацию элементов, такую как размер файла, размеры
+в пикселях, информацию EXIF или IPTC.</p>
+
+<p>Сначала должны быть синхронизированы папки/файлы.</p>
+
+<p>Процесс синхронизации может занять много времени (в зависимости от загрузки
+сервера и количества синхронизируемых элементов) то есть возможно стоит продвигаться
+пошагово:  от категории к категории.</p>
Index: /tags/2.0.2/language/ru_RU/help/thumbnail.html
===================================================================
--- /tags/2.0.2/language/ru_RU/help/thumbnail.html	(revision 3278)
+++ /tags/2.0.2/language/ru_RU/help/thumbnail.html	(revision 3278)
@@ -0,0 +1,17 @@
+<h2>Создание миниатюр</h2>
+<p>Эта страница позволяет создать отсутствующие миниатюры.</p>
+<dl>
+<dt>Версия GD</dt>
+<dd>GD - это графическая библиотека для PHP. Выберите версию, установленную на
+Вашем сервере. Если выбрать неправильную версию, выведется сообщение об ошибке,
+вернитесь и задайте другую версию. Если ни один из вариантов не работает, значит
+сервер не поддерживает GD.</dd>
+<dt>Ширина и высота</dt>
+<dd>Задается максимальный размер миниатюры. Соотношение сторон сохраняется.</dd>
+<dt>Количество создаваемых миниатюр</dt>  <dd>Не пытайтесь уменьшить сразу много
+фотографий. Уменьшение загружает CPU. Если скрипт установлен на сервере бесплатного
+провайдера, слишком большая загрузка CPU со стороны Вашего сайта может привести
+к его удалению.</dd>
+<dt>Формат файла</dt>
+<dd>Файлы миниатюр имеют только тип JPEG. Миниатюры могут быть созданы только для
+файлов PNG и JPEG.</dd></dl>
Index: /tags/2.0.2/language/ru_RU/help/user_list.html
===================================================================
--- /tags/2.0.2/language/ru_RU/help/user_list.html	(revision 3278)
+++ /tags/2.0.2/language/ru_RU/help/user_list.html	(revision 3278)
@@ -0,0 +1,41 @@
+<h2>Список пользователей</h2>
+
+<p>На этой странице Вы можете управлять зарегистрированными пользователями.
+Только разрешениями управляют в нескольких различных экранах.</p>
+
+<h3>Добавление пользователей</h3>
+
+<p>Администратор может вручную добавить пользователя.</p>
+
+<h3>Список пользователей</h3>
+
+<p>Список может быть отфильтрован по имени пользователя (используйте * как
+подстановочный знак), группе или статусу. Список можно отсортировать по дате
+регистрации или имени пользователя, по возрастанию или по убыванию.</p>
+
+<p>Этот экран позволяет производить над несколькими пользователями одно или несколько действий:</p>
+
+<ul>
+
+  <li>удаление пользователей (требуется подтвердить установкой галочки)</li>
+
+  <li>изменение статуса</li>
+
+  <li>включение или исключение из группы</li>
+
+  <li>редактирование свойств отображения</li>
+
+  <li>редактирование дополнительных свойств</li>
+
+</ul>
+
+<p>Настройки применяются к выбранным пользователям (по умолчанию) или ко всем.</p>
+<h3>Советник</h3>
+<p>Определение пользователя со статусом советник:</p>
+<ul>
+  <li>разрешен доступ на все экраны возможные для этого статуса</li>
+  <li>доступ только для чтения или только имитация</li>
+</ul>
+
+<p>Существование статуса советника регулируется переменной $conf['allow_adviser'].</p>
+<p>Если она имеет значение 'true', можно определить в качестве статуса пользователю статус советника</p>
Index: /tags/2.0.2/language/ru_RU/index.php
===================================================================
--- /tags/2.0.2/language/ru_RU/index.php	(revision 3278)
+++ /tags/2.0.2/language/ru_RU/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008      Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/language/ru_RU/install.lang.php
===================================================================
--- /tags/2.0.2/language/ru_RU/install.lang.php	(revision 3278)
+++ /tags/2.0.2/language/ru_RU/install.lang.php	(revision 3278)
@@ -0,0 +1,66 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008      Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+$lang['Installation'] = 'Установка';
+$lang['Initial_config'] = 'Базовая настройка';
+$lang['Default_lang'] = 'Язык по умолчанию';
+$lang['step1_title'] = 'Настройка базы данных';
+$lang['step2_title'] = 'Настройка администрирования';
+$lang['Start_Install'] = 'Начать установку';
+$lang['reg_err_mail_address'] = 'адрес электронной почты должен быть похож на xxx@yyy.eee (например: jack@altern.org)';
+
+$lang['install_webmaster'] = 'Логин вебмастера';
+$lang['install_webmaster_info'] = 'Он будет показан посетителям. Необходим для администрирования сайта';
+
+$lang['step1_confirmation'] = 'Все прошло успешно';
+$lang['step1_err_db'] = 'Успешно соединились с сервером, но невозможно подключиться к базе данных';
+$lang['step1_err_server'] = 'Невозможно соединиться с сервером';
+$lang['step1_err_copy_2'] = 'Можно переходить к следующему шагу';
+$lang['step1_err_copy_next'] = 'следующий шаг';
+$lang['step1_err_copy'] = 'Скопируйте текст с розового поля между дефисами и вставьте его в файл "include/mysql.inc.php"(Внимание: mysql.inc.php должен содержать только это, ни пустых строк, ни пробелов быть не должно)';
+
+$lang['step1_host'] = 'Хост MySQL';
+$lang['step1_host_info'] = 'localhost, sql.multimania.com, toto.freesurf.fr';
+$lang['step1_user'] = 'Пользователь';
+$lang['step1_user_info'] = 'логин, который выдал провайдер';
+$lang['step1_pass'] = 'Пароль';
+$lang['step1_pass_info'] = 'пароль, который выдал провайдер';
+$lang['step1_database'] = 'Имя базы данных';
+$lang['step1_database_info'] = 'также выдается провайдером. Часто совпадает с логином';
+$lang['step1_prefix'] = 'Префикс таблиц в базе данных';
+$lang['step1_prefix_info'] = 'названия таблиц в базе данных будут начинаться с этого (что упростит их обслуживание)';
+$lang['step2_err_login1'] = 'нужно ввести логин для вебмастера';
+$lang['step2_err_login3'] = 'логин вебмастера не должен содержать символы  \' или "';
+$lang['step2_err_pass'] = 'еще раз пароль';
+$lang['install_end_title'] = 'Установка завершена';
+$lang['step2_pwd'] = 'Пароль вебмастера';
+$lang['step2_pwd_info'] = 'Не сообщайте его никому, он необходим для доступа к панели администрирования';
+$lang['step2_pwd_conf'] = 'Повторите пароль';
+$lang['step2_pwd_conf_info'] = 'еще раз для исключения опечатки';
+$lang['install_help'] = 'Нужна помощь? Задайте свои вопросы на <a href="%s">Форуме Piwigo</a>.';
+$lang['install_end_message'] = 'Настройка Piwigo закончена, переходите к следующему шагу<br /><br />
+* перейдите на страницу [ <a href="identification.php">идентификации</a> ] и введите логин и пароль вебмастера<br />
+* это позволит получить доступ к панели администрирования и инструкциям по размещению фотографий в папках';
+$lang['conf_mail_webmaster'] = 'Электронная почта вебмастера';
+$lang['conf_mail_webmaster_info'] = 'Будет использоваться для контакта посетителей с администратором';
+?>
Index: /tags/2.0.2/language/ru_RU/iso.txt
===================================================================
--- /tags/2.0.2/language/ru_RU/iso.txt	(revision 3278)
+++ /tags/2.0.2/language/ru_RU/iso.txt	(revision 3278)
@@ -0,0 +1,1 @@
+Русский [RU]
Index: /tags/2.0.2/language/ru_RU/upgrade.lang.php
===================================================================
--- /tags/2.0.2/language/ru_RU/upgrade.lang.php	(revision 3278)
+++ /tags/2.0.2/language/ru_RU/upgrade.lang.php	(revision 3278)
@@ -0,0 +1,44 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008      Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+$lang['Upgrade'] = 'Обновление';
+$lang['introduction message'] = 'Эта страница предлагает привести в соответствие вашу базу данных и текущую версию.
+Ассистент обновления считает, что сейчас работает <strong>релиз %s</strong> (или эквивалент).';
+$lang['Upgrade from %s to %s'] = 'Обновление с версии %s до %s';
+$lang['Statistics'] = 'Статистика';
+$lang['total upgrade time'] = 'общее время обновления';
+$lang['total SQL time'] = 'общее время SQL';
+$lang['SQL queries'] = 'SQL запросы';
+$lang['Upgrade informations'] = 'Информация об обновлениях';
+$lang['perform a maintenance check'] = 'Выполните обслуживание [Администирирование> Специальное> Обслуживание] если вы столкнулись с какими-либо проблемами.';
+$lang['deactivated plugins'] = 'В качестве предосторожности, следующие плагины были отключены. Проверьте обновления плагинов перед их активацией:';
+$lang['upgrade login message'] = 'Только администратор может запустить обновление: проверьте ниже.';
+$lang['You do not have access rights to run upgrade'] = 'У вас нет прав на запуск обновлений';
+$lang['in include/mysql.inc.php, before ?>, insert:'] = 'В <i>include/mysql.inc.php</i>, перед <b>?></b>, вставьте:';
+
+// Upgrade informations from upgrade_1.3.1.php
+$lang['all sub-categories of private categories become private'] = 'Все подкатегории приватных категорий будут приватными';
+$lang['user permissions and group permissions have been erased'] = 'Разрешения пользователей и групп были стерты';
+$lang['only thumbnails prefix and webmaster mail saved'] = 'Только префикс эскизов и адрес почты вебмастера были сохранены от предыдущей конфигурации';
+
+?>
Index: /tags/2.0.2/language/zh_CN/about.html
===================================================================
--- /tags/2.0.2/language/zh_CN/about.html	(revision 3278)
+++ /tags/2.0.2/language/zh_CN/about.html	(revision 3278)
@@ -0,0 +1,6 @@
+  <li>Piwigo是一个简单实用的WEB图库管理程序。</li>
+
+  <li>在技术上, Piwigo基于PHP和MySQL数据库开发。</li>
+
+  <li>如果你有好的建议和想法, 请访问<a
+  href="http://fr.piwigo.org">官方网站</a>和<a href="http://fr.piwigo.org/forum">论坛</a>。</li>
Index: /tags/2.0.2/language/zh_CN/admin.lang.php
===================================================================
--- /tags/2.0.2/language/zh_CN/admin.lang.php	(revision 3278)
+++ /tags/2.0.2/language/zh_CN/admin.lang.php	(revision 3278)
@@ -0,0 +1,650 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+$lang['%d association'] = '%d 相关';
+$lang['%d associations'] = '%d 相关';
+$lang['cat_inclu_part1_S'] = '包含 %d 类';
+$lang['cat_inclu_part1_P'] = '包含 %d 等类';
+$lang['cat_inclu_part2_S'] = '物理 %d';
+$lang['cat_inclu_part2_P'] = '物理 %d ';
+$lang['cat_inclu_part3_S'] = ' 和 虚拟 %d ';
+$lang['cat_inclu_part3_P'] = ' 和 虚拟 %d ';
+$lang['%d category moved'] = '%d 类已迁移';
+$lang['%d categories moved'] = '%d 等类已迁移';
+$lang['%d group'] = '%d 组';
+$lang['%d groups'] = '%d 组';
+$lang['%d member'] = '%d 成员';
+$lang['%d members'] = '%d 成员';
+$lang['%d tag'] = '%d 标签';
+$lang['%d tags'] = '%d 标签';
+$lang['%d user comment rejected'] = '%d 用户评论被删除';
+$lang['%d user comments rejected'] = '%d 用户评论被删除';
+$lang['%d user comment validated'] = '%d 用户评论已确认有效';
+$lang['%d user comments validated'] = '%d 用户评论已确认有效';
+$lang['%d user deleted'] = '%d 用户已删除';
+$lang['%d users deleted'] = '%d 用户已删除';
+$lang['%d user'] = '%d 用户';
+$lang['%d users'] = '%d 用户';
+$lang['%d waiting for validation'] = '%d 等待确认有效';
+$lang['%d waiting pictures rejected'] = '%d 图片等待被删除';
+$lang['%d waiting pictures validated'] = '%d 图片等待被确认有效';
+$lang['Actions'] = '实施';
+$lang['Activate'] = '激活';
+$lang['Add/delete a permalink'] = '增加/删除一个固定链接';
+$lang['Add a tag'] = '增加标签';
+$lang['Add a user'] = '增加用户';
+$lang['Add group'] = '增加组';
+$lang['Add selected elements to caddie'] = '把所选的图片放到购物篮';
+$lang['Add'] = '增加';
+$lang['Allow user registration'] = '允许用户注册';
+$lang['Apply to subcategories'] = '应用于子类中';
+$lang['Are you sure?'] = '确定?';
+$lang['Associated'] = '关联于';
+$lang['Association to categories'] = '与类相关联';
+$lang['Batch management'] = '分批管理';
+$lang['Caddie management'] = '购物篮管理';
+$lang['Caddie'] = '购物篮';
+$lang['Categories authorized thanks to group associations'] = '同组成员可以访问授权类';
+$lang['Categories manual order was saved'] = '类手动排序已保存';
+$lang['Categories ordered alphanumerically'] = '按字母数字顺序排序类';
+$lang['Category elements associated to the following categories: %s'] = '本类成员与如下类产生关联: %s';
+$lang['Check for upgrade failed for unknown reasons.'] = '因未知原因导致更新检测失败.';
+$lang['Check for upgrade'] = '检测更新';
+$lang['Comments for all'] = '对所有成员进行评论';
+$lang['Controversy'] = '辩论';
+$lang['Current name'] = '现用名';
+$lang['Database'] = '数据库';
+$lang['Deactivate'] = '注销';
+$lang['Delete Representant'] = '删除代理人';
+$lang['Delete selected tags'] = '删除所选标签';
+$lang['Delete selected users'] = '删除所选用户';
+$lang['Deletions'] = '删除';
+$lang['Deny selected groups'] = '所选组禁止访问';
+$lang['Deny selected users'] = '所选用户禁止访问';
+$lang['Description'] = '描述';
+$lang['Display options'] = '显示选项';
+$lang['Dissociated'] = '取消联系';
+$lang['Does not represent'] = '不需描绘';
+$lang['Edit all picture informations'] = '编辑修改跟本图片相关的所有信息';
+$lang['Edit selected tags'] = '编辑所选标签';
+$lang['Edit tags'] = '编辑标签';
+$lang['Elements'] = '成员';
+$lang['Email administrators when a new user registers'] = '一旦用户注册就通知管理员';
+$lang['Email administrators when a valid comment is entered'] = '当用户发表评论时就通知管理员';
+$lang['Email administrators when a comment requires validation'] = '当用户要求确认他的评论时通知管理员';
+$lang['Email administrators when a picture is uploaded'] = '当图片被下载时通知管理员';
+$lang['Empty caddie'] = '清空购物篮';
+$lang['Environment'] = '环境';
+$lang['Form'] = '表单';
+$lang['Gallery URL'] = '图库URL';
+$lang['Gallery description'] = '图库简介';
+$lang['Gallery title'] = '图库标题';
+$lang['Grant selected groups'] = '对所选组授权';
+$lang['Grant selected users'] = '对所选用户授权';
+$lang['Group name'] = '组名';
+$lang['Groups'] = '组';
+$lang['Guests'] = '游客';
+$lang['History'] = '历史';
+$lang['Informations'] = '信息';
+$lang['Install'] = '安装';
+$lang['Link all category elements to a new category'] = '把所有本类中的成员关联到一个新类';
+$lang['Link all category elements to some existing categories'] = '把所有本类中的成员关联到已存在类中';
+$lang['Linked categories'] = '关联类';
+$lang['Lock gallery'] = '冻结图库';
+$lang['Maintenance'] = '维护';
+$lang['Manage permissions for a category'] = '对类进行权限管理';
+$lang['Manage permissions for group "%s"'] = '对组 "%s" 进行权限管理';
+$lang['Manage permissions for user "%s"'] = '对用户 "%s" 进行权限管理';
+$lang['Manage tags'] = '标签管理';
+$lang['Members'] = '成员';
+$lang['Metadata synchronized from file'] = '对文件进行元数据同步';
+$lang['Move categories'] = '移动类';
+$lang['Move'] = '移动';
+$lang['Name'] = '名字';
+$lang['New name'] = '新名';
+$lang['New parent category'] = '新父类';
+$lang['New tag'] = '新标签';
+$lang['No tag defined. Use Administration>Pictures>Tags'] = '没有定义任何标签. 使用 Adminstration>Images>Tags';
+$lang['Number of comments per page'] = '每页评论数';
+$lang['Number of rates'] = '投票数';
+$lang['Number of thumbnails to create'] = '缩略图数';
+$lang['Only private categories are listed'] = '只列表显示私类';
+$lang['Operating system'] = '操作系统';
+$lang['Options'] = '选项';
+$lang['Order alphanumerically'] = '字母数字排序';
+$lang['Other private categories'] = '另外私类';
+$lang['Page banner'] = '页标语';
+$lang['Parent category'] = '父类';
+$lang['Path'] = '路径';
+$lang['Permalink'] = '固定链接';
+$lang['Permalink_%s_histo_used_by_%s'] = '链接 %s 先前已经被类 %s 使用. 请删除固定链接历史记录';
+$lang['Permalink_name_rule'] = '固定链接中包含了非法字符（"a-zA-Z0-9", "-", "_" ou "/"）. 禁止使用数字和以"-"开头后面紧跟数字';
+$lang['Permalink %s is already used by category %s'] = '链接 %s 已经被类 %s 使用.';
+$lang['Permalink history'] = '固定链接历史记录';
+$lang['Permalinks'] = '固定链接';
+$lang['Permission denied'] = '禁止访问';
+$lang['Permission granted thanks to a group'] = '同组成员可以访问授权类';
+$lang['Permission granted'] = '允许访问';
+$lang['Picture informations updated'] = '图片更新信息';
+$lang['Plugins'] = '插件';
+$lang['Position'] = '位置';
+$lang['Preferences'] = '个人偏好';
+$lang['Properties'] = '属性';
+$lang['Random picture'] = '随机';
+$lang['Rate date'] = '投票日期';
+$lang['Rating by guests'] = '游客投票数';
+$lang['Rating'] = '投票';
+$lang['Reject All'] = '取消所有修改';
+$lang['Reject'] = '取消';
+$lang['Representant'] = '代理人';
+$lang['Representation of categories'] = '类表现';
+$lang['Representative'] = '代理人';
+$lang['Represents'] = '代理';
+$lang['Save order'] = '保存排序';
+$lang['Save to permalink history'] = '保存到固定链接的历史记录中';
+$lang['Select at least one category'] = '至少选中一个类';
+$lang['Select at least one picture'] = '至少选中一张图片';
+$lang['Select at least one user'] = '至少选中一个用户';
+$lang['Show info'] = '显示所有信息';
+$lang['Site manager'] = '网管';
+$lang['Status'] = '状态';
+$lang['Statistics'] = '统计';
+$lang['Storage category'] = '保存类';
+$lang['Sum of rates'] = '总投票分';
+$lang['Tag "%s" already exists'] = '标签 "%s" 已存在';
+$lang['Tag "%s" was added'] = '标签 "%s" 已加入';
+$lang['Tag selection'] = '标签选择';
+$lang['Take selected elements out of caddie'] = '去除购物篮中所选的图片';
+$lang['The %d following tag were deleted'] = '下面标签 %d 已删除';
+$lang['The %d following tags were deleted'] = '下面标签 %d 已删除';
+$lang['Unable to check for upgrade.'] = '不能检测更新.';
+$lang['Uninstall'] = '卸载';
+$lang['Use default sort order']='使用默认图片排序(在配置文件中定义)';
+$lang['User comments validation'] = '确认用户评论';
+$lang['Users'] = '用户';
+$lang['Validate All'] = '确认所有评论';
+$lang['Validate'] = '确认';
+$lang['Validation'] = '确认';
+$lang['Version'] = '版本';
+$lang['Virtual categories movement'] = '移动虚拟类';
+$lang['Virtual categories to move'] = '将要移动的虚拟类';
+$lang['Virtual category name'] = '虚拟类名';
+$lang['Webmaster cannot be deleted'] = '不能删除网管帐户';
+$lang['You are running on development sources, no check possible.'] = '你运行的是源码开发版本, 不能检测最新版.';
+$lang['You cannot delete your account'] = "你不能删除自己本身帐号";
+$lang['You cannot move a category in its own sub category'] = '你不能把类移到它本身子类中';
+$lang['You need to confirm deletion'] = '你必须确认删除操作';
+$lang['add tags'] = '增加标签';
+$lang['adviser'] = '顾问';
+$lang['associate to category'] = '关联到类';
+$lang['associate to group'] = '关联到组';
+$lang['authorized'] = '授权';
+$lang['cat_add'] = '增加虚拟类';
+$lang['cat_comments_title'] = '允许用户对所选类发表评论';
+$lang['cat_error_name'] = '类名不能为空';
+$lang['cat_lock_title'] = '冻结类';
+$lang['cat_private'] = '私类';
+$lang['cat_public'] = '公类';
+$lang['cat_representant'] = '随机寻找代理人';
+$lang['cat_security'] = '公有 / 私有';
+$lang['cat_status_title'] = '管理所选类权限';
+$lang['cat_upload_title'] = '选择上传类';
+$lang['cat_virtual_added'] = '虚拟类已加入';
+$lang['cat_virtual_deleted'] = '虚拟类已删除';
+$lang['category'] = '类';
+$lang['conf_access'] = '权限类型';
+$lang['conf_comments_title'] = '评论';
+$lang['conf_confirmation'] = '信息已保存到数据库中';
+$lang['conf_display'] = '默认显示';
+$lang['conf_history_title'] = '历史记录';
+$lang['conf_gallery_url_error'] = '图库地址不合法.';
+$lang['conf_main_title'] = '主页';
+$lang['conf_nb_comment_page_error'] = '每页用户评论数必须在5和50之间.';
+$lang['config'] = '设置';
+$lang['confirm'] = '设置';
+$lang['Date'] = '日期';
+$lang['delete category'] = '删除类';
+$lang['dissociate from category'] = '取消类关联';
+$lang['dissociate from group'] = '取消组关联';
+$lang['edit category permissions'] = '修改类权限';
+$lang['editcat_confirm'] = '类信息成功更新.';
+$lang['editcat_uploadable'] = '允许上传图片';
+$lang['elements per page'] = '每页图片';
+$lang['elements'] = '图';
+$lang['enabled_high'] = '激活高清功能';
+$lang['file'] = '文件';
+$lang['filesize'] = '大小';
+$lang['first element added on %s'] = '于 %s 上传了第一幅图';
+$lang['forbidden'] = '禁止';
+$lang['conf_general'] = '普通';
+$lang['global mode'] = '全局模式';
+$lang['group "%s" added'] = '增加 "%s" 组';
+$lang['group "%s" deleted'] = '删除 "%s" 组';
+$lang['group "%s" updated'] = '更新 "%s" 组';
+$lang['group'] = '组';
+$lang['group_add_error1'] = '组名不能包含 " 或 \' 并不能为空.';
+$lang['group_add_error2'] = '组名已存在.';
+$lang['groups'] = '组';
+$lang['instructions'] = '操作指南';
+$lang['is_high_disabled'] = '';
+$lang['is_high_enabled'] = '高清';
+$lang['jump to category'] = '跳转到类';
+$lang['jump to image'] = '跳转到图';
+$lang['leave'] = '开锁';
+$lang['lock'] = '上锁';
+$lang['locked'] = '锁定';
+$lang['manage category elements'] = '管理类成员';
+$lang['manage sub-categories'] = '管理子类';
+$lang['manage'] = '管理';
+$lang['maximum height'] = '最高高度';
+$lang['maximum width'] = '最长长度';
+$lang['nbm_background_treatment_redirect_second'] = '已超过执行时间, 处理还需时间[估计时间: %d 秒].';
+$lang['nbm_background_treatment_redirect_seconds'] = '已超过执行时间, 处理还需时间[估计时间: %d 秒].';
+$lang['nbm_break_timeout_list_user'] = '由于发送用户列表的准备时间受限制,其余用户将不被列出.';
+$lang['nbm_break_timeout_send_mail'] = '发送邮件时间有限,其余邮件被忽略.';
+$lang['nbm_col_check_user_send_mail'] = '发送?';
+$lang['nbm_col_last_send'] = '最后一次发送';
+$lang['nbm_col_mail'] = '邮件';
+$lang['nbm_col_user'] = '用户';
+$lang['nbm_complementary_mail_content'] = '邮件附件';
+$lang['nbm_content_byebye'] = '再见,';
+$lang['nbm_content_goto_1'] = '转至 ';
+$lang['nbm_content_goto_2'] = '.';
+$lang['nbm_content_hello_1'] = '你好 ';
+$lang['nbm_content_hello_2'] = ',';
+$lang['nbm_content_new_elements'] = '加入一些新图片';
+$lang['nbm_content_new_elements_single'] = '时间: ';
+$lang['nbm_content_new_elements_between_1'] = '时间: ';
+$lang['nbm_content_new_elements_between_2'] = ' 至 ';
+$lang['nbm_content_subscribe_by_admin'] = '网管开通了你的邮件通知功能.';
+$lang['nbm_content_subscribe_by_himself'] = '你开通了邮件通知功能.';
+$lang['nbm_content_subscribe_link'] = '注册新用户';
+$lang['nbm_content_problem_contact'] = '如有遇到故障或问题,请发邮件至 ';
+$lang['nbm_content_pb_contact_object'] = '[NBM] 故障或问题';
+$lang['nbm_content_unsubscribe_by_admin'] = '网管取消了你的邮件通知功能.';
+$lang['nbm_content_unsubscribe_by_himself'] = '你取消了你的邮件通知功能.';
+$lang['nbm_content_click_on'] = ', 请点击 ';
+$lang['nbm_content_unsubscribe_link'] = '注销';
+$lang['nbm_info_send_mail_as'] = '图库标题允许为空';
+$lang['nbm_item_notification'] = '通知';
+$lang['nbm_msg_error_sending_email_to'] = '发送邮件 给 %s [%s] 是发生了错误.';
+$lang['nbm_msg_mail_sent_to'] = '已发送至 %s [%s].';
+$lang['nbm_msg_n_mail_sent'] = '%s 邮件已发送.';
+$lang['nbm_msg_n_mails_sent'] = '%s 邮件已发送.';
+$lang['nbm_msg_n_mail_not_send'] = '%s 邮件未被发送.';
+$lang['nbm_msg_n_mails_not_send'] = '%s 邮件未被发送.';
+$lang['nbm_no_mail_to_send'] = '没有邮件要发送.';
+$lang['nbm_no_user_available_to_send_L1'] = '没有用户需要邮件通知.';
+$lang['nbm_no_user_available_to_send_L2'] = '只有当有新图片时,才能使用用户邮件通知功能.';
+$lang['nbm_no_user_available_to_send_L3'] = '任何人都不能使用此标签(网管除外).';
+$lang['nbm_no_user_to send_notifications_by_mail'] = '没有邮件通知用户.';
+$lang['nbm_object_news'] = '新图片已加入';
+$lang['nbm_object_subscribe'] = '注册邮件通知功能';
+$lang['nbm_object_unsubscribe'] = '注销邮件通知功能';
+$lang['nbm_param_mode'] = '设置';
+$lang['nbm_redirect_msg'] = '正在处理.'."\n".'请耐心等待...';
+$lang['nbm_repost_submit'] = '正在继续处理中...';
+$lang['nbm_send_complementary_mail_content'] = '邮件附加内容';
+$lang['nbm_send_detailed_content'] = '增加细节内容';
+$lang['nbm_send_mail_as'] = '发送邮件作为';
+$lang['nbm_send_mail_to_users'] = '给用户发送邮件';
+$lang['nbm_send_mode'] = '发送';
+$lang['nbm_send_options'] = '选项';
+$lang['nbm_send_submit'] = '发送';
+$lang['nbm_subscribe_col'] = '已注册';
+$lang['nbm_subscribe_mode'] = '注册';
+$lang['nbm_title_param'] = '设置参数';
+$lang['nbm_title_send'] = '选择接受邮件用户';
+$lang['nbm_title_subscribe'] = '注册/注销用户';
+$lang['nbm_unsubscribe_col'] = '已注销';
+$lang['nbm_updated_param_count'] = '%d 参数已更新.';
+$lang['nbm_updated_params_count'] = '%d 等参数已更新.';
+$lang['nbm_user_change_enabled_error_on_updated_data_count'] = '%d 用户没有被更新.';
+$lang['nbm_users_change_enabled_error_on_updated_data_count'] = '%d 等用户没有被更新.';
+$lang['nbm_user_change_enabled_false'] = '用户 %s [%s] 从注册名单中删除.';
+$lang['nbm_user_change_enabled_true'] = '用户 %s [%s] 加入到注册名单中.';
+$lang['nbm_user_change_enabled_updated_data_count'] = '%d 用户已更新.';
+$lang['nbm_users_change_enabled_updated_data_count'] = '%d 等用户已更新.';
+$lang['nbm_user_not_change_enabled_false'] = '用户 %s [%s] 没有从注册名单中删除.';
+$lang['nbm_user_not_change_enabled_true'] = '用户 %s [%s] 没有加到注册名当中.';
+$lang['nbm_user_x_added'] = '用户 %s [%s] 已加入.';
+$lang['nbm_warning_subscribe_unsubscribe'] = '注意, 注册或注销都会给相关用户发送邮件';
+$lang['nbm_send_html_mail'] = '以HTML格式发送邮件';
+$lang['nbm_send_recent_post_dates'] = '包括显示最近按日期分组的图片';
+$lang['nbm_info_send_recent_post_dates'] = '只能以HTML格式';
+$lang['no_write_access'] = '不能写入';
+$lang['path'] = '路径';
+$lang['permissions'] = '权限';
+$lang['private'] = '私有';
+$lang['properties'] = '属性';
+$lang['public'] = '公有';
+$lang['purge never used notification feeds'] = '清除从没使用过的通知回馈';
+$lang['purge sessions'] = '清除会话';
+$lang['randomly represented'] = '随机显示';
+$lang['registration_date'] = '保存日期';
+$lang['remote_site'] = '远站点';
+$lang['remote_site_clean'] = '清除';
+$lang['remote_site_clean_hint'] = '删除远端文件listing.xml';
+$lang['remote_site_generate'] = '创建列表';
+$lang['remote_site_generate_hint'] = '创建远端listing.xml文件';
+$lang['remote_site_local_create'] = '创建网站';
+$lang['remote_site_local_found'] = '发现本地文件listing.xml';
+$lang['remote_site_local_update'] = '读本地文件listing.xml并更新';
+$lang['remote_site_test'] = '测试';
+$lang['remote_site_test_hint'] = '测试远端站点';
+$lang['remote_site_uncorrect_url'] = '远端站点地址应以"http"或"https"开头,在两个"/"之间,只能包含"a-zA-Z0-9", "-"或"_"等字符';
+$lang['remove tags'] = '删除所有标签';
+$lang['repair and optimize database'] = '修复和优化数据库';
+$lang['selection'] = '选择';
+$lang['set to'] = '设置为';
+$lang['singly represented'] = '固定显示';
+$lang['site_already_exists'] = '此站点已存在';
+$lang['site_create'] = '新建远端站点 : (在create_listing_file.php文件中给出url地址)';
+$lang['site_created'] = '已创建';
+$lang['site_delete'] = '删除';
+$lang['site_delete_hint'] = '删除此站点和与其相关联的所有信息';
+$lang['site_deleted'] = '已删除';
+$lang['site_err'] = '发生错误';
+$lang['site_err_remote_file_not_found'] = '在远端站点中未发现create_listing_file.php文件';
+$lang['site_local'] = '本地';
+$lang['site_remote'] = '远端';
+$lang['site_synchronize'] = '同步';
+$lang['site_synchronize_hint'] = '根据文件对数据库进行更新';
+$lang['status'] = '状态';
+$lang['storage'] = '文件夹';
+$lang['sub-categories'] = '子类';
+$lang['synchronize metadata'] = '同步元数据';
+$lang['synchronize'] = '同步';
+$lang['target'] = '目标';
+$lang['thumbnail'] = '缩略图';
+$lang['title'] = '标题';
+$lang['title_categories'] = '类管理';
+$lang['title_configuration'] = '配置Piwigo';
+$lang['title_default'] = 'Piwigo管理员';
+$lang['title_edit_cat'] = '修改类';
+$lang['title_groups'] = '组管理';
+$lang['title_liste_users'] = '用户名单';
+$lang['title_picmod'] = '修改图片信息';
+$lang['title_thumbnails'] = '创建缩略图';
+$lang['title_update'] = '根据文件来同步数据库';
+$lang['title_upload'] = '图片等待确认';
+$lang['tn_all'] = '所有';
+$lang['tn_alone_title'] = '没有缩略图的图片 (只有jpeg和png)';
+$lang['tn_err_height'] = '图片高度必须超过(整数)';
+$lang['tn_err_width'] = '图片长度必须超过(整数)';
+$lang['tn_format'] = '对于文件格式';
+$lang['tn_no_missing'] = '没有丢失缩略图';
+$lang['tn_no_support'] = '不支持图片格式或无法显示';
+$lang['tn_params_GD'] = 'GD版';
+$lang['tn_params_title'] = '缩略图参数';
+$lang['tn_results_gen_time'] = '产生于';
+$lang['tn_results_title'] = '缩略图结果';
+$lang['tn_stats'] = '普通统计';
+$lang['tn_stats_max'] = '最多时间';
+$lang['tn_stats_mean'] = '平均时间';
+$lang['tn_stats_min'] = '最少时间';
+$lang['tn_stats_nb'] = '创建的缩略图数';
+$lang['tn_stats_total'] = '总共时间';
+$lang['tn_thisformat'] = '对于此文件格式';
+$lang['unit mode'] = '单一模式';
+$lang['unlocked'] = '解锁';
+$lang['unset'] = '清空';
+$lang['up'] = '置顶';
+$lang['update categories informations'] = '更新类信息';
+$lang['update images informations'] = '更新图信息';
+$lang['update'] = '同步';
+$lang['update_cats_subset'] = '只能处理一个类';
+$lang['update_default_title'] = '选择一个选项';
+$lang['update_display_info'] = '显示全部信息 (增加类, 增加图片, 删除类和图片)';
+$lang['update_err_pwg_version_differs'] = '与远端站点的Piwigo版本不相同';
+$lang['update_err_pwg_version_differs_info'] = '与远端站点文件create_listing_file.php版本和Piwigo版本必须相同';
+$lang['update_err_remote_listing_not_found'] = '没有发现listing.xml文件';
+$lang['update_err_remote_listing_not_found_info'] = '没有发现远端站点listing.xml文件. 可以通过命令"générer le listing" 来产生此文件';
+$lang['update_error_list_title'] = '错误清单';
+$lang['update_errors_caption'] = '错误说明';
+$lang['update_infos_title'] = '详细信息';
+$lang['update_missing_file_or_dir'] = '文件/文件夹打开错误';
+$lang['update_missing_file_or_dir_info'] = '无法打开文件或文件夹(要么根本不存在,要么拒绝访问)';
+$lang['update_missing_tn_info'] = '每个图片文件需要一个缩略图.缩略图应该存在于类文件夹下的子文件夹"thumbnail"中. 缩略图文件名应该以设置参数"prefix_thumbnail"开始, 扩展名为:';
+$lang['update_missing_tn_short'] = '缺少缩略图';
+$lang['update_nb_del_categories'] = '类已从数据库中删除';
+$lang['update_nb_del_elements'] = '图片已从数据库中删除';
+$lang['update_nb_elements_metadata_available'] = '对应同步元数据的候选图片';
+$lang['update_nb_elements_metadata_sync'] = '附有元数据的同步图片信息informations des images synchronisées avec les méta-données';
+$lang['update_nb_errors'] = '同步期间发生错误';
+$lang['update_nb_new_categories'] = '增加类到数据库';
+$lang['update_nb_new_elements'] = '增加图片到数据库';
+$lang['update_nb_upd_elements'] = '更新数据库中的图片';
+$lang['update_part_research'] = '查询文件中的新图片';
+$lang['update_research_added'] = '已加入';
+$lang['update_research_deleted'] = '已删除';
+$lang['update_result_metadata'] = '元数据更新结果';
+$lang['update_simulate'] = '只进行模拟操作(不会改变数据库中的任何内容)';
+$lang['update_simulation_title'] = '[模拟]';
+$lang['update_sync_all'] = '文件夹 + 文件';
+$lang['update_sync_dirs'] = '只对文件夹';
+$lang['update_sync_files'] = '同步文件结构和数据库';
+$lang['update_sync_metadata'] = '根据文件元数据同步数据库中的图片信息';
+$lang['update_sync_metadata_all'] = '包括已经同步的图片';
+$lang['update_used_metadata'] = '已使用过的元数据';
+$lang['update_wrong_dirname_info'] = '文件夹和文件名称只能包含字母, 数字, "-", "_" 和 "."';
+$lang['update_wrong_dirname_short'] = '文件名出错';
+$lang['upload'] = '增加';
+$lang['user "%s" added'] = '用户 "%s" 已加入';
+$lang['user_status'] = '用户状态';
+$lang['user_status_admin'] = '管理员';
+$lang['user_status_generic'] = '一般用户';
+$lang['user_status_guest'] = '来宾';
+$lang['user_status_normal'] = '游客';
+$lang['user_status_webmaster'] = '网管';
+$lang['username'] = '用户名';
+$lang['users'] = '用户';
+$lang['virtual_category'] = '虚拟类';
+$lang['waiting'] = '等待';
+$lang['is_default_group'] = '默认';
+$lang['toggle_is_default_group'] = '赋予\'groupe par défaut\'默认组属性';
+$lang['Advanced_features'] = '高级功能';
+$lang['Elements_not_linked'] = '无链接图片';
+$lang['special_admin_menu'] = '特殊';
+$lang['Duplicates'] = '在好几个物理类中存在同名文件';
+
+$lang['Overall'] = '全局视图';
+$lang['Year'] = '年';
+$lang['Month'] = '月';
+$lang['Day'] = '日';
+$lang['Pages seen'] = '已访问过的页面';
+$lang['Pictures'] = '图片';
+$lang['time'] = '时间';
+$lang['user'] = '用户';
+$lang['IP'] = 'IP';
+$lang['image'] = '图片';
+$lang['section'] = '区域';
+$lang['tags'] = '标签';
+$lang['conf_history_guest'] = '根据来宾来保存访问页面';
+$lang['conf_history_user'] = '根据用户来保存访问页面';
+$lang['conf_history_admin'] = '根据管理员来保存访问页面';
+$lang['cat_options_title'] = '属性';
+$lang['An information email was sent to group "%s"'] = '已向组 "%s" 的所有成员发送了信息邮件';
+$lang['Send an information email to group members'] = '向组成员发送一份信息邮件';
+$lang['Group'] = '组';
+$lang['[%s] Come to visit the category %s'] = '[%s] 访问了类 %s';
+$lang['Hello,'] = '你好,';
+$lang['See you soon.'] = '再见.';
+$lang['Come to discover the category:'] = '挖掘类:';
+$lang['mail_content'] = '邮件内容';
+$lang['none'] = '没有任何人';
+$lang['high'] = '高';
+$lang['other'] = '另外';
+$lang['Element type'] = "内容类型";
+$lang['User'] = '用户';
+$lang['Image id'] = '图片标识符';
+$lang['Summary'] = '概述';
+$lang['%d line filtered'] = '%d 行被过滤';
+$lang['%d lines filtered'] = '%d 行被过滤';
+$lang['%d guest'] = '%d 来宾';
+$lang['%d guests'] = '%d 来宾';
+$lang['Hour'] = '小时';
+$lang['is_the_guest'] = '来宾';
+$lang['is_the_default'] = '默认值';
+$lang['High filesize'] = '高清文件大小';
+// --------- Starting below: New or revised $lang ---- from version 1.7.1
+$lang['Guest cannot be deleted'] = '不能删除来宾';
+$lang['Default user cannot be deleted'] = '不能删除默认用户';
+$lang['purge history detail'] = '清除历史记录';
+$lang['purge history summary'] = '清除历史目录';
+$lang['c13y_title'] = '检测完整性';
+$lang['c13y_Anomaly'] = '异常';
+$lang['c13y_Correction'] = '修复';
+$lang['c13y_Automatic_correction'] = '自动修复';
+$lang['c13y_Impossible_automatic_correction'] = '无法自动修复';
+$lang['c13y_Correction_applied_success'] = '修复成功';
+$lang['c13y_Correction_applied_error'] = '修复出错';
+$lang['c13y_anomaly_count'] = '发现了 %d 异常.';
+$lang['c13y_anomalies_count'] = '发现了 %d 个异常.';
+$lang['c13y_anomaly_corrected_count'] = '修正了 %d 异常.';
+$lang['c13y_anomalies_corrected_count'] = '修正了 %d 个异常.';
+$lang['c13y_anomaly_not_corrected_count'] = '不能修正 %d 异常.';
+$lang['c13y_anomalies_not_corrected_count'] = '不能修正 %d 个异常.';
+$lang['c13y_more_info'] = '获取更多信息，请到 %s 或者 %s ';
+$lang['c13y_more_info_forum'] = '论坛';
+$lang['c13y_more_info_wiki'] = 'wiki';
+$lang['c13y_exif_anomaly'] = ' %s 值不是一个正确文件，因为我们不支持exif格式';
+$lang['c13y_exif_correction'] = '在配置文件config_local.inc.php中 %s 应该设置为"false"';
+$lang['c13y_guest_non_existent'] = '主要"guest"用户不存在';
+$lang['c13y_bad_guest_status'] = '主要"guest"用户状态异常';
+$lang['c13y_default_non_existent'] = '默认帐户不再存在';
+$lang['c13y_webmaster_non_existent'] = '主要网管帐户不再存在';
+$lang['c13y_bad_webmaster_status'] = '主要网管用户状态异常';
+$lang['c13y_user_created'] = '用户 "%s" 已创建，密码是"%s"';
+$lang['c13y_user_status_updated'] = '用户 "%s" 状态已更新';
+$lang['add new elements to caddie'] = '把所有新图片放到购物篮';
+// --------- Starting below: New or revised $lang ---- from Butterfly
+$lang['no_display_thumbnail'] = '不显示缩略图';
+$lang['display_thumbnail_classic'] = '正常显示';
+$lang['display_thumbnail_hoverbox'] = '俯瞰显示';
+$lang['Thumbnails'] = '缩略图';
+$lang['obligatory_user_mail_address'] = '每个用户必须提供邮箱地址';
+$lang['Minimum privacy level'] = '最小隐私等级';
+$lang['Privacy level'] = '隐私等级';
+$lang['Level 0'] = '---';
+$lang['Level 1'] = '联系';
+$lang['Level 2'] = '朋友';
+$lang['Level 4'] = '家庭';
+$lang['Level 8'] = '管理者';
+$lang['c13y_maintenance'] = '重新完整性检测';
+$lang['Check all'] = '全选';
+$lang['Uncheck all'] = '取消全选';
+$lang['c13y_check_auto'] = '自动选择';
+$lang['c13y_submit_correction'] = '应用自动选择';
+$lang['c13y_submit_ignore'] = '忽视选择异常';
+$lang['c13y_submit_refresh'] = '刷新';
+$lang['c13y_ignore_msg1'] = '此异常将被忽略，待下次版本中解决';
+$lang['c13y_ignore_msg2'] = '异常更正将取消忽略事件';
+$lang['c13y_anomaly_ignored_count'] = '%d 异常被忽略.';
+$lang['c13y_anomalies_ignored_count'] = '%d 异常被忽略.';
+$lang['plugins_need_update'] = '必须更新插件';
+$lang['plugins_dontneed_update'] = '插件已是最新版本';
+$lang['plugins_cant_check'] = '无法核查下面插件';
+$lang['plugins_actual_version'] = '最新版';
+$lang['plugins_new_version'] = '可使用版本';
+$lang['plugins_auto_update'] = '自动更新';
+$lang['plugins_auto_install'] = '自动安装';
+$lang['plugins_download'] = '下载文件';
+$lang['plugins_tab_list'] = '插件列表';
+$lang['plugins_tab_update'] = '检查更新';
+$lang['plugins_tab_new'] = '其他插件';
+$lang['plugins_revisions'] = '最新修订版';
+$lang['plugins_delete'] = '删除';
+$lang['plugins_confirm_install'] = '确定安装此插件吗?';
+$lang['plugins_confirm_delete'] = '确定要删除此插件吗?';
+$lang['plugins_confirm_upgrade'] = '确定安装此更新吗? 你必须核实无需卸载操作再进行安装此更新.';
+$lang['plugins_upgrade_ok'] = '%s 成功更新.';
+$lang['plugins_install_ok'] = '插件复制成功.';
+$lang['plugins_install_need_activate'] = '在插件列表中安装和启动插件.';
+$lang['plugins_temp_path_error'] = '无法创建临时文件.';
+$lang['plugins_dl_archive_error'] = '无法下载归档文件.';
+$lang['plugins_archive_error'] = '无法读取或解压归档文件.';
+$lang['plugins_extract_error'] = '在解压文件(%s) 发生错误.';
+$lang['plugins_check_chmod'] = '请核实"plugins"文件夹及其子文件夹的权限(CHMOD).';
+$lang['plugins_server_error'] = '无法连接到服务器.';
+$lang['Purge compiled templates'] = '清除编译模板';
+$lang['Caddie is currently empty'] = '目前购物篮为空.';
+$lang['DEMO'] = '应用演示';
+$lang['HOME'] = 'Piwigo主页';
+$lang['FORUM'] = '支持';
+$lang['BUGS'] = 'Bugs';
+$lang['EXTENSIONS'] = '扩展';
+$lang['WIKI / DOC'] = '文档';
+$lang['conf_upload_title'] = '下载';
+$lang['Show upload link every time'] = '总是显示增加图片链接';
+$lang['User access level to upload'] = '用户可上传权限级别';
+$lang['ACCESS_0'] = '自由存取';
+$lang['ACCESS_1'] = '对所有人开放';
+$lang['ACCESS_2'] = '只对注册用户开放';
+$lang['ACCESS_3'] = '只对管理员开放';
+$lang['ACCESS_4'] = '只对网管开放';
+$lang['ACCESS_5'] = '对任何人都不开放';
+$lang['A new version of Piwigo is available.'] = 'Piwigo新版发布.';
+$lang['Piwigo Administration'] = 'Piwigo管理';
+$lang['Piwigo version'] = 'Piwigo版本';
+$lang['You are running the latest version of Piwigo.'] = '你运行的是Piwigo最新版.';
+$lang['c13y_version_anomaly'] = '%s [%s]安装版本跟[%s]版本不兼容';
+$lang['c13y_version_correction'] = '为了获得全部功能，你应该更新系统，否则程序运行不正常。';
+$lang['Deleted on'] = '删除于';
+$lang['Last hit'] =  '最后一次查看';
+$lang['Hits'] = '使用';
+$lang['GD library is missing'] = '缺少GD库';
+$lang['conf_extents'] = '模板';
+$lang['extend_for_templates'] = '扩展模板';
+$lang['Replacement of original templates'] = '用位于template-extension文件夹下的用户自定义模板更换原模板';
+$lang['Replacers'] = '自定义模板';
+$lang['Original templates'] = '原模板';
+$lang['Optional URL keyword'] = '可选URL关键字';
+$lang['Templates recorded.'] = '模板设置已保存.';
+$lang['Optimizations completed'] = '优化成功.';
+$lang['Optimizations errors'] = '有些优化发生错误.';
+$lang['delete this comment'] = '删除评论';
+$lang['link_info_image'] = '修改信息';
+$lang['edit category informations'] = '编辑类信息';
+$lang['nothing'] = '没有内容';
+$lang['overrides existing values with empty ones'] = '用空数据来删除已存在的数据';
+$lang['manage image ranks'] = '管理图片排序';
+$lang['Manage image ranks'] = '管理图片排序';
+$lang['Edit ranks'] = '修改排序方式';
+$lang['No element in this category'] = '该类中没有图片';
+$lang['Images manual order was saved'] = '图片手动排序已保存';
+$lang['ranks'] = '顺序';
+$lang['Drag to re-order'] = '拖放进行排序';
+$lang['Unable to retrieve server informations since allow_url_fopen is disabled.'] = '由于allow_url_fopen功能没激活导致无法连接服务器.';
+$lang['Quick Local Synchronization'] = '快速同步';
+$lang['No photo can be deleted'] = '没有图片可以删除';
+$lang['Note: Only deletes photos added with pLoader'] = '注意: 只有通过pLoader上传的图片才能被删除';
+$lang['Delete selected photos'] = '删除图片';
+$lang['%d photo was deleted'] = '%d 图片被删除';
+$lang['%d photos were deleted'] = '%d 图片被删除';
+$lang['Bound template'] = '模板绑定';
+$lang['Downloads'] = '下载';
+$lang['Released on'] = '发布于';
+$lang['Number of downloads'] = '下载次数';
+// --------- Starting below: New or revised $lang ---- from Colibri (2.1)
+?>
Index: /tags/2.0.2/language/zh_CN/common.lang.php
===================================================================
--- /tags/2.0.2/language/zh_CN/common.lang.php	(revision 3278)
+++ /tags/2.0.2/language/zh_CN/common.lang.php	(revision 3278)
@@ -0,0 +1,368 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Langage informations
+$lang_info['language_name'] = '中文';
+$lang_info['country'] = '中国';
+$lang_info['direction'] = 'ltr';
+$lang_info['code'] = 'cn';
+$lang_info['zero_plural'] = false;
+
+$lang['%.2f (rated %d times, standard deviation = %.2f)'] = '%.2f (标注 %d 次, 标准差 = %.2f)';
+$lang['%d Kb'] = '%d KB';
+$lang['%d category updated'] = '%d 类已更新';
+$lang['%d categories updated'] = '%d 等多类已更新';
+$lang['%d comment to validate'] = '%d 条用户评论被确认';
+$lang['%d comments to validate'] = '%d 条用户评论被确认';
+$lang['%d new comment'] = '%d 新评论';
+$lang['%d new comments'] = '%d 新评论';
+$lang['%d comment'] = '%d 评论';
+$lang['%d comments'] = '%d 评论';
+$lang['%d hit'] = '查看 %d 次';
+$lang['%d hits'] = '查看 %d 次';
+$lang['%d new element'] = '%d 新图片';
+$lang['%d new elements'] = '%d 新图片';
+$lang['%d new user'] = '%d 新用户';
+$lang['%d new users'] = '%d 新用户';
+$lang['%d waiting element'] = '%d 等待项';
+$lang['%d waiting elements'] = '%d 等待项';
+$lang['About'] = '关于';
+$lang['All tags must match'] = '所有标签必须匹配';
+$lang['All tags'] = '所有标签';
+$lang['Any tag'] = '任何标签';
+$lang['At least one listed rule must be satisfied.'] = '至少符合一项标准.';
+$lang['At least one tag must match'] = '至少匹配一个标签';
+$lang['Author'] = '拥有者';
+$lang['Average rate'] = '评分';
+$lang['Categories'] = '类';
+$lang['Category'] = '类';
+$lang['Close this window'] = '关闭窗口';
+$lang['Complete RSS feed'] = '完整RSS回馈(图片, 评论等)';
+$lang['Confirm Password'] = '重复输入密码';
+$lang['Connection settings'] = '连接设置';
+$lang['Connection'] = '连接';
+$lang['Contact webmaster'] = '联系网管';
+$lang['Create a new account'] = '新建帐号';
+$lang['Created on'] = '创建于';
+$lang['Creation date'] = '创建日期';
+$lang['Current password is wrong'] = '密码错误';
+$lang['Dimensions'] = '尺寸';
+$lang['Display'] = '显示';
+$lang['Each listed rule must be satisfied.'] = '必须符合每项标准';
+$lang['Email address is missing'] = '缺少邮箱地址';
+$lang['Email address'] = '邮箱地址';
+$lang['Enter your personnal informations'] = '输入您的个人信息';
+$lang['Error sending email'] = '发送邮件出错';
+$lang['File name'] = '文件名';
+$lang['File'] = '文件';
+$lang['Filesize'] = '文件大小';
+$lang['Filter and display'] = '过滤并显示';
+$lang['Filter'] = '过滤';
+$lang['Forgot your password?'] = '忘记密码?';
+$lang['Go through the gallery as a visitor'] = '以游客身份浏览图库';
+$lang['Help'] = '帮助';
+$lang['Identification'] = '身份鉴别';
+$lang['Image only RSS feed'] = '图片RSS';
+$lang['Keyword'] = '关键字';
+$lang['Links'] = '链接';
+$lang['Mail address'] = $lang['Email address'];
+$lang['N/A'] = '不存在';
+$lang['New on %s'] = '新创于 %s';
+$lang['New password confirmation does not correspond'] = '前后密码不一致';
+$lang['New password sent by email'] = '新密码已发送';
+$lang['No email address'] = '没有邮箱地址';
+$lang['No user matches this email address'] = '此邮箱地址不存在';
+$lang['Notification'] = '通知';
+$lang['Number of items'] = '总数';
+$lang['Original dimensions'] = '原始大小';
+$lang['Password forgotten'] = '忘记密码';
+$lang['Password'] = '密码';
+$lang['Post date'] = '上传日期';
+$lang['Posted on'] = '上传于';
+$lang['Profile'] = '用户信息';
+$lang['Quick connect'] = '快速连接';
+$lang['RSS feed'] = 'RSS流';
+$lang['Rate'] = '评分';
+$lang['Register'] = '注册';
+$lang['Registration'] = '注册';
+$lang['Related tags'] = '关联标签';
+$lang['Reset'] = '重新设置';
+$lang['Retrieve password'] = '重新取得密码';
+$lang['Search rules'] = '搜索规则';
+$lang['Search tags'] = '搜索标签';
+$lang['Search'] = '搜索';
+$lang['See available tags'] = '查看现有标签';
+$lang['Send new password'] = '发送新密码';
+$lang['Since'] = '自从';
+$lang['Sort by'] = '排序';
+$lang['Sort order'] = '排序规则';
+$lang['Tag'] = '标签';
+$lang['Tags'] = '标签簇';
+$lang['The RSS notification feed provides notification on news from this website : new pictures, updated categories, new comments. Use a RSS feed reader.'] = 'RSS提供通知更新事件功能 : 加入新图片, 更新图类, 新的用户评论. 请使用相关软件来获得RSS.';
+$lang['Unknown feed identifier'] = '未知流标识';
+$lang['User comments'] = '用户评论';
+$lang['Username'] = '用户名';
+$lang['Visits'] = '访问';
+$lang['Webmaster'] = '网管';
+$lang['Week %d'] = '星期 %d';
+$lang['about_page_title'] = '关于Piwigo';
+$lang['access_forbiden'] = '你无权访问此页';
+$lang['add to caddie'] = '放入购物篮';
+$lang['add_favorites_hint'] = '把图片放到收藏夹';
+$lang['admin'] = '管理员';
+$lang['adviser_mode_enabled'] = '激活建议模式';
+$lang['all'] = '所有';
+$lang['ascending'] = '升序';
+$lang['author(s) : %s'] = '拥有者 : %s';
+$lang['auto_expand'] = '展开所有类';
+$lang['became available after %s (%s)'] = '插入到 %s (%s) 之后';
+$lang['became available before %s (%s)'] = '插入到 %s (%s) 之前';
+$lang['became available between %s (%s) and %s (%s)'] = '插入到 %s (%s) 和 le %s (%s) 之间';
+$lang['became available on %s'] = '插入 %s';
+$lang['best_rated_cat'] = '得票最高';
+$lang['best_rated_cat_hint'] = '显示得票最高的图片';
+$lang['caddie'] = '购物篮';
+$lang['calendar'] = '日历';
+$lang['calendar_any'] = '所有';
+$lang['calendar_hint'] = '按时间顺序来显示';
+$lang['calendar_picture_hint'] = '显示这之后的图片 ';
+$lang['calendar_view'] = '视图';
+$lang['chronology_monthly_calendar'] = '月历';
+$lang['chronology_monthly_list'] = '月清单';
+$lang['chronology_weekly_list'] = '周清单';
+$lang['click_to_redirect'] = '如果你的浏览器不支持自动转页，请按这里。';
+$lang['comment date'] = '评论日期';
+$lang['comment'] = '评论';
+$lang['comment_added'] = '评论已保存';
+$lang['comment_anti-flood'] = '反灌水系统 : 请稍候再加评论';
+$lang['comment_not_added'] = '由于不符合格式规定，你的评论不能被保存';
+$lang['comment_to_validate'] = '评论需经管理员确认才能显示在页面里。';
+$lang['comment_user_exists'] = '用户名已存在';
+$lang['comments'] = '评论';
+$lang['comments_add'] = '加评论';
+$lang['created after %s (%s)'] = '创建于 %s (%s) 之后';
+$lang['created before %s (%s)'] = '创建于 %s (%s) 之前';
+$lang['created between %s (%s) and %s (%s)'] = '创建于 %s (%s) 和 le %s (%s) 之间';
+$lang['created on %s'] = '创建于 %s';
+$lang['customize'] = '自定义';
+$lang['customize_page_title'] = '自定义页标题';
+$lang['day'][0] = '星期日';
+$lang['day'][1] = '星期一';
+$lang['day'][2] = '星期二';
+$lang['day'][3] = '星期三';
+$lang['day'][4] = '星期四';
+$lang['day'][5] = '星期五';
+$lang['day'][6] = '星期六';
+$lang['default_sort'] = '默认';
+$lang['del_favorites_hint'] = '从收藏夹中删除此图片';
+$lang['delete'] = '删除';
+$lang['descending'] = '降序';
+$lang['download'] = '下载';
+$lang['download_hint'] = '下载此文件';
+$lang['edit'] = '编辑';
+$lang['err_date'] = '日期出错';
+$lang['excluded'] = '不包括';
+$lang['favorite_cat'] = '收藏夹';
+$lang['favorite_cat_hint'] = '显示收藏图片';
+$lang['favorites'] = '收藏';
+$lang['first_page'] = '首页';
+$lang['gallery_locked_message'] = '系统维护，请稍候再试。';
+$lang['generation_time'] = '页面创建时间';
+$lang['guest'] = '游客';
+$lang['hello'] = '你好';
+$lang['hint_admin'] = '只限于管理者';
+$lang['hint_category'] = '显示所有此类图片';
+$lang['hint_comments'] = '查看最新用户评论';
+$lang['hint_customize'] = '个性化设置';
+$lang['hint_search'] = '搜索';
+$lang['home'] = '主页';
+$lang['identification'] = '身份鉴别';
+$lang['images_available_cpl'] = '在此类中';
+$lang['images_available_cat'] = '在 %d 子类中';
+$lang['images_available_cats'] = '在 %d 等子类中';
+$lang['included'] = '包括';
+$lang['invalid_pwd'] = '密码不正确!';
+$lang['language'] = '语言';
+$lang['last %d days'] = '最近%d天';
+$lang['last_page'] = '最后';
+$lang['logout'] = '注销';
+$lang['mail_address'] = $lang['Email address'];
+$lang['mandatory'] = '必需';
+$lang['maxheight'] = '图片的最大长度';
+$lang['maxheight_error'] = '图片最大长度必须大于50';
+$lang['maxwidth'] = '图片的最大宽度';
+$lang['maxwidth_error'] = '图片最大宽度必须大于50';
+$lang['mode_created_hint'] = '通过创建时间显示日历';
+$lang['mode_flat_hint'] = '平铺显示所有类及其子类图片';
+$lang['mode_normal_hint'] = '返回到普通模式显示';
+$lang['mode_posted_hint'] = '通过发送时间来显示日历';
+$lang['month'][10] = '十月';
+$lang['month'][11] = '十一月';
+$lang['month'][12] = '十二月';
+$lang['month'][1] = '一月';
+$lang['month'][2] = '二月';
+$lang['month'][3] = '三月';
+$lang['month'][4] = '四月';
+$lang['month'][5] = '五月';
+$lang['month'][6] = '六月';
+$lang['month'][7] = '七月';
+$lang['month'][8] = '八月';
+$lang['month'][9] = '九月';
+$lang['most_visited_cat'] = '最受喜欢';
+$lang['most_visited_cat_hint'] = '显示查看次数最多的图片';
+$lang['nb_image_line_error'] = '每行图片数必须是非零整数';
+$lang['nb_image_per_row'] = '每行图片数';
+$lang['nb_line_page_error'] = '每页总行数必须是非零整数';
+$lang['nb_row_per_page'] = '每页行数';
+$lang['nbm_unknown_identifier'] = '帐户不存在';
+$lang['new_password'] = '新密码';
+$lang['new_rate'] = '对图片投票';
+$lang['next_page'] = '下一页';
+$lang['no_category'] = '主页';
+$lang['no_rate'] = '没有被投票';
+$lang['note_filter_day'] = '只显示最近 %d 天的图片.';
+$lang['note_filter_days'] = '只显示最近 %d 天的图片.';
+$lang['password updated'] = '密码已更新';
+$lang['periods_error'] = '再次发表间隔时间必须是正整数';
+$lang['picture'] = '图片';
+$lang['picture_high'] = '点击查看大图片';
+$lang['picture_show_metadata'] = '显示文件的元数据';
+$lang['powered_by'] = '基于';
+$lang['preferences'] = '使用偏好';
+$lang['previous_page'] = '前页';
+$lang['random_cat'] = '随机图片';
+$lang['random_cat_hint'] = '随机显示图片';
+$lang['recent_cats_cat'] = '最近更新的类';
+$lang['recent_cats_cat_hint'] = '显示最近更新或创建的类';
+$lang['recent_period'] = '最近阶段';
+$lang['recent_pics_cat'] = '最新图片';
+$lang['recent_pics_cat_hint'] = '显示最新图片';
+$lang['redirect_msg'] = '转跳至...';
+$lang['reg_err_login1'] = '请输入用户名';
+$lang['reg_err_login2'] = '用户名不能以空格结尾';
+$lang['reg_err_login3'] = '用户名不能以空格开头';
+$lang['reg_err_login5'] = '用户名已存在';
+$lang['reg_err_mail_address'] = '邮件地址格式必须符合标准邮件地址格式 xxx@yyy.eee (例如 : jack@altern.org)';
+$lang['reg_err_pass'] = '请输入新密码';
+$lang['remember_me'] = '自动连接';
+$lang['remove this tag'] = '删除此标签';
+$lang['representative'] = '代理人';
+$lang['return to homepage'] = '返回首页';
+$lang['search_author'] = '搜索上传者';
+$lang['search_categories'] = '在这些类中查询';
+$lang['search_date'] = '通过日期查询';
+$lang['search_date_from'] = '开始日期';
+$lang['search_date_to'] = '最终日期';
+$lang['search_date_type'] = '日期类型';
+$lang['search_keywords'] = '关键字';
+$lang['search_mode_and'] = '以与模式查询';
+$lang['search_mode_or'] = '以或模式查询';
+$lang['search_one_clause_at_least'] = '查询语句不能为空';
+$lang['search_options'] = '查询选项';
+$lang['search_result'] = '搜索结果';
+$lang['search_subcats_included'] = '在子类中搜索';
+$lang['search_title'] = '搜索';
+$lang['searched words : %s'] = '搜索词 : %s';
+$lang['send_mail'] = '联系';
+$lang['set as category representative'] = '选择此类代理';
+$lang['show_nb_comments'] = '显示评论总数';
+$lang['show_nb_hits'] = '显示查看次数';
+$lang['slideshow'] = '幻灯片放映';
+$lang['slideshow_stop'] = '停止幻灯片放映';
+$lang['special_categories'] = '特别类';
+$lang['sql_queries_in'] = 'sql查询语句';
+$lang['start_filter_hint'] = '只显示最近内容';
+$lang['stop_filter_hint'] = '返回到所有图片页面';
+$lang['the beginning'] = '开始';
+$lang['theme'] = '主题';
+$lang['thumbnails'] = '缩略图';
+$lang['title_menu'] = '菜单';
+$lang['title_send_mail'] = '网站评论';
+$lang['today'] = '今天';
+$lang['update_rate'] = '更改投票';
+$lang['update_wrong_dirname'] = '文件夹名不合法';
+$lang['upload_advise_filesize'] = '上传图片最大尺寸 : ';
+$lang['upload_advise_filetype'] = '支持图片格式：jpg, png ou gif';
+$lang['upload_advise_height'] = '上传图片最大长度 : ';
+$lang['upload_advise_thumbnail'] = '此选项可选, 但强烈推荐 : 选择相对应的缩略图';
+$lang['upload_advise_width'] = '上传图片最大宽度 : ';
+$lang['upload_author'] = '上传者';
+$lang['upload_cannot_upload'] = '上传失败';
+$lang['upload_err_username'] = '缺少用户名';
+$lang['upload_file_exists'] = '文件已存在';
+$lang['upload_filenotfound'] = '不支持此文件格式';
+$lang['upload_forbidden'] = '不能把这图片加入到此类';
+$lang['upload_name'] = '图片名';
+$lang['upload_picture'] = '上传图片';
+$lang['upload_successful'] = '上传成功, 但必须经管理员确认才能看到图片';
+$lang['upload_title'] = '上传图片';
+$lang['useful when password forgotten'] = '忘记密码';
+$lang['qsearch'] = '快速搜索';
+$lang['Connected user: %s'] = '在线用户: %s';
+$lang['IP: %s'] = 'IP地址: %s';
+$lang['Browser: %s'] = '浏览器: %s';
+$lang['Author: %s'] = '上传者: %s';
+$lang['Comment: %s'] = '评论: %s';
+$lang['Delete: %s'] = '删除: %s';
+$lang['Validate: %s'] = '确认: %s';
+$lang['Comment by %s'] = '评论人 %s';
+$lang['User: %s'] = '用户: %s';
+$lang['Email: %s'] = 'Email: %s';
+$lang['Admin: %s'] = '管理员: %s';
+$lang['Registration of %s'] = '注册 %s';
+$lang['Category: %s'] = '类别: %s';
+$lang['Picture name: %s'] = '图片名: %s';
+$lang['Creation date: %s'] = '创建日期: %d';
+$lang['Waiting page: %s'] = '等待页面: %s';
+$lang['Picture uploaded by %s'] = '图片上载者 %s';
+// --------- Starting below: New or revised $lang ---- from version 1.7.1
+$lang['guest_must_be_guest'] = '如果游客反常拥有普通用户才拥有状态，请向网络管理员报告。';
+// --------- Starting below: New or revised $lang ---- from Butterfly (2.0)
+$lang['Administrator, webmaster and special user cannot use this method'] = '管理员, 网管和特定用户不能使用此方法功能';
+$lang['reg_err_mail_address_dbl'] = '邮箱地址已存在';
+$lang['Category results for'] = '符合查询类结果';
+$lang['Tag results for'] = '符合查询标签结果';
+$lang['from %s to %s'] = '从 %s 到 %s';
+$lang['start_play'] = '播放';
+$lang['stop_play'] = '暂停';
+$lang['start_repeat'] = '重复播放';
+$lang['stop_repeat'] = '停止重复播放';
+$lang['inc_period'] = '减慢播放速度';
+$lang['dec_period'] = '加快播放速度';
+$lang['Submit'] = '确认';
+$lang['Yes'] = '是';
+$lang['No'] = '否';
+$lang['%d element']='%d 图片';
+$lang['%d elements']='%d 图片';
+$lang['%d element are also linked to current tags'] = '%d 图片同时与当前标签相关';
+$lang['%d elements are also linked to current tags'] = '%d 图片同时与当前标签相关';
+$lang['See elements linked to this tag only'] = '只查看和这标签相关的图片';
+$lang['elements posted during the last %d days'] = '图片在最近%d天里更新';
+$lang['Choose an image'] = '选择图片';
+$lang['Piwigo Help'] = 'Piwigo帮助';
+$lang['Rank'] = '分类';
+$lang['group by letters'] = '按字母顺序分';
+$lang['letters'] = '字母';
+$lang['show tag cloud'] = '显示标签云';
+$lang['cloud'] = '云';
+?>
Index: /tags/2.0.2/language/zh_CN/install.lang.php
===================================================================
--- /tags/2.0.2/language/zh_CN/install.lang.php	(revision 3278)
+++ /tags/2.0.2/language/zh_CN/install.lang.php	(revision 3278)
@@ -0,0 +1,74 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+$lang['Installation'] = '安装';
+$lang['Initial_config'] = '基本设置';
+$lang['Default_lang'] = '图库默认语言';
+$lang['step1_title'] = '数据库设置';
+$lang['step2_title'] = '管理员帐户设置';
+$lang['Start_Install'] = '开始安装';
+$lang['reg_err_mail_address'] = '邮箱地址格式 xxx@yyy.eee (例 : jack@altern.org)';
+
+$lang['install_webmaster'] = '管理员';
+$lang['install_webmaster_info'] = '所有用户都能看到此帐户。必须提供此帐户来管理网站';
+
+$lang['step1_confirmation'] = '输入参数正确';
+$lang['step1_err_db'] = '服务器连接正常，但是无法连接到数据库';
+$lang['step1_err_server'] = '无法连接到服务器';
+
+$lang['step1_host'] = 'MySQL主机地址';
+$lang['step1_host_info'] = 'localhost, sql.multimania.com, toto.freesurf.fr';
+$lang['step1_user'] = '用户';
+$lang['step1_user_info'] = '主机用户名';
+$lang['step1_pass'] = '密码';
+$lang['step1_pass_info'] = '主机用户密码';
+$lang['step1_database'] = '数据库名称';
+$lang['step1_database_info'] = '在主机设定的数据库名称';
+$lang['step1_prefix'] = '表名称前缀';
+$lang['step1_prefix_info'] = '所有的表名称都加此前缀(有利于数据库管理)';
+$lang['step2_err_login1'] = '请输入网管名';
+$lang['step2_err_login3'] = '网管名不应包含字符 " 和 \'';
+$lang['step2_err_pass'] = '请再次输入密码';
+$lang['install_end_title'] = '安装结束';
+$lang['step2_pwd'] = '密码';
+$lang['step2_pwd_info'] = '请小心保管好此密码，它允许你操作管理板块。';
+$lang['step2_pwd_conf'] = '密码 [ 确认 ]';
+$lang['step2_pwd_conf_info'] = '核实';
+$lang['step1_err_copy'] = '请拷贝短横线之间的粉红色文字并粘贴到位于Piwigo安装目录下的include文件夹里的mysql.inc.php文件中（每行不允许有空格或回车）';
+$lang['install_help'] = '需要帮助？ 请到<a href="%s">Piwigo论坛</a>提出你的问题.';
+$lang['install_end_message'] = '程序配置正确，继续完成下面步骤<br /><br />
+* 请到登录页面并且用网管帐号登录<br />
+* 进入管理页面并会告知如何把图片移到文件夹中。';
+$lang['conf_mail_webmaster'] = '管理员Email地址';
+$lang['conf_mail_webmaster_info'] = '游客通过此Email跟你联系';
+
+$lang['PHP 5 is required'] = '必须PHP 5版本';
+$lang['It appears your webhost is currently running PHP %s.'] = '你主机PHP版本好像是PHP %s.';
+$lang['Piwigo may try to switch your configuration to PHP 5 by creating or modifying a .htaccess file.'] = 'Piwigo试着创建或修改.htaccess文件来转换到PHP 5。';
+$lang['Note you can change your configuration by yourself and restart Piwigo after that.'] = '注意；你也可以自己修改设置PHP然后重新启动Piwigo。';
+$lang['Try to configure PHP 5'] = '试试配置PHP 5';
+$lang['Sorry!'] = '对不起!';
+$lang['Piwigo was not able to configure PHP 5.'] = 'Piwigo不能设置PHP 5.';
+$lang["You may referer to your hosting provider's support and see how you could switch to PHP 5 by yourself."] = '你应该联系你的主机管理员并向其请教如何设置PHP 5.';
+$lang['Hope to see you back soon.'] = '希望下次再见到你...';
+?>
Index: /tags/2.0.2/language/zh_CN/iso.txt
===================================================================
--- /tags/2.0.2/language/zh_CN/iso.txt	(revision 3278)
+++ /tags/2.0.2/language/zh_CN/iso.txt	(revision 3278)
@@ -0,0 +1,1 @@
+﻿简体中文 [CN]
Index: /tags/2.0.2/nbm.php
===================================================================
--- /tags/2.0.2/nbm.php	(revision 3278)
+++ /tags/2.0.2/nbm.php	(revision 3278)
@@ -0,0 +1,87 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+
+//--------------------------------------------------------------------- include
+define('PHPWG_ROOT_PATH','./');
+include_once(PHPWG_ROOT_PATH.'include/common.inc.php');
+check_status(ACCESS_FREE);
+include_once(PHPWG_ROOT_PATH.'include/functions_notification.inc.php');
+include_once(PHPWG_ROOT_PATH.'include/functions_mail.inc.php');
+include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+include_once(PHPWG_ROOT_PATH.'admin/include/functions_notification_by_mail.inc.php');
+// Translations are in admin file too
+load_language('admin.lang');
+// Need to update a second time
+trigger_action('loading_lang');
+load_language('local.lang', '', array('no_fallback'=>true) );
+
+
+
+// +-----------------------------------------------------------------------+
+// | Main                                                                  |
+// +-----------------------------------------------------------------------+
+$page['errors'] = array();
+$page['infos'] = array();
+
+if (isset($_GET['subscribe'])
+    and preg_match('/^[A-Za-z0-9]{16}$/', $_GET['subscribe']))
+{
+  subscribe_notification_by_mail(false, array($_GET['subscribe']));
+}
+else
+if (isset($_GET['unsubscribe'])
+    and preg_match('/^[A-Za-z0-9]{16}$/', $_GET['unsubscribe']))
+{
+  unsubscribe_notification_by_mail(false, array($_GET['unsubscribe']));
+}
+else
+{
+  array_push($page['errors'], l10n('nbm_unknown_identifier'));
+}
+
+// +-----------------------------------------------------------------------+
+// | template initialization                                               |
+// +-----------------------------------------------------------------------+
+$title = l10n('nbm_item_notification');
+$page['body_id'] = 'theNBMPage';
+include(PHPWG_ROOT_PATH.'include/page_header.php');
+
+$template->set_filenames(array('nbm'=>'nbm.tpl'));
+
+// +-----------------------------------------------------------------------+
+// | errors & infos                                                        |
+// +-----------------------------------------------------------------------+
+$template->assign(
+    array(
+      'errors' => $page['errors'],
+      'infos' => $page['infos'],
+    )
+  );
+
+// +-----------------------------------------------------------------------+
+// | html code display                                                     |
+// +-----------------------------------------------------------------------+
+$template->parse('nbm');
+include(PHPWG_ROOT_PATH.'include/page_tail.php');
+?>
Index: /tags/2.0.2/notification.php
===================================================================
--- /tags/2.0.2/notification.php	(revision 3278)
+++ /tags/2.0.2/notification.php	(revision 3278)
@@ -0,0 +1,88 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// +-----------------------------------------------------------------------+
+// |                           initialization                              |
+// +-----------------------------------------------------------------------+
+
+define('PHPWG_ROOT_PATH','./');
+include_once( PHPWG_ROOT_PATH.'include/common.inc.php' );
+
+// +-----------------------------------------------------------------------+
+// | Check Access and exit when user status is not ok                      |
+// +-----------------------------------------------------------------------+
+check_status(ACCESS_GUEST);
+
+// +-----------------------------------------------------------------------+
+// |                          new feed creation                            |
+// +-----------------------------------------------------------------------+
+
+$page['feed'] = find_available_feed_id();
+
+$query = '
+INSERT INTO '.USER_FEED_TABLE.'
+  (id, user_id, last_check)
+  VALUES
+  (\''.$page['feed'].'\', '.$user['id'].', NULL)
+;';
+pwg_query($query);
+
+
+$feed_url=PHPWG_ROOT_PATH.'feed.php';
+if (is_a_guest())
+{
+  $feed_image_only_url=$feed_url;
+  $feed_url .= '?feed='.$page['feed'];
+}
+else
+{
+  $feed_url .= '?feed='.$page['feed'];
+  $feed_image_only_url=$feed_url.'&amp;image_only';
+}
+
+// +-----------------------------------------------------------------------+
+// |                        template initialization                        |
+// +-----------------------------------------------------------------------+
+
+$title = l10n('Notification');
+$page['body_id'] = 'theNotificationPage';
+$page['meta_robots']=array('noindex'=>1, 'nofollow'=>1);
+
+
+$template->set_filenames(array('notification'=>'notification.tpl'));
+
+$template->assign(
+  array(
+    'U_FEED' => $feed_url,
+    'U_FEED_IMAGE_ONLY' => $feed_image_only_url,
+    )
+  );
+
+// +-----------------------------------------------------------------------+
+// |                           html code display                           |
+// +-----------------------------------------------------------------------+
+include(PHPWG_ROOT_PATH.'include/page_header.php');
+$template->pparse('notification');
+include(PHPWG_ROOT_PATH.'include/page_tail.php');
+
+?>
Index: /tags/2.0.2/password.php
===================================================================
--- /tags/2.0.2/password.php	(revision 3278)
+++ /tags/2.0.2/password.php	(revision 3278)
@@ -0,0 +1,165 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// +-----------------------------------------------------------------------+
+// |                           initialization                              |
+// +-----------------------------------------------------------------------+
+
+define('PHPWG_ROOT_PATH','./');
+include_once( PHPWG_ROOT_PATH.'include/common.inc.php' );
+include_once(PHPWG_ROOT_PATH.'include/functions_mail.inc.php');
+
+// +-----------------------------------------------------------------------+
+// | Check Access and exit when user status is not ok                      |
+// +-----------------------------------------------------------------------+
+check_status(ACCESS_FREE);
+
+// +-----------------------------------------------------------------------+
+// |                          send a new password                          |
+// +-----------------------------------------------------------------------+
+
+$page['errors'] = array();
+$page['infos'] = array();
+
+if (isset($_POST['submit']))
+{
+  $mailto =
+    '<a href="mailto:'.get_webmaster_mail_address().'">'
+    .l10n('Contact webmaster')
+    .'</a>'
+    ;
+
+  if (isset($_POST['no_mail_address']) and $_POST['no_mail_address'] == 1)
+  {
+    array_push($page['infos'], l10n('Email address is missing'));
+    array_push($page['infos'], $mailto);
+  }
+  else if (isset($_POST['mail_address']) and !empty($_POST['mail_address']))
+  {
+    $mail_address = mysql_real_escape_string($_POST['mail_address']);
+    
+    $query = '
+SELECT '.$conf['user_fields']['id'].' AS id
+     , '.$conf['user_fields']['username'].' AS username
+     , '.$conf['user_fields']['email'].' AS email
+FROM '.USERS_TABLE.' as u
+  INNER JOIN '.USER_INFOS_TABLE.' AS ui
+      ON u.'.$conf['user_fields']['id'].' = ui.user_id
+WHERE '
+  .$conf['user_fields']['email'].' = \''.$mail_address.'\' AND
+  (
+    ui.status = \'normal\' OR
+    (ui.status in (\'admin\', \'webmaster\') AND ui.adviser = \'true\')
+  )
+;';
+    $result = pwg_query($query);
+
+    if (mysql_num_rows($result) > 0)
+    {
+      $error_on_mail = false;
+      $datas = array();
+      
+      while ($row = mysql_fetch_array($result))
+      {
+        $new_password = generate_key(6);
+
+        $infos =
+          l10n('Username').': '.$row['username']
+          ."\n".l10n('Password').': '.$new_password
+          ;
+
+        if (pwg_mail($row['email'],
+              array('subject' => l10n('password updated'), 'content' => $infos)))
+        {
+          $data =
+            array(
+              $conf['user_fields']['id']
+              => $row['id'],
+              
+              $conf['user_fields']['password']
+              => $conf['pass_convert']($new_password)
+              );
+
+          array_push($datas, $data);
+        }
+        else
+        {
+          $error_on_mail = true;
+        }
+      }
+      
+      if ($error_on_mail)
+      {
+        array_push($page['errors'], l10n('Error sending email'));
+        array_push($page['errors'], $mailto);
+      }
+      else
+      {
+        include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+        mass_updates(
+          USERS_TABLE,
+          array(
+            'primary' => array($conf['user_fields']['id']),
+            'update' => array($conf['user_fields']['password'])
+          ),
+          $datas
+          );
+
+        array_push($page['infos'], l10n('New password sent by email'));
+      }
+    }
+    else
+    {
+      array_push($page['errors'], l10n('No user matches this email address'));
+      array_push($page['errors'], l10n('Administrator, webmaster and special user cannot use this method'));
+      array_push($page['errors'], $mailto);
+    }
+  }
+}
+
+// +-----------------------------------------------------------------------+
+// |                        template initialization                        |
+// +-----------------------------------------------------------------------+
+
+$title = l10n('Forgot your password?');
+$page['body_id'] = 'thePasswordPage';
+
+$template->set_filenames(array('password'=>'password.tpl'));
+$template->assign( array(
+    'F_ACTION'=> get_root_url().'password.php'
+    )
+  );
+// +-----------------------------------------------------------------------+
+// |                        infos & errors display                         |
+// +-----------------------------------------------------------------------+
+$template->assign('errors', $page['errors']);
+$template->assign('infos', $page['infos']);
+
+// +-----------------------------------------------------------------------+
+// |                           html code display                           |
+// +-----------------------------------------------------------------------+
+include(PHPWG_ROOT_PATH.'include/page_header.php');
+$template->pparse('password');
+include(PHPWG_ROOT_PATH.'include/page_tail.php');
+
+?>
Index: /tags/2.0.2/picture.php
===================================================================
--- /tags/2.0.2/picture.php	(revision 3278)
+++ /tags/2.0.2/picture.php	(revision 3278)
@@ -0,0 +1,960 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+define('PHPWG_ROOT_PATH','./');
+include_once(PHPWG_ROOT_PATH.'include/common.inc.php');
+include(PHPWG_ROOT_PATH.'include/section_init.inc.php');
+include_once(PHPWG_ROOT_PATH.'include/functions_picture.inc.php');
+
+// Check Access and exit when user status is not ok
+check_status(ACCESS_GUEST);
+
+// access authorization check
+if (isset($page['category']))
+{
+  check_restrictions($page['category']['id']);
+}
+
+$page['rank_of'] = array_flip($page['items']);
+
+// if this image_id doesn't correspond to this category, an error message is
+// displayed, and execution is stopped
+if ( !isset($page['rank_of'][$page['image_id']]) )
+{
+  $query = '
+SELECT id, file, level
+  FROM '.IMAGES_TABLE.'
+  WHERE ';
+  if ($page['image_id']>0)
+  {
+    $query .= 'id = '.$page['image_id'];
+  }
+  else
+  {// url given by file name
+    assert( !empty($page['image_file']) );
+    $query .= 'file LIKE "' .
+      str_replace(array('_','%'), array('/_','/%'), $page['image_file'] ).
+      '.%" ESCAPE "/" LIMIT 1';
+  }
+  if ( ! ( $row = mysql_fetch_array(pwg_query($query)) ) )
+  {// element does not exist
+    page_not_found( 'The requested image does not exist',
+      duplicate_index_url()
+      );
+  }
+  if ($row['level']>$user['level'])
+  {
+    access_denied();
+  }
+  list($page['image_id'], $page['image_file']) =  $row;
+  if ( !isset($page['rank_of'][$page['image_id']]) )
+  {// the image can still be non accessible (filter/cat perm) and/or not in the set
+    global $filter;
+    if ( !empty($filter['visible_images']) and
+      !in_array($page['image_id'], explode(',',$filter['visible_images']) ) )
+    {
+      page_not_found( 'The requested image is filtered',
+          duplicate_index_url()
+        );
+    }
+    if ('categories'==$page['section'] and !isset($page['category']) )
+    {// flat view - all items
+      access_denied();
+    }
+    else
+    {// try to see if we can access it differently
+      $query = '
+SELECT id
+  FROM '.IMAGES_TABLE.' INNER JOIN '.IMAGE_CATEGORY_TABLE.' ON id=image_id
+  WHERE id='.$page['image_id']
+        . get_sql_condition_FandF(
+            array('forbidden_categories' => 'category_id'),
+            " AND"
+          ).'
+  LIMIT 1';
+      if ( mysql_num_rows( pwg_query($query) ) == 0 )
+      {
+        access_denied();
+      }
+      else
+      {
+        if ('best_rated'==$page['section'])
+        {
+          $page['rank_of'][$page['image_id']] = count($page['items']);
+          array_push($page['items'], $page['image_id'] );
+        }
+        else
+        {
+          $url = make_picture_url(
+              array(
+                'image_id' => $page['image_id'],
+                'image_file' => $page['image_file'],
+                'section' => 'categories',
+                'flat' => true,
+              )
+            );
+          set_status_header( 'recent_pics'==$page['section'] ? 301 : 302);
+          redirect_http( $url );
+        }
+      }
+    }
+  }
+}
+
+// There is cookie, so we must handle it at the beginning
+if ( isset($_GET['metadata']) )
+{
+  if ( pwg_get_session_var('show_metadata') == null )
+	{
+		pwg_set_session_var('show_metadata', 1 );
+	} else {
+  	pwg_unset_session_var('show_metadata');
+	}
+}
+
+// add default event handler for rendering element content
+add_event_handler(
+  'render_element_content',
+  'default_picture_content',
+  EVENT_HANDLER_PRIORITY_NEUTRAL,
+  2
+  );
+// add default event handler for rendering element description
+add_event_handler('render_element_description', 'nl2br');
+
+trigger_action('loc_begin_picture');
+
+// this is the default handler that generates the display for the element
+function default_picture_content($content, $element_info)
+{
+  if ( !empty($content) )
+  {// someone hooked us - so we skip;
+    return $content;
+  }
+  if (!isset($element_info['image_url']))
+  { // nothing to do
+    return $content;
+  }
+
+  global $user, $page, $template;
+
+  $template->set_filenames(
+    array('default_content'=>'picture_content.tpl')
+    );
+
+  if ( !$page['slideshow'] and isset($element_info['high_url']) )
+  {
+    $uuid = uniqid(rand());
+    $template->assign(
+      'high',
+      array(
+        'U_HIGH' => $element_info['high_url'],
+        'UUID'   => $uuid,
+        )
+      );
+  }
+  $template->assign( array(
+      'SRC_IMG' => $element_info['image_url'],
+      'ALT_IMG' => $element_info['file'],
+      'WIDTH_IMG' => @$element_info['scaled_width'],
+      'HEIGHT_IMG' => @$element_info['scaled_height'],
+      )
+    );
+  return $template->parse( 'default_content', true);
+}
+
+// +-----------------------------------------------------------------------+
+// |                            initialization                             |
+// +-----------------------------------------------------------------------+
+
+// caching first_rank, last_rank, current_rank in the displayed
+// section. This should also help in readability.
+$page['first_rank']   = 0;
+$page['last_rank']    = count($page['items']) - 1;
+$page['current_rank'] = $page['rank_of'][ $page['image_id'] ];
+
+// caching current item : readability purpose
+$page['current_item'] = $page['image_id'];
+
+if ($page['current_rank'] != $page['first_rank'])
+{
+  // caching first & previous item : readability purpose
+  $page['previous_item'] = $page['items'][ $page['current_rank'] - 1 ];
+  $page['first_item'] = $page['items'][ $page['first_rank'] ];
+}
+
+if ($page['current_rank'] != $page['last_rank'])
+{
+  // caching next & last item : readability purpose
+  $page['next_item'] = $page['items'][ $page['current_rank'] + 1 ];
+  $page['last_item'] = $page['items'][ $page['last_rank'] ];
+}
+
+$url_up = duplicate_index_url(
+  array(
+    'start' =>
+      floor($page['current_rank'] / $user['nb_image_page'])
+      * $user['nb_image_page']
+    ),
+  array(
+    'start',
+    )
+  );
+
+$url_self = duplicate_picture_url();
+
+// +-----------------------------------------------------------------------+
+// |                                actions                                |
+// +-----------------------------------------------------------------------+
+
+/**
+ * Actions are favorite adding, user comment deletion, setting the picture
+ * as representative of the current category...
+ *
+ * Actions finish by a redirection
+ */
+
+if (isset($_GET['action']))
+{
+  switch ($_GET['action'])
+  {
+    case 'add_to_favorites' :
+    {
+      $query = '
+INSERT INTO '.FAVORITES_TABLE.'
+  (image_id,user_id)
+  VALUES
+  ('.$page['image_id'].','.$user['id'].')
+;';
+      pwg_query($query);
+
+      redirect($url_self);
+
+      break;
+    }
+    case 'remove_from_favorites' :
+    {
+      $query = '
+DELETE FROM '.FAVORITES_TABLE.'
+  WHERE user_id = '.$user['id'].'
+    AND image_id = '.$page['image_id'].'
+;';
+      pwg_query($query);
+
+      if ('favorites' == $page['section'])
+      {
+        redirect($url_up);
+      }
+      else
+      {
+        redirect($url_self);
+      }
+
+      break;
+    }
+    case 'set_as_representative' :
+    {
+      if (is_admin() and !is_adviser() and isset($page['category']))
+      {
+        $query = '
+UPDATE '.CATEGORIES_TABLE.'
+  SET representative_picture_id = '.$page['image_id'].'
+  WHERE id = '.$page['category']['id'].'
+;';
+        pwg_query($query);
+      }
+
+      redirect($url_self);
+
+      break;
+    }
+    case 'toggle_metadata' :
+    {
+      break;
+    }
+    case 'add_to_caddie' :
+    {
+      fill_caddie(array($page['image_id']));
+      redirect($url_self);
+      break;
+    }
+    case 'rate' :
+    {
+      include_once(PHPWG_ROOT_PATH.'include/functions_rate.inc.php');
+      rate_picture(
+        $page['image_id'],
+        isset($_POST['rate']) ? $_POST['rate'] : $_GET['rate']
+        );
+      redirect($url_self);
+    }
+    case 'delete_comment' :
+    {
+      if (isset($_GET['comment_to_delete'])
+          and is_numeric($_GET['comment_to_delete'])
+          and is_admin() and !is_adviser() )
+      {
+        $query = '
+DELETE FROM '.COMMENTS_TABLE.'
+  WHERE id = '.$_GET['comment_to_delete'].'
+;';
+        pwg_query( $query );
+      }
+
+      redirect($url_self);
+    }
+  }
+}
+
+// incrementation of the number of hits, we do this only if no action
+if (trigger_event('allow_increment_element_hit_count', !isset($_POST['content']) ) )
+{
+  $query = '
+UPDATE
+  '.IMAGES_TABLE.'
+  SET hit = hit+1
+  WHERE id = '.$page['image_id'].'
+;';
+  pwg_query($query);
+}
+//---------------------------------------------------------- related categories
+$query = '
+SELECT category_id,uppercats,commentable,global_rank
+  FROM '.IMAGE_CATEGORY_TABLE.'
+    INNER JOIN '.CATEGORIES_TABLE.' ON category_id = id
+  WHERE image_id = '.$page['image_id'].'
+'.get_sql_condition_FandF
+  (
+    array
+      (
+        'forbidden_categories' => 'category_id',
+        'visible_categories' => 'category_id'
+      ),
+    'AND'
+  ).'
+;';
+$result = pwg_query($query);
+$related_categories = array();
+while ($row = mysql_fetch_array($result))
+{
+  array_push($related_categories, $row);
+}
+usort($related_categories, 'global_rank_compare');
+//-------------------------first, prev, current, next & last picture management
+$picture = array();
+
+$ids = array($page['image_id']);
+if (isset($page['previous_item']))
+{
+  array_push($ids, $page['previous_item']);
+  array_push($ids, $page['first_item']);
+}
+if (isset($page['next_item']))
+{
+  array_push($ids, $page['next_item']);
+  array_push($ids, $page['last_item']);
+}
+
+$query = '
+SELECT *
+  FROM '.IMAGES_TABLE.'
+  WHERE id IN ('.implode(',', $ids).')
+;';
+
+$result = pwg_query($query);
+
+while ($row = mysql_fetch_assoc($result))
+{
+  if (isset($page['previous_item']) and $row['id'] == $page['previous_item'])
+  {
+    $i = 'previous';
+  }
+  else if (isset($page['next_item']) and $row['id'] == $page['next_item'])
+  {
+    $i = 'next';
+  }
+  else if (isset($page['first_item']) and $row['id'] == $page['first_item'])
+  {
+    $i = 'first';
+  }
+  else if (isset($page['last_item']) and $row['id'] == $page['last_item'])
+  {
+    $i = 'last';
+  }
+  else
+  {
+    $i = 'current';
+  }
+
+  $picture[$i] = $row;
+
+  $picture[$i]['is_picture'] = false;
+  if (in_array(get_extension($row['file']), $conf['picture_ext']))
+  {
+    $picture[$i]['is_picture'] = true;
+  }
+
+  // ------ build element_path and element_url
+  $picture[$i]['element_path'] = get_element_path($picture[$i]);
+  $picture[$i]['element_url'] = get_element_url($picture[$i]);
+
+  // ------ build image_path and image_url
+  if ($i=='current' or $i=='next')
+  {
+    $picture[$i]['image_path'] = get_image_path( $picture[$i] );
+    $picture[$i]['image_url'] = get_image_url( $picture[$i] );
+  }
+
+  if ($i=='current')
+  {
+    if ( $picture[$i]['is_picture'] )
+    {
+      if ( $user['enabled_high']=='true' )
+      {
+        $hi_url=get_high_url($picture[$i]);
+        if ( !empty($hi_url) )
+        {
+          $picture[$i]['high_url'] = $hi_url;
+          $picture[$i]['download_url'] = get_download_url('h',$picture[$i]);
+        }
+      }
+    }
+    else
+    { // not a pic - need download link
+      $picture[$i]['download_url'] = get_download_url('e',$picture[$i]);
+    }
+  }
+
+  $picture[$i]['thumbnail'] = get_thumbnail_url($row);
+
+  if ( !empty( $row['name'] ) )
+  {
+    $picture[$i]['name'] = $row['name'];
+  }
+  else
+  {
+    $file_wo_ext = get_filename_wo_extension($row['file']);
+    $picture[$i]['name'] = str_replace('_', ' ', $file_wo_ext);
+  }
+
+  $picture[$i]['url'] = duplicate_picture_url(
+    array(
+      'image_id' => $row['id'],
+      'image_file' => $row['file'],
+      ),
+    array(
+      'start',
+      )
+    );
+
+  if ('previous'==$i and $page['previous_item']==$page['first_item'])
+  {
+    $picture['first'] = $picture[$i];
+  }
+  if ('next'==$i and $page['next_item']==$page['last_item'])
+  {
+    $picture['last'] = $picture[$i];
+  }
+}
+
+// calculation of width and height for the current picture
+if (empty($picture['current']['width']))
+{
+  $taille_image = @getimagesize($picture['current']['image_path']);
+  if ($taille_image!==false)
+  {
+    $picture['current']['width'] = $taille_image[0];
+    $picture['current']['height']= $taille_image[1];
+  }
+}
+
+if (!empty($picture['current']['width']))
+{
+  list(
+    $picture['current']['scaled_width'],
+    $picture['current']['scaled_height']
+    ) = get_picture_size(
+      $picture['current']['width'],
+      $picture['current']['height'],
+      @$user['maxwidth'],
+      @$user['maxheight']
+    );
+}
+
+$url_admin =
+  get_root_url().'admin.php?page=picture_modify'
+  .'&amp;cat_id='.(isset($page['category']) ? $page['category']['id'] : '')
+  .'&amp;image_id='.$page['image_id']
+;
+
+$slideshow_params = array();
+$slideshow_url_params = array();
+
+if (isset($_GET['slideshow']))
+{
+  $page['slideshow'] = true;
+  $page['meta_robots'] = array('noindex'=>1, 'nofollow'=>1);
+
+  $slideshow_params = decode_slideshow_params($_GET['slideshow']);
+  $slideshow_url_params['slideshow'] = encode_slideshow_params($slideshow_params);
+
+  if ($slideshow_params['play'])
+  {
+    $id_pict_redirect = '';
+    if (isset($page['next_item']))
+    {
+      $id_pict_redirect = 'next';
+    }
+    else
+    {
+      if ($slideshow_params['repeat'] and isset($page['first_item']))
+      {
+        $id_pict_redirect = 'first';
+      }
+    }
+
+    if (!empty($id_pict_redirect))
+    {
+      // $refresh, $url_link and $title are required for creating
+      // an automated refresh page in header.tpl
+      $refresh = $slideshow_params['period'];
+      $url_link = add_url_params(
+          $picture[$id_pict_redirect]['url'],
+          $slideshow_url_params
+        );
+    }
+  }
+}
+else
+{
+  $page['slideshow'] = false;
+}
+if ($page['slideshow'] and $conf['light_slideshow'])
+{
+  $template->set_filenames( array('slideshow' => 'slideshow.tpl'));
+}
+else
+{
+  $template->set_filenames( array('picture' => 'picture.tpl'));
+}
+
+$title =  $picture['current']['name'];
+$title_nb = ($page['current_rank'] + 1).'/'.count($page['items']);
+
+// metadata
+$url_metadata = duplicate_picture_url();
+$url_metadata = add_url_params( $url_metadata, array('metadata'=>null) );
+
+
+// do we have a plugin that can show metadata for something else than images?
+$metadata_showable = trigger_event(
+  'get_element_metadata_available',
+  (
+    ($conf['show_exif'] or $conf['show_iptc'])
+    and isset($picture['current']['image_path'])
+    ),
+  $picture['current']['path']
+  );
+
+if ( $metadata_showable and pwg_get_session_var('show_metadata') )
+{
+  $page['meta_robots']=array('noindex'=>1, 'nofollow'=>1);
+}
+
+
+
+$page['body_id'] = 'thePicturePage';
+
+// allow plugins to change what we computed before passing data to template
+$picture = trigger_event('picture_pictures_data', $picture);
+
+
+if (isset($picture['next']['image_url'])
+    and $picture['next']['is_picture'] )
+{
+  $template->assign('U_PREFETCH', $picture['next']['image_url'] );
+}
+
+//------------------------------------------------------- navigation management
+foreach (array('first','previous','next','last', 'current') as $which_image)
+{
+  if (isset($picture[$which_image]))
+  {
+    $template->assign(
+      $which_image,
+      array_merge(
+        $picture[$which_image],
+        array(
+          'TITLE' => $picture[$which_image]['name'],
+          'THUMB_SRC' => $picture[$which_image]['thumbnail'],
+          // Params slideshow was transmit to navigation buttons
+          'U_IMG' =>
+            add_url_params(
+              $picture[$which_image]['url'], $slideshow_url_params),
+          'U_DOWNLOAD' => @$picture['current']['download_url'],
+          )
+        )
+      );
+  }
+}
+
+
+if ($page['slideshow'])
+{
+  $tpl_slideshow = array();
+
+  //slideshow end
+  $template->assign(
+    array(
+      'U_SLIDESHOW_STOP' => $picture['current']['url'],
+      )
+    );
+
+  foreach (array('repeat', 'play') as $p)
+  {
+    $var_name =
+      'U_'
+      .($slideshow_params[$p] ? 'STOP_' : 'START_')
+      .strtoupper($p);
+
+    $tpl_slideshow[$var_name] =
+          add_url_params(
+            $picture['current']['url'],
+            array('slideshow' =>
+              encode_slideshow_params(
+                array_merge($slideshow_params,
+                  array($p => ! $slideshow_params[$p]))
+                )
+              )
+          );
+  }
+
+  foreach (array('dec', 'inc') as $op)
+  {
+    $new_period = $slideshow_params['period'] + ((($op == 'dec') ? -1 : 1) * $conf['slideshow_period_step']);
+    $new_slideshow_params =
+      correct_slideshow_params(
+        array_merge($slideshow_params,
+                  array('period' => $new_period)));
+
+    if ($new_slideshow_params['period'] === $new_period)
+    {
+      $var_name = 'U_'.strtoupper($op).'_PERIOD';
+      $tpl_slideshow[$var_name] =
+            add_url_params(
+              $picture['current']['url'],
+              array('slideshow' => encode_slideshow_params($new_slideshow_params)
+                  )
+          );
+    }
+  }
+  $template->assign('slideshow', $tpl_slideshow );
+}
+else
+{
+  $template->assign(
+    array(
+      'U_SLIDESHOW_START' =>
+        add_url_params(
+          $picture['current']['url'],
+          array( 'slideshow'=>''))
+      )
+    );
+}
+
+$template->assign(
+  array(
+    'SECTION_TITLE' => $page['title'],
+    'PHOTO' => $title_nb,
+    'SHOW_PICTURE_NAME_ON_TITLE' => $conf['show_picture_name_on_title'],
+    'IS_HOME' => ('categories'==$page['section'] and !isset($page['category']) ),
+
+    'LEVEL_SEPARATOR' => $conf['level_separator'],
+
+    'U_HOME' => make_index_url(),
+    'U_UP' => $url_up,
+    'U_METADATA' => $url_metadata,
+    )
+  );
+
+
+//------------------------------------------------------- upper menu management
+
+// admin links
+if (is_admin())
+{
+  if (isset($page['category']))
+  {
+    $template->assign(
+      array(
+        'U_SET_AS_REPRESENTATIVE' => add_url_params($url_self,
+                    array('action'=>'set_as_representative')
+                 )
+        )
+      );
+  }
+
+  $template->assign(
+    array(
+      'U_CADDIE' => add_url_params($url_self,
+                  array('action'=>'add_to_caddie')
+               ),
+      'U_ADMIN' => $url_admin,
+      )
+    );
+}
+
+// favorite manipulation
+if (!is_a_guest())
+{
+  // verify if the picture is already in the favorite of the user
+  $query = '
+SELECT COUNT(*) AS nb_fav
+  FROM '.FAVORITES_TABLE.'
+  WHERE image_id = '.$page['image_id'].'
+    AND user_id = '.$user['id'].'
+;';
+  $result = pwg_query($query);
+  $row = mysql_fetch_array($result);
+
+  if ($row['nb_fav'] == 0)
+  {
+    $template->assign(
+      'favorite',
+      array(
+        'FAVORITE_IMG'  =>
+          get_root_url().get_themeconf('icon_dir').'/favorite.png',
+        'FAVORITE_HINT' => l10n('add_favorites_hint'),
+        'U_FAVORITE'    => add_url_params(
+          $url_self,
+          array('action'=>'add_to_favorites')
+          ),
+        )
+      );
+  }
+  else
+  {
+    $template->assign(
+      'favorite',
+      array(
+        'FAVORITE_IMG'  =>
+          get_root_url().get_themeconf('icon_dir').'/del_favorite.png',
+        'FAVORITE_HINT' => l10n('del_favorites_hint'),
+        'U_FAVORITE'    => add_url_params(
+          $url_self,
+          array('action'=>'remove_from_favorites')
+          ),
+        )
+      );
+  }
+}
+
+//--------------------------------------------------------- picture information
+// legend
+if (isset($picture['current']['comment'])
+    and !empty($picture['current']['comment']))
+{
+  $template->assign(
+      'COMMENT_IMG',
+        trigger_event('render_element_description',
+          $picture['current']['comment'])
+      );
+}
+
+$infos = array();
+
+// author
+if (!empty($picture['current']['author']))
+{
+  $infos['INFO_AUTHOR'] =
+// FIXME because of search engine partial rewrite, giving the author
+// name threw GET is not supported anymore. This feature should come
+// back later, with a better design
+//     '<a href="'.
+//       PHPWG_ROOT_PATH.'category.php?cat=search'.
+//       '&amp;search=author:'.$picture['current']['author']
+//       .'">'.$picture['current']['author'].'</a>';
+    $picture['current']['author'];
+}
+
+// creation date
+if (!empty($picture['current']['date_creation']))
+{
+  $val = format_date($picture['current']['date_creation']);
+  $url = make_index_url(
+    array(
+      'chronology_field'=>'created',
+      'chronology_style'=>'monthly',
+      'chronology_view'=>'list',
+      'chronology_date' => explode('-', $picture['current']['date_creation'])
+      )
+    );
+  $infos['INFO_CREATION_DATE'] =
+    '<a href="'.$url.'" rel="nofollow">'.$val.'</a>';
+}
+
+// date of availability
+$val = format_date($picture['current']['date_available']);
+$url = make_index_url(
+  array(
+    'chronology_field'=>'posted',
+    'chronology_style'=>'monthly',
+    'chronology_view'=>'list',
+    'chronology_date' => explode(
+      '-',
+      substr($picture['current']['date_available'], 0, 10)
+      )
+    )
+  );
+$infos['INFO_POSTED_DATE'] = '<a href="'.$url.'" rel="nofollow">'.$val.'</a>';
+
+// size in pixels
+if ($picture['current']['is_picture'] and isset($picture['current']['width']) )
+{
+  if ($picture['current']['scaled_width'] !== $picture['current']['width'] )
+  {
+    $infos['INFO_DIMENSIONS'] =
+      '<a href="'.$picture['current']['image_url'].'" title="'.
+      l10n('Original dimensions').'">'.
+      $picture['current']['width'].'*'.$picture['current']['height'].'</a>';
+  }
+  else
+  {
+    $infos['INFO_DIMENSIONS'] =
+      $picture['current']['width'].'*'.$picture['current']['height'];
+  }
+}
+
+// filesize
+if (!empty($picture['current']['filesize']))
+{
+  $infos['INFO_FILESIZE'] =
+    sprintf(l10n('%d Kb'), $picture['current']['filesize']);
+}
+
+// number of visits
+$infos['INFO_VISITS'] = $picture['current']['hit'];
+
+// file
+$infos['INFO_FILE'] = $picture['current']['file'];
+
+$template->assign($infos);
+
+// related tags
+$tags = get_common_tags( array($page['image_id']), -1);
+if ( count($tags) )
+{
+  foreach ($tags as $tag)
+  {
+    $template->append(
+        'related_tags',
+        array_merge( $tag,
+          array(
+            'URL' => make_index_url(
+                      array(
+                        'tags' => array($tag)
+                        )
+                      ),
+            'U_TAG_IMAGE' => duplicate_picture_url(
+                      array(
+                        'section' => 'tags',
+                        'tags' => array($tag)
+                        )
+                    )
+          )
+        )
+      );
+  }
+}
+
+// related categories
+if ( count($related_categories)==1 and
+    isset($page['category']) and
+    $related_categories[0]['category_id']==$page['category']['id'] )
+{ // no need to go to db, we have all the info
+  $template->append(
+      'related_categories',
+      get_cat_display_name( $page['category']['upper_names'] )
+    );
+}
+else
+{ // use only 1 sql query to get names for all related categories
+  $ids = array();
+  foreach ($related_categories as $category)
+  {// add all uppercats to $ids
+    $ids = array_merge($ids, explode(',', $category['uppercats']) );
+  }
+  $ids = array_unique($ids);
+  $query = '
+SELECT id, name, permalink
+  FROM '.CATEGORIES_TABLE.'
+  WHERE id IN ('.implode(',',$ids).')';
+  $cat_map = hash_from_query($query, 'id');
+  foreach ($related_categories as $category)
+  {
+    $cats = array();
+    foreach ( explode(',', $category['uppercats']) as $id )
+    {
+      $cats[] = $cat_map[$id];
+    }
+    $template->append('related_categories', get_cat_display_name($cats) );
+  }
+}
+
+// maybe someone wants a special display (call it before page_header so that
+// they can add stylesheets)
+$element_content = trigger_event(
+  'render_element_content',
+  '',
+  $picture['current']
+  );
+$template->assign( 'ELEMENT_CONTENT', $element_content );
+
+if (is_admin())
+{
+  $template->assign('available_permission_levels', $conf['available_permission_levels']);
+}
+// +-----------------------------------------------------------------------+
+// |                               sub pages                               |
+// +-----------------------------------------------------------------------+
+
+include(PHPWG_ROOT_PATH.'include/picture_rate.inc.php');
+include(PHPWG_ROOT_PATH.'include/picture_comment.inc.php');
+if ($metadata_showable and pwg_get_session_var('show_metadata') <> null )
+{
+  include(PHPWG_ROOT_PATH.'include/picture_metadata.inc.php');
+}
+
+include(PHPWG_ROOT_PATH.'include/page_header.php');
+trigger_action('loc_end_picture');
+if ($page['slideshow'] and $conf['light_slideshow'])
+{
+  $template->pparse('slideshow');
+}
+else
+{
+  $template->pparse('picture');
+}
+//------------------------------------------------------------ log informations
+pwg_log($picture['current']['id'], 'picture');
+include(PHPWG_ROOT_PATH.'include/page_tail.php');
+?>
Index: /tags/2.0.2/plugins/LocalFilesEditor/admin.php
===================================================================
--- /tags/2.0.2/plugins/LocalFilesEditor/admin.php	(revision 3278)
+++ /tags/2.0.2/plugins/LocalFilesEditor/admin.php	(revision 3278)
@@ -0,0 +1,400 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH')) die('Hacking attempt!');
+include_once(PHPWG_ROOT_PATH.'admin/include/tabsheet.class.php');
+include_once(LOCALEDIT_PATH.'functions.inc.php');
+load_language('plugin.lang', LOCALEDIT_PATH);
+$my_base_url = get_admin_plugin_menu_link(__FILE__);
+
+// +-----------------------------------------------------------------------+
+// |                            Tabssheet
+// +-----------------------------------------------------------------------+
+if (!isset($_GET['tab']))
+    $page['tab'] = 'localconf';
+else
+    $page['tab'] = $_GET['tab'];
+
+$tabsheet = new tabsheet();
+$tabsheet->add('localconf',
+               l10n('locfiledit_onglet_localconf'),
+               $my_base_url.'&amp;tab=localconf');
+$tabsheet->add('css',
+               l10n('locfiledit_onglet_css'),
+               $my_base_url.'&amp;tab=css');
+$tabsheet->add('tpl',
+               l10n('locfiledit_onglet_tpl'),
+               $my_base_url.'&amp;tab=tpl');
+$tabsheet->add('lang',
+               l10n('locfiledit_onglet_lang'),
+               $my_base_url.'&amp;tab=lang');
+$tabsheet->add('plug',
+               l10n('locfiledit_onglet_plug'),
+               $my_base_url.'&amp;tab=plug');
+$tabsheet->select($page['tab']);
+$tabsheet->assign();
+
+
+// +-----------------------------------------------------------------------+
+// |                            Variables init
+// +-----------------------------------------------------------------------+
+$edited_file = isset($_POST['edited_file']) ? $_POST['edited_file'] : '';
+$content_file = '';
+$new_file['localconf'] = "<?php\n\n/* ".l10n('locfiledit_newfile')." */\n\n\n\n\n?>";
+$new_file['css'] = "/* " . l10n('locfiledit_newfile') . " */\n\n";
+$new_file['tpl'] = "{* " . l10n('locfiledit_newfile') . " *}\n\n";
+$new_file['lang'] = $new_file['localconf'];
+$new_file['plug'] = "<?php\n/*
+Plugin Name: " . l10n('locfiledit_onglet_plug') . "
+Version: 1.0
+Description: " . l10n('locfiledit_onglet_plug') . "
+Plugin URI: http://piwigo.org
+Author:
+Author URI:
+*/\n\n\n\n\n?>";
+$newfile_page = isset($_GET['newfile']) ? true : false;
+
+// Editarea options
+$editarea_options = array(
+  'language' => substr($user['language'], 0, 2),
+  'start_highlight' => true,
+  'allow_toggle' => false,
+  'toolbar' => 'search,fullscreen, |,select_font, |, undo, redo, change_smooth_selection, highlight, reset_highlight, |, help');
+
+// Edit selected file for CSS, template and language
+if ((isset($_POST['edit'])) and !is_numeric($_POST['file_to_edit']))
+{
+  $edited_file = $_POST['file_to_edit'];
+  $content_file = file_exists($edited_file) ? 
+    file_get_contents($edited_file) : $new_file[$page['tab']];
+}
+
+// Edit new tpl file
+if (isset($_POST['create_tpl']))
+{
+  $filename = $_POST['tpl_name'];
+  if (empty($filename))
+  {
+    array_push($page['errors'], l10n('locfiledit_empty_filename'));
+  }
+  if (get_extension($filename) != 'tpl')
+  {
+    $filename .= '.tpl';
+  }
+  if (!preg_match('/^[a-zA-Z0-9-_.]+$/', $filename))
+  {
+    array_push($page['errors'], l10n('locfiledit_filename_error'));
+  }
+  if (is_numeric($_POST['tpl_model']) and $_POST['tpl_model'] != '0')
+  {
+    array_push($page['errors'], l10n('locfiledit_model_error'));
+  }
+  if (file_exists($_POST['tpl_parent'] . '/' . $filename))
+  {
+    array_push($page['errors'], l10n('locfiledit_file_already_exists'));
+  }
+  if (!empty($page['errors']))
+  {
+    $newfile_page = true;
+  }
+  else
+  {
+    $edited_file = $_POST['tpl_parent'] . '/' . $filename;
+    $content_file = ($_POST['tpl_model'] == '0') ? $new_file['tpl'] : file_get_contents($_POST['tpl_model']);
+  }
+}
+
+// +-----------------------------------------------------------------------+
+// |                            Process tabsheet
+// +-----------------------------------------------------------------------+
+switch ($page['tab'])
+{
+  case 'localconf':
+    $edited_file = PHPWG_ROOT_PATH . "include/config_local.inc.php";
+    $content_file = file_exists($edited_file) ?
+      file_get_contents($edited_file) : $new_file['localconf'];
+	
+    $template->assign('show_default' , array(
+        array('SHOW_DEFAULT' => LOCALEDIT_PATH
+                . 'show_default.php?file=include/config_default.inc.php',
+              'FILE' => 'config_default.inc.php')));
+    $editarea_options['syntax'] = 'php';
+    break;
+
+  case 'css':
+    $template_dir = PHPWG_ROOT_PATH . 'template';
+    $selected = 0; 
+    $options[] = l10n('locfiledit_choose_file');
+    $options[] = '----------------------';
+    $value = PHPWG_ROOT_PATH . "template-common/local-layout.css";
+    $options[$value] = 'template-common / local-layout.css';
+    if ($edited_file == $value) $selected = $value;
+	
+    foreach (get_dirs($template_dir) as $pwg_template)
+    {
+      $options[] = '----------------------';
+      $value = $template_dir . '/' . $pwg_template . '/local-layout.css';
+      $options[$value] = $pwg_template . ' / local-layout.css';
+      if ($edited_file == $value) $selected = $value;
+      $options[] = '----------------------';
+      foreach (get_dirs($template_dir.'/'.$pwg_template.'/theme') as $theme)
+      {
+        $value = $template_dir.'/'.$pwg_template.'/theme/'.$theme.'/theme.css';
+        $options[$value] = $pwg_template . ' / ' . $theme . ' / theme.css';
+        if ($edited_file == $value) $selected = $value;
+      }
+    }
+    $template->assign('css_lang_tpl', array(
+        'OPTIONS' => $options,
+        'SELECTED' => $selected));
+    $editarea_options['syntax'] = 'css';
+    break;
+  
+  case 'tpl':
+    // New file form creation
+    if ($newfile_page and !is_adviser())
+    {
+      $filename = isset($_POST['tpl_name']) ? $_POST['tpl_name'] : '';
+      $selected['model'] = isset($_POST['tpl_model']) ? $_POST['tpl_model'] : '0';
+      $selected['parent'] = isset($_POST['tpl_parent']) ? $_POST['tpl_parent'] : PHPWG_ROOT_PATH . 'template-extension';
+
+      // Parent directories list
+      $options['parent'] = array(PHPWG_ROOT_PATH . 'template-extension' => 'template-extension');
+      $options['parent'] = array_merge($options['parent'], get_rec_dirs(PHPWG_ROOT_PATH . 'template-extension'));
+
+      // Model list
+      $eligible_templates = array(
+          'about.tpl',
+          'footer.tpl',
+          'header.tpl',
+          'identification.tpl',
+          'index.tpl',
+          'mainpage_categories.tpl',
+          'menubar.tpl',
+          'menubar_categories.tpl',
+          'menubar_identification.tpl',
+          'menubar_links.tpl',
+          'menubar_menu.tpl',
+          'menubar_specials.tpl',
+          'menubar_tags.tpl',
+          'nbm.tpl',
+          'notification.tpl',
+          'picture.tpl',
+          'picture_content.tpl',
+          'popuphelp.tpl',
+          'profile.tpl',
+          'profile_content.tpl',
+          'redirect.tpl',
+          'register.tpl',
+          'search.tpl',
+          'search_rules.tpl',
+          'slideshow.tpl',
+          'tags.tpl',
+          'thumbnails.tpl',
+          'upload.tpl');
+
+      $options['model'][] = l10n('locfiledit_empty_page');
+      $options['model'][] = '----------------------';
+      foreach (get_extents() as $pwg_template)
+      {
+        $value = PHPWG_ROOT_PATH . 'template-extension/' . $pwg_template;
+        $options['model'][$value] =  'template-extension / ' . str_replace('/', ' / ', $pwg_template);
+      }
+      $template_dir = PHPWG_ROOT_PATH . 'template';
+      foreach (get_dirs($template_dir) as $pwg_template)
+      {
+        if (count($options['model']) > 2)
+        {
+          $options['model'][] = '----------------------';
+        }
+        $dir = $template_dir . '/' . $pwg_template . '/';
+        if (is_dir($dir) and $content = opendir($dir))
+        {
+          while ($node = readdir($content))
+          {
+            if (is_file($dir . $node) and in_array($node, $eligible_templates))
+            {
+              $value = $dir . $node;
+              $options['model'][$value] = $pwg_template . ' / ' . $node;
+            }
+          }
+        }
+      }
+      // Assign variables to template
+      $template->assign('create_tpl', array(
+        'NEW_FILE_NAME' => $filename,
+        'MODEL_OPTIONS' => $options['model'],
+        'MODEL_SELECTED' => $selected['model'],
+        'PARENT_OPTIONS' => $options['parent'],
+        'PARENT_SELECTED' => $selected['parent']));
+      break;
+    }
+    // List existing template extensions
+    $template_dir = PHPWG_ROOT_PATH . 'template-extension';
+    $selected = 0; 
+    $options[] = l10n('locfiledit_choose_file');
+    $options[] = '----------------------';
+    foreach (get_extents() as $pwg_template)
+    {
+      $value = './template-extension/' . $pwg_template;
+      $options[$value] =  str_replace('/', ' / ', $pwg_template);
+      if ($edited_file == $value) $selected = $value;
+    }
+    if ($selected == 0 and !empty($edited_file))
+    {
+      $options[$edited_file] =  str_replace(array('./template-extension/', '/'), array('', ' / '), $edited_file);
+      $selected = $edited_file;
+    }
+    $template->assign('css_lang_tpl', array(
+      'OPTIONS' => $options,
+      'SELECTED' => $selected,
+      'NEW_FILE_URL' => $my_base_url.'&amp;tab=tpl&amp;newfile',
+      'NEW_FILE_CLASS' => empty($edited_file) ? '' : 'top_right'));
+
+    $editarea_options['syntax'] = 'html';
+    break;
+
+  case 'lang':
+    $selected = 0; 
+    $options[] = l10n('locfiledit_choose_file');
+    $options[] = '----------------------';
+    foreach (get_languages() as $language_code => $language_name)
+    {
+      $value = PHPWG_ROOT_PATH.'language/'.$language_code.'/local.lang.php';
+      if ($edited_file == $value)
+      {
+        $selected = $value;
+        $template->assign('show_default', array(
+          array('SHOW_DEFAULT' => LOCALEDIT_PATH
+                  . 'show_default.php?file='
+                  . 'language/'.$language_code.'/common.lang.php',
+                'FILE' => 'common.lang.php'),
+          array('SHOW_DEFAULT' => LOCALEDIT_PATH
+                  . 'show_default.php?file='
+                  . 'language/'.$language_code.'/admin.lang.php',
+                'FILE' => 'admin.lang.php')));
+      }
+      $options[$value] = $language_name;
+    }
+    $template->assign('css_lang_tpl', array(
+        'OPTIONS' => $options,
+        'SELECTED' => $selected));
+    $editarea_options['syntax'] = 'php';
+    break;
+    
+  case 'plug':
+    $edited_file = PHPWG_PLUGINS_PATH . "PersonalPlugin/main.inc.php";
+    $content_file = file_exists($edited_file) ?
+      file_get_contents($edited_file) : $new_file['plug'];
+    $editarea_options['syntax'] = 'php';
+    break;
+}
+
+// +-----------------------------------------------------------------------+
+// |                           Load backup file
+// +-----------------------------------------------------------------------+
+if (isset($_POST['restore']) and !is_adviser())
+{
+  $edited_file = $_POST['edited_file'];
+  $content_file = file_get_contents(get_bak_file($edited_file));
+  array_push($page['infos'],
+    l10n('locfiledit_bak_loaded1'),
+    l10n('locfiledit_bak_loaded2'));
+}
+
+// +-----------------------------------------------------------------------+
+// |                            Save file
+// +-----------------------------------------------------------------------+
+if (isset($_POST['submit']) and !is_adviser())
+{
+  $edited_file = $_POST['edited_file'];
+  $content_file = stripslashes($_POST['text']);
+  if (get_extension($edited_file) == 'php')
+	{
+    $content_file = eval_syntax($content_file);
+  }
+  if ($content_file === false)
+	{
+    array_push($page['errors'], l10n('locfiledit_syntax_error'));
+  }
+	else
+	{
+    if ($page['tab'] == 'plug' and !is_dir(PHPWG_PLUGINS_PATH . 'PersonalPlugin'))
+    {
+      @mkdir(PHPWG_PLUGINS_PATH . "PersonalPlugin");
+    }
+    if (file_exists($edited_file))
+    {
+      @copy($edited_file, get_bak_file($edited_file));
+      array_push($page['infos'], sprintf(l10n('locfiledit_saved_bak'), substr(get_bak_file($edited_file), 2)));
+    }
+    
+    if ($file = @fopen($edited_file , "w"))
+		{
+      @fwrite($file , $content_file);
+      @fclose($file);
+      array_unshift($page['infos'], l10n('locfiledit_save_config'));
+    }
+		else
+    {
+      array_push($page['errors'], l10n('locfiledit_cant_save'));
+    }
+  }
+}
+
+// +-----------------------------------------------------------------------+
+// |                            template initialization
+// +-----------------------------------------------------------------------+
+$template->set_filenames(array(
+    'plugin_admin_content' => dirname(__FILE__) . '/admin.tpl'));
+
+if (!empty($edited_file))
+{
+  if (!empty($page['errors']))
+	{
+    $content_file = stripslashes($_POST['text']);
+  }
+  $template->assign('zone_edit',
+    array('EDITED_FILE' => $edited_file,
+          'CONTENT_FILE' => htmlspecialchars($content_file),
+          'FILE_NAME' => trim($edited_file, './\\')));
+  if (file_exists(get_bak_file($edited_file)))
+  {
+    $template->assign('restore', true);
+  }
+  if (file_exists($edited_file))
+  {
+    $template->assign('restore_infos', true);
+  }
+  
+}
+
+$template->assign(array(
+  'F_ACTION' => PHPWG_ROOT_PATH.'admin.php?page=plugin&amp;section=LocalFilesEditor%2Fadmin.php&amp;tab=' . $page['tab'],
+  'LOCALEDIT_PATH' => LOCALEDIT_PATH,
+  'LOAD_EDITAREA' => isset($conf['LocalFilesEditor']) ? $conf['LocalFilesEditor'] : 'off',
+  'EDITAREA_OPTIONS' => $editarea_options));
+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'plugin_admin_content');
+
+?>
Index: /tags/2.0.2/plugins/LocalFilesEditor/admin.tpl
===================================================================
--- /tags/2.0.2/plugins/LocalFilesEditor/admin.tpl	(revision 3278)
+++ /tags/2.0.2/plugins/LocalFilesEditor/admin.tpl	(revision 3278)
@@ -0,0 +1,103 @@
+{* $Id$ *}
+{html_head}<link rel="stylesheet" type="text/css" href="{$LOCALEDIT_PATH}locfiledit.css">{/html_head}
+{known_script id="jquery" src=$ROOT_URL|@cat:"template-common/lib/jquery.packed.js"}
+{known_script id="editarea" src=$LOCALEDIT_PATH|@cat:"editarea/edit_area_full.js"}
+<script type="text/javascript">
+var editarea = "{$LOAD_EDITAREA}";
+
+function loadEditarea() {ldelim} 
+  editAreaLoader.init({ldelim}
+    id: "text"
+    {foreach from=$EDITAREA_OPTIONS key=option item=value}
+    , {$option}: {$value|editarea_quote}
+    {/foreach}
+  });
+  jQuery("#showedit").hide();
+  jQuery("#hideedit").show();
+  jQuery.post("plugins/LocalFilesEditor/update_config.php", {ldelim} editarea: "on"});
+}
+
+function unloadEditarea() {ldelim} 
+  editAreaLoader.delete_instance("text");
+  jQuery("#hideedit").hide();
+  jQuery("#showedit").show();
+  jQuery.post("plugins/LocalFilesEditor/update_config.php", {ldelim} editarea: "off"});
+}
+</script>
+
+<div class="titrePage">
+  <h2>LocalFiles Editor</h2>
+</div>
+
+<form method="post" class="properties" action="{$F_ACTION}" ENCTYPE="multipart/form-data" name="form">
+
+<div id="LocalFilesEditor">
+
+<input type="hidden" value="{$zone_edit.EDITED_FILE}" name="edited_file"/>
+
+{if isset ($create_tpl)}
+  <table>
+    <tr>
+      <td style="text-align: right;">{'locfiledit_new_filename'|@translate}</td>
+      <td style="text-align: left;"><input type="text" size="55" maxlength="50" value="{$create_tpl.NEW_FILE_NAME}" name="tpl_name"/></td>
+    </tr>
+    <tr>
+      <td style="text-align: right;">{'locfiledit_parent_directory'|@translate}</td>
+      <td style="text-align: left;">{html_options name=tpl_parent options=$create_tpl.PARENT_OPTIONS selected=$create_tpl.PARENT_SELECTED}</td>
+    </tr>
+    <tr>
+      <td style="text-align: right;">{'locfiledit_model'|@translate}</td>
+      <td style="text-align: left;">{html_options name=tpl_model options=$create_tpl.MODEL_OPTIONS selected=$create_tpl.MODEL_SELECTED}</td>
+    </tr>
+  </table>
+<br><br>
+<input class="submit" type="submit" value="{'Submit'|@translate}" name="create_tpl" />
+{/if}
+
+{if isset ($css_lang_tpl)}
+{html_options name=file_to_edit options=$css_lang_tpl.OPTIONS selected=$css_lang_tpl.SELECTED}
+<input class="submit" type="submit" value="{'locfiledit_edit'|@translate}" name="edit" />
+<br><br>
+  {if isset ($css_lang_tpl.NEW_FILE_URL)}
+  <span class="{$css_lang_tpl.NEW_FILE_CLASS}">
+  <a href="{$css_lang_tpl.NEW_FILE_URL}">{'locfiledit_new_tpl'|@translate}</a>
+  </span>
+  {/if}
+{/if}
+
+{foreach from=$show_default item=file name=default_loop}
+<span class="top_right">
+<a href="{$file.SHOW_DEFAULT}" onclick="window.open( this.href, 'local_file', 'location=no,toolbar=no,menubar=no,status=no,resizable=yes,scrollbars=yes,width=800,height=600' ); return false;">{'locfiledit_show_default'|@translate} "{$file.FILE}"</a>
+</span>
+{if !($smarty.foreach.default_loop.last)}<br>{/if}
+{/foreach}
+
+{if isset ($zone_edit)}
+<b>{$zone_edit.FILE_NAME}</b>
+
+<textarea rows="30" cols="90" name="text" id="text">{$zone_edit.CONTENT_FILE}</textarea>
+<div id="editarea_buttons">
+<a href="javascript:loadEditarea();" id="showedit">[{'locfiledit_enable_editarea'|@translate}]</a>
+<a href="javascript:unloadEditarea();" id="hideedit">[{'locfiledit_disable_editarea'|@translate}]</a>
+</div>
+
+<br>
+
+<input class="submit" type="submit" value="{'locfiledit_save_file'|@translate}" name="submit" {$TAG_INPUT_ENABLED}/>
+{if isset ($restore)}
+<input class="submit" type="submit" value="{'locfiledit_restore'|@translate}" name="restore" onclick="return confirm('{'locfiledit_restore_confirm'|@translate|escape:'javascript'}');" {$TAG_INPUT_ENABLED}/>
+{/if}
+
+{if isset ($restore_infos)}
+<br><br>
+{'locfiledit_save_bak'|@translate}
+{/if}
+
+{/if}
+</div>
+</form>
+
+<script type="text/javascript">
+jQuery("#editarea_buttons").show();
+if ((editarea == "on") && (document.getElementById("text") != null)) loadEditarea();
+</script>
Index: /tags/2.0.2/plugins/LocalFilesEditor/editarea/edit_area_full.js
===================================================================
--- /tags/2.0.2/plugins/LocalFilesEditor/editarea/edit_area_full.js	(revision 3278)
+++ /tags/2.0.2/plugins/LocalFilesEditor/editarea/edit_area_full.js	(revision 3278)
@@ -0,0 +1,38 @@
+ function EAL(){this.version="0.7.2.3";date=new Date();this.start_time=date.getTime();this.win="loading";this.error=false;this.baseURL="";this.template="";this.lang=new Object();this.load_syntax=new Object();this.syntax=new Object();this.loadedFiles=new Array();this.waiting_loading=new Object();this.scripts_to_load=new Array();this.sub_scripts_to_load=new Array();this.resize=new Array();this.hidden=new Object();this.default_settings={debug:false ,smooth_selection:true ,font_size:"10" ,font_family:"monospace" ,start_highlight:false ,autocompletion:false ,toolbar:"search,go_to_line,fullscreen,|,undo,redo,|,select_font,|,change_smooth_selection,highlight,reset_highlight,|,help" ,begin_toolbar:"" ,end_toolbar:"" ,is_multi_files:false ,allow_resize:"both" ,show_line_colors:false ,min_width:400 ,min_height:125 ,replace_tab_by_spaces:false ,allow_toggle:true ,language:"en" ,syntax:"" ,syntax_selection_allow:"basic,brainfuck,c,coldfusion,cpp,css,html,js,pas,perl,php,python,ruby,robotstxt,sql,tsql,vb,xml" ,display:"onload" ,max_undo:30 ,browsers:"known" ,plugins:"" ,gecko_spellcheck:false ,fullscreen:false ,is_editable:true ,wrap_text:false ,load_callback:"" ,save_callback:"" ,change_callback:"" ,submit_callback:"" ,EA_init_callback:"" ,EA_delete_callback:"" ,EA_load_callback:"" ,EA_unload_callback:"" ,EA_toggle_on_callback:"" ,EA_toggle_off_callback:"" ,EA_file_switch_on_callback:"" ,EA_file_switch_off_callback:"" ,EA_file_close_callback:"" };this.advanced_buttons=[ ['new_document','newdocument.gif','new_document',false],['search','search.gif','show_search',false],['go_to_line','go_to_line.gif','go_to_line',false],['undo','undo.gif','undo',true],['redo','redo.gif','redo',true],['change_smooth_selection','smooth_selection.gif','change_smooth_selection_mode',true],['reset_highlight','reset_highlight.gif','resync_highlight',true],['highlight','highlight.gif','change_highlight',true],['help','help.gif','show_help',false],['save','save.gif','save',false],['load','load.gif','load',false],['fullscreen','fullscreen.gif','toggle_full_screen',false],['autocompletion','autocompletion.gif','toggle_autocompletion',true] ];ua=navigator.userAgent;this.nav=new Object();this.nav['isMacOS']=(ua.indexOf('Mac OS')!=-1);this.nav['isIE']=(navigator.appName=="Microsoft Internet Explorer");if(this.nav['isIE']){this.nav['isIE']=ua.replace(/^.*?MSIE ([0-9\.]*).*$/,"$1");if(this.nav['isIE']<6)this.has_error();}if(this.nav['isNS']=ua.indexOf('Netscape/')!=-1){this.nav['isNS']=ua.substr(ua.indexOf('Netscape/')+9);if(this.nav['isNS']<8||!this.nav['isIE'])this.has_error();}if(this.nav['isOpera']=(ua.indexOf('Opera')!=-1)){this.nav['isOpera']=ua.replace(/^.*?Opera.*?([0-9\.]+).*$/i,"$1");if(this.nav['isOpera']<9)this.has_error();this.nav['isIE']=false;}this.nav['isGecko']=(ua.indexOf('Gecko')!=-1);if(this.nav['isFirefox'] =(ua.indexOf('Firefox')!=-1))this.nav['isFirefox']=ua.replace(/^.*?Firefox.*?([0-9\.]+).*$/i,"$1");if(this.nav['isIceweasel'] =(ua.indexOf('Iceweasel')!=-1))this.nav['isFirefox']=this.nav['isIceweasel']=ua.replace(/^.*?Iceweasel.*?([0-9\.]+).*$/i,"$1");if(this.nav['GranParadiso'] =(ua.indexOf('GranParadiso')!=-1))this.nav['isFirefox']=this.nav['isGranParadiso']=ua.replace(/^.*?GranParadiso.*?([0-9\.]+).*$/i,"$1");if(this.nav['BonEcho'] =(ua.indexOf('BonEcho')!=-1))this.nav['isFirefox']=this.nav['isBonEcho']=ua.replace(/^.*?BonEcho.*?([0-9\.]+).*$/i,"$1");if(this.nav['isCamino'] =(ua.indexOf('Camino')!=-1))this.nav['isCamino']=ua.replace(/^.*?Camino.*?([0-9\.]+).*$/i,"$1");if(this.nav['isChrome'] =(ua.indexOf('Chrome')!=-1))this.nav['isChrome']=ua.replace(/^.*?Chrome.*?([0-9\.]+).*$/i,"$1");if(this.nav['isSafari'] =(ua.indexOf('Safari')!=-1))this.nav['isSafari']=ua.replace(/^.*?Version\/([0-9]+\.[0-9]+).*$/i,"$1");if(this.nav['isIE']>=6||this.nav['isOpera']>=9||this.nav['isFirefox']||this.nav['isChrome']||this.nav['isCamino']||this.nav['isSafari']>=3)this.nav['isValidBrowser']=true;
+else this.nav['isValidBrowser']=false;this.set_base_url();for(var i=0;i<this.scripts_to_load.length;i++){setTimeout("eAL.load_script('"+this.baseURL+this.scripts_to_load[i]+".js');",1);this.waiting_loading[this.scripts_to_load[i]+".js"]=false;}this.add_event(window,"load",EAL.prototype.window_loaded);};EAL.prototype ={has_error:function(){this.error=true;for(var i in EAL.prototype){EAL.prototype[i]=function(){};}},window_loaded:function(){eAL.win="loaded";if (document.forms){for (var i=0;i<document.forms.length;i++){var form=document.forms[i];form.edit_area_replaced_submit=null;try{form.edit_area_replaced_submit=form.onsubmit;form.onsubmit="";}catch (e){}eAL.add_event(form,"submit",EAL.prototype.submit);eAL.add_event(form,"reset",EAL.prototype.reset);}}eAL.add_event(window,"unload",function(){for(var i in eAs){eAL.delete_instance(i);}});},init_ie_textarea:function(id){var t=document.getElementById(id);try{if(t&&typeof(t.focused)=="undefined"){t.focus();t.focused=true;t.selectionStart=t.selectionEnd=0;get_IE_selection(t);eAL.add_event(t,"focus",IE_textarea_focus);eAL.add_event(t,"blur",IE_textarea_blur);}}catch(ex){}},init:function(settings){if(!settings["id"])this.has_error();if(this.error)return;if(eAs[settings["id"]])eAL.delete_instance(settings["id"]);for(var i in this.default_settings){if(typeof(settings[i])=="undefined")settings[i]=this.default_settings[i];}if(settings["browsers"]=="known"&&this.nav['isValidBrowser']==false){return;}if(settings["begin_toolbar"].length>0)settings["toolbar"]=settings["begin_toolbar"] +","+settings["toolbar"];if(settings["end_toolbar"].length>0)settings["toolbar"]=settings["toolbar"] +","+settings["end_toolbar"];settings["tab_toolbar"]=settings["toolbar"].replace(/ /g,"").split(",");settings["plugins"]=settings["plugins"].replace(/ /g,"").split(",");for(var i=0;i<settings["plugins"].length;i++){if(settings["plugins"][i].length==0)settings["plugins"].splice(i,1);}this.get_template();this.load_script(this.baseURL+"langs/"+settings["language"]+".js");if(settings["syntax"].length>0){settings["syntax"]=settings["syntax"].toLowerCase();this.load_script(this.baseURL+"reg_syntax/"+settings["syntax"]+".js");}eAs[settings["id"]]={"settings":settings};eAs[settings["id"]]["displayed"]=false;eAs[settings["id"]]["hidden"]=false;eAL.start(settings["id"]);},delete_instance:function(id){eAL.execCommand(id,"EA_delete");if(window.frames["frame_"+id]&&window.frames["frame_"+id].editArea){if(eAs[id]["displayed"])eAL.toggle(id,"off");window.frames["frame_"+id].editArea.execCommand("EA_unload");}var span=document.getElementById("EditAreaArroundInfos_"+id);if(span)span.parentNode.removeChild(span);var iframe=document.getElementById("frame_"+id);if(iframe){iframe.parentNode.removeChild(iframe);try{delete window.frames["frame_"+id];}catch (e){}}delete eAs[id];},start:function(id){if(this.win!="loaded"){setTimeout("eAL.start('"+id+"');",50);return;}for(var i in eAL.waiting_loading){if(eAL.waiting_loading[i]!="loaded"&&typeof(eAL.waiting_loading[i])!="function"){setTimeout("eAL.start('"+id+"');",50);return;}}if(!eAL.lang[eAs[id]["settings"]["language"]]||(eAs[id]["settings"]["syntax"].length>0&&!eAL.load_syntax[eAs[id]["settings"]["syntax"]])){setTimeout("eAL.start('"+id+"');",50);return;}if(eAs[id]["settings"]["syntax"].length>0)eAL.init_syntax_regexp();if(!document.getElementById("EditAreaArroundInfos_"+id)&&(eAs[id]["settings"]["debug"]||eAs[id]["settings"]["allow_toggle"])){var span=document.createElement("span");span.id="EditAreaArroundInfos_"+id;var html="";if(eAs[id]["settings"]["allow_toggle"]){checked=(eAs[id]["settings"]["display"]=="onload")?"checked":"";html+="<div id='edit_area_toggle_"+i+"'>";html+="<input id='edit_area_toggle_checkbox_"+id +"' class='toggle_"+id +"' type='checkbox' onclick='eAL.toggle(\""+id +"\");' accesskey='e' "+checked+" />";html+="<label for='edit_area_toggle_checkbox_"+id +"'>{$toggle}</label></div>";}if(eAs[id]["settings"]["debug"])html+="<textarea id='edit_area_debug_"+id +"' style='z-index:20;width:100%;height:120px;overflow:auto;border:solid black 1px;'></textarea><br />";html=eAL.translate(html,eAs[id]["settings"]["language"]);span.innerHTML=html;var father=document.getElementById(id).parentNode;var next=document.getElementById(id).nextSibling;if(next==null)father.appendChild(span);
+else father.insertBefore(span,next);}if(!eAs[id]["initialized"]){this.execCommand(id,"EA_init");if(eAs[id]["settings"]["display"]=="later"){eAs[id]["initialized"]=true;return;}}if(this.nav['isIE']){eAL.init_ie_textarea(id);}var html_toolbar_content="";area=eAs[id];for(var i=0;i<area["settings"]["tab_toolbar"].length;i++){html_toolbar_content+=this.get_control_html(area["settings"]["tab_toolbar"][i],area["settings"]["language"]);}if(!this.iframe_script){this.iframe_script="";for(var i=0;i<this.sub_scripts_to_load.length;i++)this.iframe_script+='<script language="javascript" type="text/javascript" src="'+this.baseURL+this.sub_scripts_to_load[i] +'.js"></script>';}for(var i=0;i<area["settings"]["plugins"].length;i++){if(!eAL.all_plugins_loaded)this.iframe_script+='<script language="javascript" type="text/javascript" src="'+this.baseURL+'plugins/'+area["settings"]["plugins"][i]+'/'+area["settings"]["plugins"][i] +'.js"></script>';this.iframe_script+='<script language="javascript" type="text/javascript" src="'+this.baseURL+'plugins/'+area["settings"]["plugins"][i]+'/langs/'+area["settings"]["language"] +'.js"></script>';}if(!this.iframe_css){this.iframe_css="<link href='"+this.baseURL +"edit_area.css' rel='stylesheet' type='text/css' />";}var template=this.template.replace(/\[__BASEURL__\]/g,this.baseURL);template=template.replace("[__TOOLBAR__]",html_toolbar_content);template=this.translate(template,area["settings"]["language"],"template");template=template.replace("[__CSSRULES__]",this.iframe_css);template=template.replace("[__JSCODE__]",this.iframe_script);template=template.replace("[__EA_VERSION__]",this.version);area.textarea=document.getElementById(area["settings"]["id"]);eAs[area["settings"]["id"]]["textarea"]=area.textarea;if(typeof(window.frames["frame_"+area["settings"]["id"]])!='undefined')delete window.frames["frame_"+area["settings"]["id"]];var father=area.textarea.parentNode;var content=document.createElement("iframe");content.name="frame_"+area["settings"]["id"];content.id="frame_"+area["settings"]["id"];content.style.borderWidth="0px";setAttribute(content,"frameBorder","0");content.style.overflow="hidden";content.style.display="none";var next=area.textarea.nextSibling;if(next==null)father.appendChild(content);
+else father.insertBefore(content,next);var frame=window.frames["frame_"+area["settings"]["id"]];frame.document.open();frame.eAs=eAs;frame.area_id=area["settings"]["id"];frame.document.area_id=area["settings"]["id"];frame.document.write(template);frame.document.close();},toggle:function(id,toggle_to){if(!toggle_to)toggle_to=(eAs[id]["displayed"]==true)?"off":"on";if(eAs[id]["displayed"]==true &&toggle_to=="off"){this.toggle_off(id);}
+else if(eAs[id]["displayed"]==false &&toggle_to=="on"){this.toggle_on(id);}return false;},toggle_off:function(id){if(window.frames["frame_"+id]){var frame=window.frames["frame_"+id];if(frame.editArea.fullscreen['isFull'])frame.editArea.toggle_full_screen(false);eAs[id]["displayed"]=false;eAs[id]["textarea"].wrap="off";setAttribute(eAs[id]["textarea"],"wrap","off");var parNod=eAs[id]["textarea"].parentNode;var nxtSib=eAs[id]["textarea"].nextSibling;parNod.removeChild(eAs[id]["textarea"]);parNod.insertBefore(eAs[id]["textarea"],nxtSib);eAs[id]["textarea"].value=frame.editArea.textarea.value;var selStart=frame.editArea.last_selection["selectionStart"];var selEnd=frame.editArea.last_selection["selectionEnd"];var scrollTop=frame.document.getElementById("result").scrollTop;var scrollLeft=frame.document.getElementById("result").scrollLeft;document.getElementById("frame_"+id).style.display='none';eAs[id]["textarea"].style.display="inline";eAs[id]["textarea"].focus();if(this.nav['isIE']){eAs[id]["textarea"].selectionStart=selStart;eAs[id]["textarea"].selectionEnd=selEnd;eAs[id]["textarea"].focused=true;set_IE_selection(eAs[id]["textarea"]);}
+else{if(this.nav['isOpera']){eAs[id]["textarea"].setSelectionRange(0,0);}try{eAs[id]["textarea"].setSelectionRange(selStart,selEnd);}catch(e){};}eAs[id]["textarea"].scrollTop=scrollTop;eAs[id]["textarea"].scrollLeft=scrollLeft;frame.editArea.execCommand("toggle_off");}},toggle_on:function(id){if(window.frames["frame_"+id]){var frame=window.frames["frame_"+id];area=window.frames["frame_"+id].editArea;area.textarea.value=eAs[id]["textarea"].value;var selStart=0;var selEnd=0;var scrollTop=0;var scrollLeft=0;if(eAs[id]["textarea"].use_last==true){var selStart=eAs[id]["textarea"].last_selectionStart;var selEnd=eAs[id]["textarea"].last_selectionEnd;var scrollTop=eAs[id]["textarea"].last_scrollTop;var scrollLeft=eAs[id]["textarea"].last_scrollLeft;eAs[id]["textarea"].use_last=false;}
+else{try{var selStart=eAs[id]["textarea"].selectionStart;var selEnd=eAs[id]["textarea"].selectionEnd;var scrollTop=eAs[id]["textarea"].scrollTop;var scrollLeft=eAs[id]["textarea"].scrollLeft;}catch(ex){}}this.set_editarea_size_from_textarea(id,document.getElementById("frame_"+id));eAs[id]["textarea"].style.display="none";document.getElementById("frame_"+id).style.display="inline";area.execCommand("focus");eAs[id]["displayed"]=true;area.execCommand("update_size");window.frames["frame_"+id].document.getElementById("result").scrollTop=scrollTop;window.frames["frame_"+id].document.getElementById("result").scrollLeft=scrollLeft;area.area_select(selStart,selEnd-selStart);area.execCommand("toggle_on");}
+else{var elem=document.getElementById(id);elem.last_selectionStart=elem.selectionStart;elem.last_selectionEnd=elem.selectionEnd;elem.last_scrollTop=elem.scrollTop;elem.last_scrollLeft=elem.scrollLeft;elem.use_last=true;eAL.start(id);}},set_editarea_size_from_textarea:function(id,frame){var elem=document.getElementById(id);var width=Math.max(eAs[id]["settings"]["min_width"],elem.offsetWidth)+"px";var height=Math.max(eAs[id]["settings"]["min_height"],elem.offsetHeight)+"px";if(elem.style.width.indexOf("%")!=-1)width=elem.style.width;if(elem.style.height.indexOf("%")!=-1)height=elem.style.height;frame.style.width=width;frame.style.height=height;},set_base_url:function(){if (!this.baseURL){var elements=document.getElementsByTagName('script');for (var i=0;i<elements.length;i++){if (elements[i].src&&elements[i].src.match(/edit_area_[^\\\/]*$/i)){var src=elements[i].src;src=src.substring(0,src.lastIndexOf('/'));this.baseURL=src;this.file_name=elements[i].src.substr(elements[i].src.lastIndexOf("/")+1);break;}}}var documentBasePath=document.location.href;if (documentBasePath.indexOf('?')!=-1)documentBasePath=documentBasePath.substring(0,documentBasePath.indexOf('?'));var documentURL=documentBasePath;documentBasePath=documentBasePath.substring(0,documentBasePath.lastIndexOf('/'));if (this.baseURL.indexOf('://')==-1&&this.baseURL.charAt(0)!='/'){this.baseURL=documentBasePath+"/"+this.baseURL;}this.baseURL+="/";},get_button_html:function(id,img,exec,isFileSpecific,baseURL){if(!baseURL)baseURL=this.baseURL;var cmd='editArea.execCommand(\''+exec+'\')';html='<a id="a_'+id +'" href="javascript:'+cmd+'" onclick="'+cmd+';return false;" onmousedown="return false;" target="_self" fileSpecific="'+(isFileSpecific?'yes':'no')+'">';html+='<img id="'+id+'" src="'+baseURL +'images/'+img+'" title="{$'+id+'}" width="20" height="20" class="editAreaButtonNormal" onmouseover="editArea.switchClass(this,\'editAreaButtonOver\');" onmouseout="editArea.restoreClass(this);" onmousedown="editArea.restoreAndSwitchClass(this,\'editAreaButtonDown\');" /></a>';return html;},get_control_html:function(button_name,lang){for (var i=0;i<this.advanced_buttons.length;i++){var but=this.advanced_buttons[i];if (but[0]==button_name){return this.get_button_html(but[0],but[1],but[2],but[3]);}}switch (button_name){case "*":case "return":return "<br />";case "|":case "separator":return '<img src="'+this.baseURL +'images/spacer.gif" width="1" height="15" class="editAreaSeparatorLine">';case "select_font":html="<select id='area_font_size' onchange='javascript:editArea.execCommand(\"change_font_size\")' fileSpecific='yes'>" +"<option value='-1'>{$font_size}</option>" +"<option value='8'>8 pt</option>" +"<option value='9'>9 pt</option>" +"<option value='10'>10 pt</option>" +"<option value='11'>11 pt</option>" +"<option value='12'>12 pt</option>" +"<option value='14'>14 pt</option>" +"</select>";return html;case "syntax_selection":var html="<select id='syntax_selection' onchange='javascript:editArea.execCommand(\"change_syntax\",this.value)' fileSpecific='yes'>";html+="<option value='-1'>{$syntax_selection}</option>";html+="</select>";return html;}return "<span id='tmp_tool_"+button_name+"'>["+button_name+"]</span>";},get_template:function(){if(this.template==""){var xhr_object=null;if(window.XMLHttpRequest)xhr_object=new XMLHttpRequest();
+else if(window.ActiveXObject)xhr_object=new ActiveXObject("Microsoft.XMLHTTP");
+else{alert("XMLHTTPRequest not supported. EditArea not loaded");return;}xhr_object.open("GET",this.baseURL+"template.html",false);xhr_object.send(null);if(xhr_object.readyState==4)this.template=xhr_object.responseText;
+else this.has_error();}},translate:function(text,lang,mode){if(mode=="word")text=eAL.get_word_translation(text,lang);
+else if(mode="template"){eAL.current_language=lang;text=text.replace(/\{\$([^\}]+)\}/gm,eAL.translate_template);}return text;},translate_template:function(){return eAL.get_word_translation(EAL.prototype.translate_template.arguments[1],eAL.current_language);},get_word_translation:function(val,lang){for(var i in eAL.lang[lang]){if(i==val)return eAL.lang[lang][i];}return "_"+val;},load_script:function(url){if (this.loadedFiles[url])return;try{var script=document.createElement("script");script.type="text/javascript";script.src=url;script.charset="UTF-8";var head=document.getElementsByTagName("head");head[0].appendChild(script);}catch(e){document.write('<sc'+'ript language="javascript" type="text/javascript" src="'+url+'" charset="UTF-8"></sc'+'ript>');}this.loadedFiles[url]=true;},add_event:function(obj,name,handler){if (obj.attachEvent){obj.attachEvent("on"+name,handler);}
+else{obj.addEventListener(name,handler,false);}},remove_event:function(obj,name,handler){if (obj.detachEvent)obj.detachEvent("on"+name,handler);
+else obj.removeEventListener(name,handler,false);},reset:function(e){var formObj=eAL.nav['isIE'] ? window.event.srcElement:e.target;if(formObj.tagName!='FORM')formObj=formObj.form;for(var i in eAs){var is_child=false;for (var x=0;x<formObj.elements.length;x++){if(formObj.elements[x].id==i)is_child=true;}if(window.frames["frame_"+i]&&is_child&&eAs[i]["displayed"]==true){var exec='window.frames["frame_'+i +'"].editArea.textarea.value=document.getElementById("'+i +'").value;';exec+='window.frames["frame_'+i +'"].editArea.execCommand("focus");';exec+='window.frames["frame_'+i +'"].editArea.check_line_selection();';exec+='window.frames["frame_'+i +'"].editArea.execCommand("reset");';window.setTimeout(exec,10);}}return;},submit:function(e){var formObj=eAL.nav['isIE'] ? window.event.srcElement:e.target;if(formObj.tagName!='FORM')formObj=formObj.form;for(var i in eAs){var is_child=false;for (var x=0;x<formObj.elements.length;x++){if(formObj.elements[x].id==i)is_child=true;}if(is_child){if(window.frames["frame_"+i]&&eAs[i]["displayed"]==true)document.getElementById(i).value=window.frames["frame_"+i].editArea.textarea.value;eAL.execCommand(i,"EA_submit");}}if(typeof(formObj.edit_area_replaced_submit)=="function"){res=formObj.edit_area_replaced_submit();if(res==false){if(eAL.nav['isIE'])return false;
+else e.preventDefault();}}return;},getValue:function(id){if(window.frames["frame_"+id]&&eAs[id]["displayed"]==true){return window.frames["frame_"+id].editArea.textarea.value;}
+else if(elem=document.getElementById(id)){return elem.value;}return false;},setValue:function(id,new_val){if(window.frames["frame_"+id]&&eAs[id]["displayed"]==true){window.frames["frame_"+id].editArea.textarea.value=new_val;window.frames["frame_"+id].editArea.execCommand("focus");window.frames["frame_"+id].editArea.check_line_selection(false);window.frames["frame_"+id].editArea.execCommand("onchange");}
+else if(elem=document.getElementById(id)){elem.value=new_val;}},getSelectionRange:function(id){var sel={"start":0,"end":0};if(window.frames["frame_"+id]&&eAs[id]["displayed"]==true){var editArea=window.frames["frame_"+id].editArea;sel["start"]=editArea.textarea.selectionStart;sel["end"]=editArea.textarea.selectionEnd;}
+else if(elem=document.getElementById(id)){sel=getSelectionRange(elem);}return sel;},setSelectionRange:function(id,new_start,new_end){if(window.frames["frame_"+id]&&eAs[id]["displayed"]==true){window.frames["frame_"+id].editArea.area_select(new_start,new_end-new_start);if(!this.nav['isIE']){window.frames["frame_"+id].editArea.check_line_selection(false);window.frames["frame_"+id].editArea.scroll_to_view();}}
+else if(elem=document.getElementById(id)){setSelectionRange(elem,new_start,new_end);}},getSelectedText:function(id){var sel=this.getSelectionRange(id);return this.getValue(id).substring(sel["start"],sel["end"]);},setSelectedText:function(id,new_val){new_val=new_val.replace(/\r/g,"");var sel=this.getSelectionRange(id);var text=this.getValue(id);if(window.frames["frame_"+id]&&eAs[id]["displayed"]==true){var scrollTop=window.frames["frame_"+id].document.getElementById("result").scrollTop;var scrollLeft=window.frames["frame_"+id].document.getElementById("result").scrollLeft;}
+else{var scrollTop=document.getElementById(id).scrollTop;var scrollLeft=document.getElementById(id).scrollLeft;}text=text.substring(0,sel["start"])+new_val +text.substring(sel["end"]);this.setValue(id,text);var new_sel_end=sel["start"]+new_val.length;this.setSelectionRange(id,sel["start"],new_sel_end);if(new_val !=this.getSelectedText(id).replace(/\r/g,"")){this.setSelectionRange(id,sel["start"],new_sel_end+new_val.split("\n").length -1);}if(window.frames["frame_"+id]&&eAs[id]["displayed"]==true){window.frames["frame_"+id].document.getElementById("result").scrollTop=scrollTop;window.frames["frame_"+id].document.getElementById("result").scrollLeft=scrollLeft;window.frames["frame_"+id].editArea.execCommand("onchange");}
+else{document.getElementById(id).scrollTop=scrollTop;document.getElementById(id).scrollLeft=scrollLeft;}},insertTags:function(id,open_tag,close_tag){var old_sel=this.getSelectionRange(id);text=open_tag+this.getSelectedText(id)+close_tag;eAL.setSelectedText(id,text);var new_sel=this.getSelectionRange(id);if(old_sel["end"] > old_sel["start"])this.setSelectionRange(id,new_sel["end"],new_sel["end"]);
+else this.setSelectionRange(id,old_sel["start"]+open_tag.length,old_sel["start"]+open_tag.length);},hide:function(id){if(document.getElementById(id)&&!this.hidden[id]){this.hidden[id]=new Object();this.hidden[id]["selectionRange"]=this.getSelectionRange(id);if(document.getElementById(id).style.display!="none"){this.hidden[id]["scrollTop"]=document.getElementById(id).scrollTop;this.hidden[id]["scrollLeft"]=document.getElementById(id).scrollLeft;}if(window.frames["frame_"+id]){this.hidden[id]["toggle"]=eAs[id]["displayed"];if(window.frames["frame_"+id]&&eAs[id]["displayed"]==true){var scrollTop=window.frames["frame_"+id].document.getElementById("result").scrollTop;var scrollLeft=window.frames["frame_"+id].document.getElementById("result").scrollLeft;}
+else{var scrollTop=document.getElementById(id).scrollTop;var scrollLeft=document.getElementById(id).scrollLeft;}this.hidden[id]["scrollTop"]=scrollTop;this.hidden[id]["scrollLeft"]=scrollLeft;if(eAs[id]["displayed"]==true)eAL.toggle_off(id);}var span=document.getElementById("EditAreaArroundInfos_"+id);if(span){span.style.display='none';}document.getElementById(id).style.display="none";}},show:function(id){if((elem=document.getElementById(id))&&this.hidden[id]){elem.style.display="inline";elem.scrollTop=this.hidden[id]["scrollTop"];elem.scrollLeft=this.hidden[id]["scrollLeft"];var span=document.getElementById("EditAreaArroundInfos_"+id);if(span){span.style.display='inline';}if(window.frames["frame_"+id]){elem.style.display="inline";if(this.hidden[id]["toggle"]==true)eAL.toggle_on(id);scrollTop=this.hidden[id]["scrollTop"];scrollLeft=this.hidden[id]["scrollLeft"];if(window.frames["frame_"+id]&&eAs[id]["displayed"]==true){window.frames["frame_"+id].document.getElementById("result").scrollTop=scrollTop;window.frames["frame_"+id].document.getElementById("result").scrollLeft=scrollLeft;}
+else{elem.scrollTop=scrollTop;elem.scrollLeft=scrollLeft;}}sel=this.hidden[id]["selectionRange"];this.setSelectionRange(id,sel["start"],sel["end"]);delete this.hidden[id];}},getCurrentFile:function(id){return this.execCommand(id,'get_file',this.execCommand(id,'curr_file'));},getFile:function(id,file_id){return this.execCommand(id,'get_file',file_id);},getAllFiles:function(id){return this.execCommand(id,'get_all_files()');},openFile:function(id,file_infos){return this.execCommand(id,'open_file',file_infos);},closeFile:function(id,file_id){return this.execCommand(id,'close_file',file_id);},setFileEditedMode:function(id,file_id,to){var reg1=new RegExp('\\\\','g');var reg2=new RegExp('"','g');return this.execCommand(id,'set_file_edited_mode("'+file_id.replace(reg1,'\\\\').replace(reg2,'\\"')+'",'+to +')');},execCommand:function(id,cmd,fct_param){switch(cmd){case "EA_init":if(eAs[id]['settings']["EA_init_callback"].length>0)eval(eAs[id]['settings']["EA_init_callback"]+"('"+id +"');");break;case "EA_delete":if(eAs[id]['settings']["EA_delete_callback"].length>0)eval(eAs[id]['settings']["EA_delete_callback"]+"('"+id +"');");break;case "EA_submit":if(eAs[id]['settings']["submit_callback"].length>0)eval(eAs[id]['settings']["submit_callback"]+"('"+id +"');");break;}if(window.frames["frame_"+id]&&window.frames["frame_"+id].editArea){if(fct_param!=undefined)return eval('window.frames["frame_'+id +'"].editArea.'+cmd +'(fct_param);');
+else return eval('window.frames["frame_'+id +'"].editArea.'+cmd +';');}return false;}};var eAL=new EAL();var eAs=new Object(); function getAttribute(elm,aname){try{var avalue=elm.getAttribute(aname );}catch(exept){}if(! avalue){for(var i=0;i < elm.attributes.length;i ++){var taName=elm.attributes [i] .name.toLowerCase();if(taName==aname){avalue=elm.attributes [i] .value;return avalue;}}}return avalue;};function setAttribute(elm,attr,val){if(attr=="class"){elm.setAttribute("className",val);elm.setAttribute("class",val);}
+else{elm.setAttribute(attr,val);}};function getChildren(elem,elem_type,elem_attribute,elem_attribute_match,option,depth){if(!option)var option="single";if(!depth)var depth=-1;if(elem){var children=elem.childNodes;var result=null;var results=new Array();for (var x=0;x<children.length;x++){strTagName=new String(children[x].tagName);children_class="?";if(strTagName!="undefined"){child_attribute=getAttribute(children[x],elem_attribute);if((strTagName.toLowerCase()==elem_type.toLowerCase()||elem_type=="")&&(elem_attribute==""||child_attribute==elem_attribute_match)){if(option=="all"){results.push(children[x]);}
+else{return children[x];}}if(depth!=0){result=getChildren(children[x],elem_type,elem_attribute,elem_attribute_match,option,depth-1);if(option=="all"){if(result.length>0){results=results.concat(result);}}
+else if(result!=null){return result;}}}}if(option=="all")return results;}return null;};function isChildOf(elem,parent){if(elem){if(elem==parent)return true;while(elem.parentNode !='undefined'){return isChildOf(elem.parentNode,parent);}}return false;};function getMouseX(e){if(e!=null&&typeof(e.pageX)!="undefined"){return e.pageX;}
+else{return (e!=null?e.x:event.x)+document.documentElement.scrollLeft;}};function getMouseY(e){if(e!=null&&typeof(e.pageY)!="undefined"){return e.pageY;}
+else{return (e!=null?e.y:event.y)+document.documentElement.scrollTop;}};function calculeOffsetLeft(r){return calculeOffset(r,"offsetLeft")};function calculeOffsetTop(r){return calculeOffset(r,"offsetTop")};function calculeOffset(element,attr){var offset=0;while(element){offset+=element[attr];element=element.offsetParent}return offset;};function get_css_property(elem,prop){if(document.defaultView){return document.defaultView.getComputedStyle(elem,null).getPropertyValue(prop);}
+else if(elem.currentStyle){var prop=prop.replace(/-\D/gi,function(sMatch){return sMatch.charAt(sMatch.length-1).toUpperCase();});return elem.currentStyle[prop];}
+else return null;}var move_current_element;function start_move_element(e,id,frame){var elem_id=(e.target||e.srcElement).id;if(id)elem_id=id;if(!frame)frame=window;if(frame.event)e=frame.event;move_current_element=frame.document.getElementById(elem_id);move_current_element.frame=frame;frame.document.onmousemove=move_element;frame.document.onmouseup=end_move_element;mouse_x=getMouseX(e);mouse_y=getMouseY(e);move_current_element.start_pos_x=mouse_x-(move_current_element.style.left.replace("px","")||calculeOffsetLeft(move_current_element));move_current_element.start_pos_y=mouse_y-(move_current_element.style.top.replace("px","")||calculeOffsetTop(move_current_element));return false;};function end_move_element(e){move_current_element.frame.document.onmousemove="";move_current_element.frame.document.onmouseup="";move_current_element=null;};function move_element(e){if(move_current_element.frame&&move_current_element.frame.event)e=move_current_element.frame.event;var mouse_x=getMouseX(e);var mouse_y=getMouseY(e);var new_top=mouse_y-move_current_element.start_pos_y;var new_left=mouse_x-move_current_element.start_pos_x;var max_left=move_current_element.frame.document.body.offsetWidth-move_current_element.offsetWidth;max_top=move_current_element.frame.document.body.offsetHeight-move_current_element.offsetHeight;new_top=Math.min(Math.max(0,new_top),max_top);new_left=Math.min(Math.max(0,new_left),max_left);move_current_element.style.top=new_top+"px";move_current_element.style.left=new_left+"px";return false;};var nav=eAL.nav;function getSelectionRange(textarea){return {"start":textarea.selectionStart,"end":textarea.selectionEnd};};function setSelectionRange(textarea,start,end){textarea.focus();start=Math.max(0,Math.min(textarea.value.length,start));end=Math.max(start,Math.min(textarea.value.length,end));if(nav['isOpera']){textarea.selectionEnd=1;textarea.selectionStart=0;textarea.selectionEnd=1;textarea.selectionStart=0;}textarea.selectionStart=start;textarea.selectionEnd=end;if(nav['isIE'])set_IE_selection(textarea);};function get_IE_selection(textarea){if(textarea&&textarea.focused){if(!textarea.ea_line_height){var div=document.createElement("div");div.style.fontFamily=get_css_property(textarea,"font-family");div.style.fontSize=get_css_property(textarea,"font-size");div.style.visibility="hidden";div.innerHTML="0";document.body.appendChild(div);textarea.ea_line_height=div.offsetHeight;document.body.removeChild(div);}var range=document.selection.createRange();var stored_range=range.duplicate();stored_range.moveToElementText(textarea );stored_range.setEndPoint('EndToEnd',range );if(stored_range.parentElement()==textarea){var elem=textarea;var scrollTop=0;while(elem.parentNode){scrollTop+=elem.scrollTop;elem=elem.parentNode;}var relative_top=range.offsetTop-calculeOffsetTop(textarea)+scrollTop;var line_start=Math.round((relative_top / textarea.ea_line_height)+1);var line_nb=Math.round(range.boundingHeight / textarea.ea_line_height);var range_start=stored_range.text.length-range.text.length;var tab=textarea.value.substr(0,range_start).split("\n");range_start+=(line_start-tab.length)*2;textarea.selectionStart=range_start;var range_end=textarea.selectionStart+range.text.length;tab=textarea.value.substr(0,range_start+range.text.length).split("\n");range_end+=(line_start+line_nb-1-tab.length)*2;textarea.selectionEnd=range_end;}}setTimeout("get_IE_selection(document.getElementById('"+textarea.id +"'));",50);};function IE_textarea_focus(){event.srcElement.focused=true;}function IE_textarea_blur(){event.srcElement.focused=false;}function set_IE_selection(textarea){if(!window.closed){var nbLineStart=textarea.value.substr(0,textarea.selectionStart).split("\n").length-1;var nbLineEnd=textarea.value.substr(0,textarea.selectionEnd).split("\n").length-1;var range=document.selection.createRange();range.moveToElementText(textarea );range.setEndPoint('EndToStart',range );range.moveStart('character',textarea.selectionStart-nbLineStart);range.moveEnd('character',textarea.selectionEnd-nbLineEnd-(textarea.selectionStart-nbLineStart));range.select();}};eAL.waiting_loading["elements_functions.js"]="loaded";
+ EAL.prototype.start_resize_area=function(){document.onmouseup=eAL.end_resize_area;document.onmousemove=eAL.resize_area;eAL.toggle(eAL.resize["id"]);var textarea=eAs[eAL.resize["id"]]["textarea"];var div=document.getElementById("edit_area_resize");if(!div){div=document.createElement("div");div.id="edit_area_resize";div.style.border="dashed #888888 1px";}var width=textarea.offsetWidth -2;var height=textarea.offsetHeight -2;div.style.display="block";div.style.width=width+"px";div.style.height=height+"px";var father=textarea.parentNode;father.insertBefore(div,textarea);textarea.style.display="none";eAL.resize["start_top"]=calculeOffsetTop(div);eAL.resize["start_left"]=calculeOffsetLeft(div);};EAL.prototype.end_resize_area=function(e){document.onmouseup="";document.onmousemove="";var div=document.getElementById("edit_area_resize");var textarea=eAs[eAL.resize["id"]]["textarea"];var width=Math.max(eAs[eAL.resize["id"]]["settings"]["min_width"],div.offsetWidth-4);var height=Math.max(eAs[eAL.resize["id"]]["settings"]["min_height"],div.offsetHeight-4);if(eAL.nav['isIE']==6){width-=2;height-=2;}textarea.style.width=width+"px";textarea.style.height=height+"px";div.style.display="none";textarea.style.display="inline";textarea.selectionStart=eAL.resize["selectionStart"];textarea.selectionEnd=eAL.resize["selectionEnd"];eAL.toggle(eAL.resize["id"]);return false;};EAL.prototype.resize_area=function(e){var allow=eAs[eAL.resize["id"]]["settings"]["allow_resize"];if(allow=="both"||allow=="y"){new_y=getMouseY(e);var new_height=Math.max(20,new_y-eAL.resize["start_top"]);document.getElementById("edit_area_resize").style.height=new_height+"px";}if(allow=="both"||allow=="x"){new_x=getMouseX(e);var new_width=Math.max(20,new_x-eAL.resize["start_left"]);document.getElementById("edit_area_resize").style.width=new_width+"px";}return false;};eAL.waiting_loading["resize_area.js"]="loaded";
+	EAL.prototype.get_regexp=function(text_array){res="(\\b)(";for(i=0;i<text_array.length;i++){if(i>0)res+="|";res+=this.get_escaped_regexp(text_array[i]);}res+=")(\\b)";reg=new RegExp(res);return res;};EAL.prototype.get_escaped_regexp=function(str){return str.replace(/(\.|\?|\*|\+|\\|\(|\)|\[|\]|\}|\{|\$|\^|\|)/g,"\\$1");};EAL.prototype.init_syntax_regexp=function(){var lang_style=new Object();for(var lang in this.load_syntax){if(!this.syntax[lang]){this.syntax[lang]=new Object();this.syntax[lang]["keywords_reg_exp"]=new Object();this.keywords_reg_exp_nb=0;if(this.load_syntax[lang]['KEYWORDS']){param="g";if(this.load_syntax[lang]['KEYWORD_CASE_SENSITIVE']===false)param+="i";for(var i in this.load_syntax[lang]['KEYWORDS']){if(typeof(this.load_syntax[lang]['KEYWORDS'][i])=="function")continue;this.syntax[lang]["keywords_reg_exp"][i]=new RegExp(this.get_regexp(this.load_syntax[lang]['KEYWORDS'][i] ),param);this.keywords_reg_exp_nb++;}}if(this.load_syntax[lang]['OPERATORS']){var str="";var nb=0;for(var i in this.load_syntax[lang]['OPERATORS']){if(typeof(this.load_syntax[lang]['OPERATORS'][i])=="function")continue;if(nb>0)str+="|";str+=this.get_escaped_regexp(this.load_syntax[lang]['OPERATORS'][i]);nb++;}if(str.length>0)this.syntax[lang]["operators_reg_exp"]=new RegExp("("+str+")","g");}if(this.load_syntax[lang]['DELIMITERS']){var str="";var nb=0;for(var i in this.load_syntax[lang]['DELIMITERS']){if(typeof(this.load_syntax[lang]['DELIMITERS'][i])=="function")continue;if(nb>0)str+="|";str+=this.get_escaped_regexp(this.load_syntax[lang]['DELIMITERS'][i]);nb++;}if(str.length>0)this.syntax[lang]["delimiters_reg_exp"]=new RegExp("("+str+")","g");}var syntax_trace=new Array();this.syntax[lang]["quotes"]=new Object();var quote_tab=new Array();if(this.load_syntax[lang]['QUOTEMARKS']){for(var i in this.load_syntax[lang]['QUOTEMARKS']){if(typeof(this.load_syntax[lang]['QUOTEMARKS'][i])=="function")continue;var x=this.get_escaped_regexp(this.load_syntax[lang]['QUOTEMARKS'][i]);this.syntax[lang]["quotes"][x]=x;quote_tab[quote_tab.length]="("+x+"(?:[^"+x+"\\\\]*(\\\\\\\\)*(\\\\"+x+"?)?)*("+x+"|$))";syntax_trace.push(x);}}this.syntax[lang]["comments"]=new Object();if(this.load_syntax[lang]['COMMENT_SINGLE']){for(var i in this.load_syntax[lang]['COMMENT_SINGLE']){if(typeof(this.load_syntax[lang]['COMMENT_SINGLE'][i])=="function")continue;var x=this.get_escaped_regexp(this.load_syntax[lang]['COMMENT_SINGLE'][i]);quote_tab[quote_tab.length]="("+x+"(.|\\r|\\t)*(\\n|$))";syntax_trace.push(x);this.syntax[lang]["comments"][x]="\n";}}if(this.load_syntax[lang]['COMMENT_MULTI']){for(var i in this.load_syntax[lang]['COMMENT_MULTI']){if(typeof(this.load_syntax[lang]['COMMENT_MULTI'][i])=="function")continue;var start=this.get_escaped_regexp(i);var end=this.get_escaped_regexp(this.load_syntax[lang]['COMMENT_MULTI'][i]);quote_tab[quote_tab.length]="("+start+"(.|\\n|\\r)*?("+end+"|$))";syntax_trace.push(start);syntax_trace.push(end);this.syntax[lang]["comments"][i]=this.load_syntax[lang]['COMMENT_MULTI'][i];}}if(quote_tab.length>0)this.syntax[lang]["comment_or_quote_reg_exp"]=new RegExp("("+quote_tab.join("|")+")","gi");if(syntax_trace.length>0)this.syntax[lang]["syntax_trace_regexp"]=new RegExp("((.|\n)*?)(\\\\*("+syntax_trace.join("|")+"|$))","gmi");if(this.load_syntax[lang]['SCRIPT_DELIMITERS']){this.syntax[lang]["script_delimiters"]=new Object();for(var i in this.load_syntax[lang]['SCRIPT_DELIMITERS']){if(typeof(this.load_syntax[lang]['SCRIPT_DELIMITERS'][i])=="function")continue;this.syntax[lang]["script_delimiters"][i]=this.load_syntax[lang]['SCRIPT_DELIMITERS'];}}this.syntax[lang]["custom_regexp"]=new Object();if(this.load_syntax[lang]['REGEXPS']){for(var i in this.load_syntax[lang]['REGEXPS']){if(typeof(this.load_syntax[lang]['REGEXPS'][i])=="function")continue;var val=this.load_syntax[lang]['REGEXPS'][i];if(!this.syntax[lang]["custom_regexp"][val['execute']])this.syntax[lang]["custom_regexp"][val['execute']]=new Object();this.syntax[lang]["custom_regexp"][val['execute']][i]={'regexp':new RegExp(val['search'],val['modifiers']),'class':val['class']};}}if(this.load_syntax[lang]['STYLES']){lang_style[lang]=new Object();for(var i in this.load_syntax[lang]['STYLES']){if(typeof(this.load_syntax[lang]['STYLES'][i])=="function")continue;if(typeof(this.load_syntax[lang]['STYLES'][i])!="string"){for(var j in this.load_syntax[lang]['STYLES'][i]){lang_style[lang][j]=this.load_syntax[lang]['STYLES'][i][j];}}
+else{lang_style[lang][i]=this.load_syntax[lang]['STYLES'][i];}}}var style="";for(var i in lang_style[lang]){if(lang_style[lang][i].length>0){style+="."+lang +" ."+i.toLowerCase()+" span{"+lang_style[lang][i]+"}\n";style+="."+lang +" ."+i.toLowerCase()+"{"+lang_style[lang][i]+"}\n";}}this.syntax[lang]["styles"]=style;}}};eAL.waiting_loading["reg_syntax.js"]="loaded";
+var editAreaLoader= eAL;var editAreas=eAs;EditAreaLoader=EAL;editAreaLoader.iframe_script= "<script type='text/javascript'> Ã EA(){Á.error=Ì;Á.inlinePopup=new Array({popup_id:\"area_search_replace\",icon_id:\"search\"},{popup_id:\"edit_area_help\",icon_id:\"help\"});Á.plugins=new Object();Á.line_number=0;Á.nav=È.eAL.nav;Á.É=new Object();Á.last_text_to_highlight=\"\";Á.last_hightlighted_text=\"\";Á.syntax_list=new Array();Á.allready_used_syntax=new Object();Á.check_line_selection_timer=50;Á.ÂFocused=Ì;Á.highlight_selection_line=null;Á.previous=new Array();Á.next=new Array();Á.last_undo=\"\";Á.files=new Object();Á.filesIdAssoc=new Object();Á.curr_file='';Á.assocBracket=new Object();Á.revertAssocBracket=new Object();Á.assocBracket[\"(\"]=\")\";Á.assocBracket[\"{\"]=\"}\";Á.assocBracket[\"[\"]=\"]\";for(var index in Á.assocBracket){Á.revertAssocBracket[Á.assocBracket[index]]=index;}Á.is_editable=Ë;Á.lineHeight=16;Á.tab_nb_char=8;if(Á.nav['isOpera'])Á.tab_nb_char=6;Á.is_tabbing=Ì;Á.fullscreen={'isFull':Ì};Á.isResizing=Ì;Á.id=area_id;Á.Å=eAs[Á.id][\"Å\"];if((\"\"+Á.Å['replace_tab_by_spaces']).match(/^[0-9]+$/)){Á.tab_nb_char=Á.Å['replace_tab_by_spaces'];Á.tabulation=\"\";for(var i=0;i<Á.tab_nb_char;i++)Á.tabulation+=\" \";}\nelse{Á.tabulation=\"\t\";}if(Á.Å[\"syntax_selection_allow\"]&&Á.Å[\"syntax_selection_allow\"].Æ>0)Á.syntax_list=Á.Å[\"syntax_selection_allow\"].replace(/ /g,\"\").split(\",\");if(Á.Å['syntax'])Á.allready_used_syntax[Á.Å['syntax']]=Ë;};EA.Ä.update_size=Ã(){if(eAs[eA.id]&&eAs[eA.id][\"displayed\"]==Ë){if(eA.fullscreen['isFull']){È.document.getElementById(\"frame_\"+eA.id).Ç.width=È.document.getElementsByTagName(\"html\")[0].clientWidth+\"px\";È.document.getElementById(\"frame_\"+eA.id).Ç.height=È.document.getElementsByTagName(\"html\")[0].clientHeight+\"px\";}if(eA.tab_browsing_area.Ç.display=='block'&&!eA.nav['isIE']){eA.tab_browsing_area.Ç.height=\"0px\";eA.tab_browsing_area.Ç.height=(eA.result.offsetTop-eA.tab_browsing_area.offsetTop -1)+\"px\";}var height=document.body.offsetHeight-eA.get_all_toolbar_height()-4;eA.result.Ç.height=height +\"px\";var width=document.body.offsetWidth -2;eA.result.Ç.width=width+\"px\";for(var i=0;i<eA.inlinePopup.Æ;i++){var popup=$(eA.inlinePopup[i][\"popup_id\"]);var max_left=document.body.offsetWidth-popup.offsetWidth;var max_top=document.body.offsetHeight-popup.offsetHeight;if(popup.offsetTop>max_top)popup.Ç.top=max_top+\"px\";if(popup.offsetLeft>max_left)popup.Ç.left=max_left+\"px\";}}};EA.Ä.init=Ã(){Á.Â=$(\"Â\");Á.container=$(\"container\");Á.result=$(\"result\");Á.content_highlight=$(\"content_highlight\");Á.selection_field=$(\"selection_field\");Á.processing_screen=$(\"processing\");Á.editor_area=$(\"editor\");Á.tab_browsing_area=$(\"tab_browsing_area\");if(!Á.Å['is_editable'])Á.set_editable(Ì);Á.set_show_line_colors(Á.Å['show_line_colors'] );if(syntax_selec=$(\"syntax_selection\")){for(var i=0;i<Á.syntax_list.Æ;i++){var syntax=Á.syntax_list[i];var option=document.createElement(\"option\");option.Ê=syntax;if(syntax==Á.Å['syntax'])option.selected=\"selected\";option.innerHTML=Á.get_translation(\"syntax_\"+syntax,\"word\");syntax_selec.appendChild(option);}}spans=È.getChildren($(\"toolbar_1\"),\"span\",\"\",\"\",\"all\",-1);for(var i=0;i<spans.Æ;i++){id=spans[i].id.replace(/tmp_tool_(.*)/,\"$1\");if(id!=spans[i].id){for(var j in Á.plugins){if(typeof(Á.plugins[j].get_control_html)==\"Ã\" ){html=Á.plugins[j].get_control_html(id);if(html!=Ì){html=Á.get_translation(html,\"template\");var new_span=document.createElement(\"span\");new_span.innerHTML=html;var father=spans[i].ÈNode;spans[i].ÈNode.replaceChild(new_span,spans[i]);break;}}}}}Á.Â.Ê=eAs[Á.id][\"Â\"].Ê;if(Á.Å[\"debug\"])Á.debug=È.document.getElementById(\"edit_area_debug_\"+Á.id);if($(\"redo\")!=null)Á.switchClassSticky($(\"redo\"),'editAreaButtonDisabled',Ë);if(typeof(È.eAL.syntax[Á.Å[\"syntax\"]])!=\"undefined\"){for(var i in È.eAL.syntax){Á.add_Ç(È.eAL.syntax[i][\"Çs\"]);}}if(Á.nav['isOpera'])$(\"editor\").onkeypress=keyDown;\nelse $(\"editor\").onkeydown=keyDown;for(var i=0;i<Á.inlinePopup.Æ;i++){if(Á.nav['isIE']||Á.nav['isFirefox'])$(Á.inlinePopup[i][\"popup_id\"]).onkeydown=keyDown;\nelse $(Á.inlinePopup[i][\"popup_id\"]).onkeypress=keyDown;}if(Á.Å[\"allow_resize\"]==\"both\"||Á.Å[\"allow_resize\"]==\"x\"||Á.Å[\"allow_resize\"]==\"y\")Á.allow_resize(Ë);È.eAL.toggle(Á.id,\"on\");Á.change_smooth_selection_mode(eA.smooth_selection);Á.execCommand(\"change_highlight\",Á.Å[\"start_highlight\"]);Á.set_font(eA.Å[\"font_family\"],eA.Å[\"font_size\"]);children=È.getChildren(document.body,\"\",\"selec\",\"none\",\"all\",-1);for(var i=0;i<children.Æ;i++){if(Á.nav['isIE'])children[i].unselectable=Ë;\nelse children[i].onmousedown=Ã(){return Ì};}if(Á.nav['isGecko']){Á.Â.spellcheck=Á.Å[\"gecko_spellcheck\"];}if(Á.nav['isFirefox'] >='3')Á.content_highlight.Ç.borderLeft=\"solid 1px transÈ\";if(Á.nav['isIE']){Á.Â.Ç.marginTop=\"-1px\";}if(Á.nav['isSafari'] ){Á.editor_area.Ç.position=\"absolute\";Á.Â.Ç.marginLeft=\"-3px\";Á.Â.Ç.marginTop=\"1px\";}if(Á.nav['isChrome'] ){Á.editor_area.Ç.position=\"absolute\";Á.Â.Ç.marginLeft=\"0px\";Á.Â.Ç.marginTop=\"0px\";}È.eAL.add_event(Á.result,\"click\",Ã(e){if((e.target||e.srcElement)==eA.result){eA.area_select(eA.Â.Ê.Æ,0);}});if(Á.Å['is_multi_files']!=Ì)Á.open_file({'id':Á.curr_file,'text':''});Á.set_wrap_text(Á.Å['wrap_text'] );setTimeout(\"eA.focus();eA.manage_size();eA.execCommand('EA_load');\",10);Á.check_undo();Á.check_line_selection(Ë);Á.scroll_to_view();for(var i in Á.plugins){if(typeof(Á.plugins[i].onload)==\"Ã\")Á.plugins[i].onload();}if(Á.Å['fullscreen']==Ë)Á.toggle_full_screen(Ë);È.eAL.add_event(window,\"resize\",eA.update_size);È.eAL.add_event(È.window,\"resize\",eA.update_size);È.eAL.add_event(top.window,\"resize\",eA.update_size);È.eAL.add_event(window,\"unload\",Ã(){if(eAs[eA.id]&&eAs[eA.id][\"displayed\"])eA.execCommand(\"EA_unload\");});};EA.Ä.manage_size=Ã(onlyOneTime){if(!eAs[Á.id])return Ì;if(eAs[Á.id][\"displayed\"]==Ë&&Á.ÂFocused){var resized=Ì;if(Á.Å['wrap_text']){}\nelse{var area_width=Á.Â.scrollWidth;var area_height=Á.Â.scrollHeight;if(Á.nav['isOpera']){area_width=10000;}}if(Á.Â.previous_scrollWidth!=area_width){Á.container.Ç.width=area_width+\"px\";Á.Â.Ç.width=area_width+\"px\";Á.content_highlight.Ç.width=area_width+\"px\";Á.Â.previous_scrollWidth=area_width;resized=Ë;}var area_height=Á.Â.scrollHeight;if(Á.nav['isOpera']){area_height=Á.É['nb_line']*Á.lineHeight;}if(Á.nav['isGecko']&&Á.smooth_selection&&Á.É[\"nb_line\"])area_height=Á.É[\"nb_line\"]*Á.lineHeight;if(Á.Â.previous_scrollHeight!=area_height){Á.container.Ç.height=(area_height+2)+\"px\";Á.Â.Ç.height=area_height+\"px\";Á.content_highlight.Ç.height=area_height+\"px\";Á.Â.previous_scrollHeight=area_height;resized=Ë;}if(Á.É[\"nb_line\"] >=Á.line_number){var div_line_number=\"\";for(i=Á.line_number+1;i<Á.É[\"nb_line\"]+100;i++){div_line_number+=i+\"<br />\";Á.line_number++;}var span=document.createElement(\"span\");if(Á.nav['isIE'])span.unselectable=Ë;span.innerHTML=div_line_number;$(\"line_number\").appendChild(span);}Á.Â.scrollTop=\"0px\";Á.Â.scrollLeft=\"0px\";if(resized==Ë){Á.scroll_to_view();}}if(!onlyOneTime)setTimeout(\"eA.manage_size();\",100);};EA.Ä.add_event=Ã(obj,name,handler){if (Á.nav['isIE']){obj.attachEvent(\"on\"+name,handler);}\nelse{obj.addEventListener(name,handler,Ì);}};EA.Ä.execCommand=Ã(cmd,param){for(var i in Á.plugins){if(typeof(Á.plugins[i].execCommand)==\"Ã\"){if(!Á.plugins[i].execCommand(cmd,param))return;}}switch(cmd){case \"save\":if(Á.Å[\"save_callback\"].Æ>0)eval(\"È.\"+Á.Å[\"save_callback\"]+\"('\"+Á.id +\"',eA.Â.Ê);\");break;case \"load\":if(Á.Å[\"load_callback\"].Æ>0)eval(\"È.\"+Á.Å[\"load_callback\"]+\"('\"+Á.id +\"');\");break;case \"onchange\":if(Á.Å[\"change_callback\"].Æ>0)eval(\"È.\"+Á.Å[\"change_callback\"]+\"('\"+Á.id +\"');\");break;case \"EA_load\":if(Á.Å[\"EA_load_callback\"].Æ>0)eval(\"È.\"+Á.Å[\"EA_load_callback\"]+\"('\"+Á.id +\"');\");break;case \"EA_unload\":if(Á.Å[\"EA_unload_callback\"].Æ>0)eval(\"È.\"+Á.Å[\"EA_unload_callback\"]+\"('\"+Á.id +\"');\");break;case \"toggle_on\":if(Á.Å[\"EA_toggle_on_callback\"].Æ>0)eval(\"È.\"+Á.Å[\"EA_toggle_on_callback\"]+\"('\"+Á.id +\"');\");break;case \"toggle_off\":if(Á.Å[\"EA_toggle_off_callback\"].Æ>0)eval(\"È.\"+Á.Å[\"EA_toggle_off_callback\"]+\"('\"+Á.id +\"');\");break;case \"re_sync\":if(!Á.do_highlight)break;case \"file_switch_on\":if(Á.Å[\"EA_file_switch_on_callback\"].Æ>0)eval(\"È.\"+Á.Å[\"EA_file_switch_on_callback\"]+\"(param);\");break;case \"file_switch_off\":if(Á.Å[\"EA_file_switch_off_callback\"].Æ>0)eval(\"È.\"+Á.Å[\"EA_file_switch_off_callback\"]+\"(param);\");break;case \"file_close\":if(Á.Å[\"EA_file_close_callback\"].Æ>0)return eval(\"È.\"+Á.Å[\"EA_file_close_callback\"]+\"(param);\");break;default:if(typeof(eval(\"eA.\"+cmd))==\"Ã\"){if(Á.Å[\"debug\"])eval(\"eA.\"+cmd +\"(param);\");\nelse try{eval(\"eA.\"+cmd +\"(param);\");}catch(e){};}}};EA.Ä.get_translation=Ã(word,mode){if(mode==\"template\")return È.eAL.translate(word,Á.Å[\"language\"],mode);\nelse return È.eAL.get_word_translation(word,Á.Å[\"language\"]);};EA.Ä.add_plugin=Ã(plug_name,plug_obj){for(var i=0;i<Á.Å[\"plugins\"].Æ;i++){if(Á.Å[\"plugins\"][i]==plug_name){Á.plugins[plug_name]=plug_obj;plug_obj.baseURL=È.eAL.baseURL+\"plugins/\"+plug_name+\"/\";if(typeof(plug_obj.init)==\"Ã\")plug_obj.init();}}};EA.Ä.load_css=Ã(url){try{link=document.createElement(\"link\");link.type=\"text/css\";link.rel=\"Çsheet\";link.media=\"all\";link.href=url;head=document.getElementsByTagName(\"head\");head[0].appendChild(link);}catch(e){document.write(\"<link href='\"+url +\"' rel='Çsheet' type='text/css' />\");}};EA.Ä.load_script=Ã(url){try{script=document.createElement(\"script\");script.type=\"text/javascript\";script.src =url;script.charset=\"UTF-8\";head=document.getElementsByTagName(\"head\");head[0].appendChild(script);}catch(e){document.write(\"<script type='text/javascript' src='\"+url+\"' charset=\\\"UTF-8\\\"><\"+\"/script>\");}};EA.Ä.add_lang=Ã(language,Ês){if(!È.eAL.lang[language])È.eAL.lang[language]=new Object();for(var i in Ês)È.eAL.lang[language][i]=Ês[i];};Ã $(id){return document.getElementById(id );};var eA=new EA();eA.add_event(window,\"load\",init);Ã init(){setTimeout(\"eA.init();\",10);};	EA.Ä.focus=Ã(){Á.Â.focus();Á.ÂFocused=Ë;};EA.Ä.check_line_selection=Ã(timer_checkup){if(!eAs[Á.id])return Ì;if(!Á.smooth_selection&&!Á.do_highlight){}\nelse if(Á.ÂFocused&&eAs[Á.id][\"displayed\"]==Ë&&Á.isResizing==Ì){infos=Á.get_selection_infos();if(Á.É[\"line_start\"] !=infos[\"line_start\"]||Á.É[\"line_nb\"] !=infos[\"line_nb\"]||infos[\"full_text\"] !=Á.É[\"full_text\"]||Á.reload_highlight){new_top=Á.lineHeight * (infos[\"line_start\"]-1);new_height=Math.max(0,Á.lineHeight * infos[\"line_nb\"]);new_width=Math.max(Á.Â.scrollWidth,Á.container.clientWidth -50);Á.selection_field.Ç.top=new_top+\"px\";Á.selection_field.Ç.width=new_width+\"px\";Á.selection_field.Ç.height=new_height+\"px\";$(\"cursor_pos\").Ç.top=new_top+\"px\";if(Á.do_highlight==Ë){var curr_text=infos[\"full_text\"].split(\"\\n\");var content=\"\";var start=Math.max(0,infos[\"line_start\"]-1);var end=Math.min(curr_text.Æ,infos[\"line_start\"]+infos[\"line_nb\"]-1);for(i=start;i< end;i++){content+=curr_text[i]+\"\\n\";}content=content.replace(/&/g,\"&amp;\");content=content.replace(/</g,\"&lt;\");content=content.replace(/>/g,\"&gt;\");if(Á.nav['isIE']||Á.nav['isOpera']||Á.nav['isFirefox'] >=3)Á.selection_field.innerHTML=\"<pre>\"+content.replace(\"\\n\",\"<br/>\")+\"</pre>\";\nelse Á.selection_field.innerHTML=content;if(Á.reload_highlight||(infos[\"full_text\"] !=Á.last_text_to_highlight&&(Á.É[\"line_start\"]!=infos[\"line_start\"]||Á.show_line_colors||Á.É[\"line_nb\"]!=infos[\"line_nb\"]||Á.É[\"nb_line\"]!=infos[\"nb_line\"])))Á.maj_highlight(infos);}}if(infos[\"line_start\"] !=Á.É[\"line_start\"]||infos[\"curr_pos\"] !=Á.É[\"curr_pos\"]||infos[\"full_text\"].Æ!=Á.É[\"full_text\"].Æ||Á.reload_highlight){var selec_char=infos[\"curr_line\"].charAt(infos[\"curr_pos\"]-1);var no_real_move=Ë;if(infos[\"line_nb\"]==1&&(Á.assocBracket[selec_char]||Á.revertAssocBracket[selec_char])){no_real_move=Ì;if(Á.findEndBracket(infos,selec_char)===Ë){$(\"end_bracket\").Ç.visibility=\"visible\";$(\"cursor_pos\").Ç.visibility=\"visible\";$(\"cursor_pos\").innerHTML=selec_char;$(\"end_bracket\").innerHTML=(Á.assocBracket[selec_char]||Á.revertAssocBracket[selec_char]);}\nelse{$(\"end_bracket\").Ç.visibility=\"hidden\";$(\"cursor_pos\").Ç.visibility=\"hidden\";}}\nelse{$(\"cursor_pos\").Ç.visibility=\"hidden\";$(\"end_bracket\").Ç.visibility=\"hidden\";}Á.displayToCursorPosition(\"cursor_pos\",infos[\"line_start\"],infos[\"curr_pos\"]-1,infos[\"curr_line\"],no_real_move);if(infos[\"line_nb\"]==1&&infos[\"line_start\"]!=Á.É[\"line_start\"])Á.scroll_to_view();}Á.É=infos;}if(timer_checkup){setTimeout(\"eA.check_line_selection(Ë)\",Á.check_line_selection_timer);}};EA.Ä.get_selection_infos=Ã(){if(Á.nav['isIE'])Á.getIESelection();start=Á.Â.selectionStart;end=Á.Â.selectionEnd;if(Á.É[\"selectionStart\"]==start&&Á.É[\"selectionEnd\"]==end&&Á.É[\"full_text\"]==Á.Â.Ê)return Á.É;if(Á.tabulation!=\"\t\"&&Á.Â.Ê.indexOf(\"\t\")!=-1){var len=Á.Â.Ê.Æ;Á.Â.Ê=Á.replace_tab(Á.Â.Ê);start=end=start+(Á.Â.Ê.Æ-len);Á.area_select(start,0);}var selections=new Object();selections[\"selectionStart\"]=start;selections[\"selectionEnd\"]=end;selections[\"full_text\"]=Á.Â.Ê;selections[\"line_start\"]=1;selections[\"line_nb\"]=1;selections[\"curr_pos\"]=0;selections[\"curr_line\"]=\"\";selections[\"indexOfCursor\"]=0;selections[\"selec_direction\"]=Á.É[\"selec_direction\"];var splitTab=selections[\"full_text\"].split(\"\\n\");var nbLine=Math.max(0,splitTab.Æ);var nbChar=Math.max(0,selections[\"full_text\"].Æ-(nbLine-1));if(selections[\"full_text\"].indexOf(\"\\r\")!=-1)nbChar=nbChar-(nbLine -1);selections[\"nb_line\"]=nbLine;selections[\"nb_char\"]=nbChar;if(start>0){var str=selections[\"full_text\"].substr(0,start);selections[\"curr_pos\"]=start-str.lastIndexOf(\"\\n\");selections[\"line_start\"]=Math.max(1,str.split(\"\\n\").Æ);}\nelse{selections[\"curr_pos\"]=1;}if(end>start){selections[\"line_nb\"]=selections[\"full_text\"].substring(start,end).split(\"\\n\").Æ;}selections[\"indexOfCursor\"]=Á.Â.selectionStart;selections[\"curr_line\"]=splitTab[Math.max(0,selections[\"line_start\"]-1)];if(selections[\"selectionStart\"]==Á.É[\"selectionStart\"]){if(selections[\"selectionEnd\"]>Á.É[\"selectionEnd\"])selections[\"selec_direction\"]=\"down\";\nelse if(selections[\"selectionEnd\"]==Á.É[\"selectionStart\"])selections[\"selec_direction\"]=Á.É[\"selec_direction\"];}\nelse if(selections[\"selectionStart\"]==Á.É[\"selectionEnd\"]&&selections[\"selectionEnd\"]>Á.É[\"selectionEnd\"]){selections[\"selec_direction\"]=\"down\";}\nelse{selections[\"selec_direction\"]=\"up\";}$(\"nbLine\").innerHTML=nbLine;$(\"nbChar\").innerHTML=nbChar;$(\"linePos\").innerHTML=selections[\"line_start\"];$(\"currPos\").innerHTML=selections[\"curr_pos\"];return selections;};EA.Ä.getIESelection=Ã(){var range=document.selection.createRange();var stored_range=range.duplicate();stored_range.moveToElementText(Á.Â );stored_range.setEndPoint('EndToEnd',range );if(stored_range.ÈElement()!=Á.Â)return;var scrollTop=Á.result.scrollTop+document.body.scrollTop;var relative_top=range.offsetTop-È.calculeOffsetTop(Á.Â)+scrollTop;var line_start=Math.round((relative_top / Á.lineHeight)+1);var line_nb=Math.round(range.boundingHeight / Á.lineHeight);var range_start=stored_range.text.Æ-range.text.Æ;var tab=Á.Â.Ê.substr(0,range_start).split(\"\\n\");range_start+=(line_start-tab.Æ)*2;Á.Â.selectionStart=range_start;var range_end=Á.Â.selectionStart+range.text.Æ;tab=Á.Â.Ê.substr(0,range_start+range.text.Æ).split(\"\\n\");range_end+=(line_start+line_nb-1-tab.Æ)*2;Á.Â.selectionEnd=range_end;};EA.Ä.setIESelection=Ã(){var nbLineStart=Á.Â.Ê.substr(0,Á.Â.selectionStart).split(\"\\n\").Æ-1;var nbLineEnd=Á.Â.Ê.substr(0,Á.Â.selectionEnd).split(\"\\n\").Æ-1;var range=document.selection.createRange();range.moveToElementText(Á.Â );range.setEndPoint('EndToStart',range );range.moveStart('character',Á.Â.selectionStart-nbLineStart);range.moveEnd('character',Á.Â.selectionEnd-nbLineEnd-(Á.Â.selectionStart-nbLineStart));range.select();};EA.Ä.tab_selection=Ã(){if(Á.is_tabbing)return;Á.is_tabbing=Ë;if(Á.nav['isIE'])Á.getIESelection();var start=Á.Â.selectionStart;var end=Á.Â.selectionEnd;var insText=Á.Â.Ê.substring(start,end);var pos_start=start;var pos_end=end;if (insText.Æ==0){Á.Â.Ê=Á.Â.Ê.substr(0,start)+Á.tabulation+Á.Â.Ê.substr(end);pos_start=start+Á.tabulation.Æ;pos_end=pos_start;}\nelse{start=Math.max(0,Á.Â.Ê.substr(0,start).lastIndexOf(\"\\n\")+1);endText=Á.Â.Ê.substr(end);startText=Á.Â.Ê.substr(0,start);tmp=Á.Â.Ê.substring(start,end).split(\"\\n\");insText=Á.tabulation+tmp.join(\"\\n\"+Á.tabulation);Á.Â.Ê=startText+insText+endText;pos_start=start;pos_end=Á.Â.Ê.indexOf(\"\\n\",startText.Æ+insText.Æ);if(pos_end==-1)pos_end=Á.Â.Ê.Æ;}Á.Â.selectionStart=pos_start;Á.Â.selectionEnd=pos_end;if(Á.nav['isIE']){Á.setIESelection();setTimeout(\"eA.is_tabbing=Ì;\",100);}\nelse Á.is_tabbing=Ì;};EA.Ä.invert_tab_selection=Ã(){if(Á.is_tabbing)return;Á.is_tabbing=Ë;if(Á.nav['isIE'])Á.getIESelection();var start=Á.Â.selectionStart;var end=Á.Â.selectionEnd;var insText=Á.Â.Ê.substring(start,end);var pos_start=start;var pos_end=end;if (insText.Æ==0){if(Á.Â.Ê.substring(start-Á.tabulation.Æ,start)==Á.tabulation){Á.Â.Ê=Á.Â.Ê.substr(0,start-Á.tabulation.Æ)+Á.Â.Ê.substr(end);pos_start=Math.max(0,start-Á.tabulation.Æ);pos_end=pos_start;}}\nelse{start=Á.Â.Ê.substr(0,start).lastIndexOf(\"\\n\")+1;endText=Á.Â.Ê.substr(end);startText=Á.Â.Ê.substr(0,start);tmp=Á.Â.Ê.substring(start,end).split(\"\\n\");insText=\"\";for(i=0;i<tmp.Æ;i++){for(j=0;j<Á.tab_nb_char;j++){if(tmp[i].charAt(0)==\"\t\"){tmp[i]=tmp[i].substr(1);j=Á.tab_nb_char;}\nelse if(tmp[i].charAt(0)==\" \")tmp[i]=tmp[i].substr(1);}insText+=tmp[i];if(i<tmp.Æ-1)insText+=\"\\n\";}Á.Â.Ê=startText+insText+endText;pos_start=start;pos_end=Á.Â.Ê.indexOf(\"\\n\",startText.Æ+insText.Æ);if(pos_end==-1)pos_end=Á.Â.Ê.Æ;}Á.Â.selectionStart=pos_start;Á.Â.selectionEnd=pos_end;if(Á.nav['isIE']){Á.setIESelection();setTimeout(\"eA.is_tabbing=Ì;\",100);}\nelse Á.is_tabbing=Ì;};EA.Ä.press_enter=Ã(){if(!Á.smooth_selection)return Ì;if(Á.nav['isIE'])Á.getIESelection();var scrollTop=Á.result.scrollTop;var scrollLeft=Á.result.scrollLeft;var start=Á.Â.selectionStart;var end=Á.Â.selectionEnd;var start_last_line=Math.max(0,Á.Â.Ê.substring(0,start).lastIndexOf(\"\\n\")+1 );var begin_line=Á.Â.Ê.substring(start_last_line,start).replace(/^([ \t]*).*/gm,\"$1\");if(begin_line==\"\\n\"||begin_line==\"\\r\"||begin_line.Æ==0)return Ì;if(Á.nav['isIE']||Á.nav['isOpera']){begin_line=\"\\r\\n\"+begin_line;}\nelse{begin_line=\"\\n\"+begin_line;}Á.Â.Ê=Á.Â.Ê.substring(0,start)+begin_line+Á.Â.Ê.substring(end);Á.area_select(start+begin_line.Æ ,0);if(Á.nav['isIE']){Á.result.scrollTop=scrollTop;Á.result.scrollLeft=scrollLeft;}return Ë;};EA.Ä.findEndBracket=Ã(infos,bracket){var start=infos[\"indexOfCursor\"];var normal_order=Ë;if(Á.assocBracket[bracket])endBracket=Á.assocBracket[bracket];\nelse if(Á.revertAssocBracket[bracket]){endBracket=Á.revertAssocBracket[bracket];normal_order=Ì;}var end=-1;var nbBracketOpen=0;for(var i=start;i<infos[\"full_text\"].Æ&&i>=0;){if(infos[\"full_text\"].charAt(i)==endBracket){nbBracketOpen--;if(nbBracketOpen<=0){end=i;break;}}\nelse if(infos[\"full_text\"].charAt(i)==bracket)nbBracketOpen++;if(normal_order)i++;\nelse i--;}if(end==-1)return Ì;var endLastLine=infos[\"full_text\"].substr(0,end).lastIndexOf(\"\\n\");if(endLastLine==-1)line=1;\nelse line=infos[\"full_text\"].substr(0,endLastLine).split(\"\\n\").Æ+1;var curPos=end-endLastLine;Á.displayToCursorPosition(\"end_bracket\",line,curPos,infos[\"full_text\"].substring(endLastLine +1,end));return Ë;};EA.Ä.displayToCursorPosition=Ã(id,start_line,cur_pos,lineContent,no_real_move){var elem=$(\"test_font_size\");var dest=$(id);var postLeft=0;elem.innerHTML=\"<pre><span id='test_font_size_inner'>\"+lineContent.substr(0,cur_pos).replace(/&/g,\"&amp;\").replace(/</g,\"&lt;\")+\"</span></pre>\";posLeft=45+$('test_font_size_inner').offsetWidth;var posTop=Á.lineHeight * (start_line-1);if(no_real_move!=Ë){dest.Ç.top=posTop+\"px\";dest.Ç.left=posLeft+\"px\";}dest.cursor_top=posTop;dest.cursor_left=posLeft;};EA.Ä.area_select=Ã(start,Æ){Á.Â.focus();start=Math.max(0,Math.min(Á.Â.Ê.Æ,start));end=Math.max(start,Math.min(Á.Â.Ê.Æ,start+Æ));if(Á.nav['isIE']){Á.Â.selectionStart=start;Á.Â.selectionEnd=end;Á.setIESelection();}\nelse{if(Á.nav['isOpera']){Á.Â.setSelectionRange(0,0);}Á.Â.setSelectionRange(start,end);}Á.check_line_selection();};EA.Ä.area_get_selection=Ã(){var text=\"\";if(document.selection ){var range=document.selection.createRange();text=range.text;}\nelse{text=Á.Â.Ê.substring(Á.Â.selectionStart,Á.Â.selectionEnd);}return text;}; EA.Ä.replace_tab=Ã(text){return text.replace(/((\\n?)([^\t\\n]*)\t)/gi,eA.smartTab);};EA.Ä.smartTab=Ã(){val=\"                   \";return EA.Ä.smartTab.arguments[2]+EA.Ä.smartTab.arguments[3]+val.substr(0,eA.tab_nb_char-(EA.Ä.smartTab.arguments[3].Æ)%eA.tab_nb_char);};EA.Ä.show_waiting_screen=Ã(){width=Á.editor_area.offsetWidth;height=Á.editor_area.offsetHeight;if(Á.nav['isGecko']||Á.nav['isOpera']||Á.nav['isIE']>=7){width-=2;height-=2;}Á.processing_screen.Ç.display=\"block\";Á.processing_screen.Ç.width=width+\"px\";Á.processing_screen.Ç.height=height+\"px\";Á.waiting_screen_displayed=Ë;};EA.Ä.hide_waiting_screen=Ã(){Á.processing_screen.Ç.display=\"none\";Á.waiting_screen_displayed=Ì;};EA.Ä.add_Ç=Ã(Çs){if(Çs.Æ>0){newcss=document.createElement(\"Ç\");newcss.type=\"text/css\";newcss.media=\"all\";document.getElementsByTagName(\"head\")[0].appendChild(newcss);cssrules=Çs.split(\"}\");newcss=document.ÇSheets[0];if(newcss.rules){for(i=cssrules.Æ-2;i>=0;i--){newrule=cssrules[i].split(\"{\");newcss.addRule(newrule[0],newrule[1])}}\nelse if(newcss.cssRules){for(i=cssrules.Æ-1;i>=0;i--){if(cssrules[i].indexOf(\"{\")!=-1){newcss.insertRule(cssrules[i]+\"}\",0);}}}}};EA.Ä.set_font=Ã(family,size){var elems=new Array(\"Â\",\"content_highlight\",\"cursor_pos\",\"end_bracket\",\"selection_field\",\"line_number\");if(family&&family!=\"\")Á.Å[\"font_family\"]=family;if(size&&size>0)Á.Å[\"font_size\"]=size;if(Á.nav['isOpera'])Á.Å['font_family']=\"monospace\";var elem_font=$(\"area_font_size\");if(elem_font){for(var i=0;i<elem_font.Æ;i++){if(elem_font.options[i].Ê&&elem_font.options[i].Ê==Á.Å[\"font_size\"])elem_font.options[i].selected=Ë;}}elem=$(\"test_font_size\");elem.Ç.fontFamily=\"\"+Á.Å[\"font_family\"];elem.Ç.fontSize=Á.Å[\"font_size\"]+\"pt\";elem.innerHTML=\"0\";Á.lineHeight=elem.offsetHeight;for(var i=0;i<elems.Æ;i++){var elem=$(elems[i]);elem.Ç.fontFamily=Á.Å[\"font_family\"];elem.Ç.fontSize=Á.Å[\"font_size\"]+\"pt\";elem.Ç.lineHeight=Á.lineHeight+\"px\";}if(Á.nav['isOpera']){var start=Á.Â.selectionStart;var end=Á.Â.selectionEnd;var parNod=Á.Â.ÈNode,nxtSib=Á.Â.nextSibling;parNod.removeChild(Á.Â);parNod.insertBefore(Á.Â,nxtSib);Á.area_select(start,end-start);}Á.add_Ç(\"pre{font-family:\"+Á.Å[\"font_family\"]+\"}\");Á.last_line_selected=-1;Á.É=new Array();Á.resync_highlight();};EA.Ä.change_font_size=Ã(){var size=$(\"area_font_size\").Ê;if(size>0)Á.set_font(\"\",size);};EA.Ä.open_inline_popup=Ã(popup_id){Á.close_all_inline_popup();var popup=$(popup_id);var editor=$(\"editor\");for(var i=0;i<Á.inlinePopup.Æ;i++){if(Á.inlinePopup[i][\"popup_id\"]==popup_id){var icon=$(Á.inlinePopup[i][\"icon_id\"]);if(icon){Á.switchClassSticky(icon,'editAreaButtonSelected',Ë);break;}}}popup.Ç.height=\"auto\";popup.Ç.overflow=\"visible\";if(document.body.offsetHeight< popup.offsetHeight){popup.Ç.height=(document.body.offsetHeight-10)+\"px\";popup.Ç.overflow=\"auto\";}if(!popup.positionned){var new_left=editor.offsetWidth /2-popup.offsetWidth /2;var new_top=editor.offsetHeight /2-popup.offsetHeight /2;popup.Ç.left=new_left+\"px\";popup.Ç.top=new_top+\"px\";popup.positionned=Ë;}popup.Ç.visibility=\"visible\";};EA.Ä.close_inline_popup=Ã(popup_id){var popup=$(popup_id);for(var i=0;i<Á.inlinePopup.Æ;i++){if(Á.inlinePopup[i][\"popup_id\"]==popup_id){var icon=$(Á.inlinePopup[i][\"icon_id\"]);if(icon){Á.switchClassSticky(icon,'editAreaButtonNormal',Ì);break;}}}popup.Ç.visibility=\"hidden\";};EA.Ä.close_all_inline_popup=Ã(e){for(var i=0;i<Á.inlinePopup.Æ;i++){Á.close_inline_popup(Á.inlinePopup[i][\"popup_id\"]);}Á.Â.focus();};EA.Ä.show_help=Ã(){Á.open_inline_popup(\"edit_area_help\");};EA.Ä.new_document=Ã(){Á.Â.Ê=\"\";Á.area_select(0,0);};EA.Ä.get_all_toolbar_height=Ã(){var area=$(\"editor\");var results=È.getChildren(area,\"div\",\"class\",\"area_toolbar\",\"all\",\"0\");var height=0;for(var i=0;i<results.Æ;i++){height+=results[i].offsetHeight;}return height;};EA.Ä.go_to_line=Ã(line){if(!line){var icon=$(\"go_to_line\");if(icon !=null){Á.restoreClass(icon);Á.switchClassSticky(icon,'editAreaButtonSelected',Ë);}line=prompt(Á.get_translation(\"go_to_line_prompt\"));if(icon !=null)Á.switchClassSticky(icon,'editAreaButtonNormal',Ì);}if(line&&line!=null&&line.search(/^[0-9]+$/)!=-1){var start=0;var lines=Á.Â.Ê.split(\"\\n\");if(line > lines.Æ)start=Á.Â.Ê.Æ;\nelse{for(var i=0;i<Math.min(line-1,lines.Æ);i++)start+=lines[i].Æ+1;}Á.area_select(start,0);}};EA.Ä.change_smooth_selection_mode=Ã(setTo){if(Á.do_highlight)return;if(setTo !=null){if(setTo ===Ì)Á.smooth_selection=Ë;\nelse Á.smooth_selection=Ì;}var icon=$(\"change_smooth_selection\");Á.Â.focus();if(Á.smooth_selection===Ë){Á.switchClassSticky(icon,'editAreaButtonNormal',Ì);Á.smooth_selection=Ì;Á.selection_field.Ç.display=\"none\";$(\"cursor_pos\").Ç.display=\"none\";$(\"end_bracket\").Ç.display=\"none\";}\nelse{Á.switchClassSticky(icon,'editAreaButtonSelected',Ì);Á.smooth_selection=Ë;Á.selection_field.Ç.display=\"block\";$(\"cursor_pos\").Ç.display=\"block\";$(\"end_bracket\").Ç.display=\"block\";}};EA.Ä.scroll_to_view=Ã(show){if(!Á.smooth_selection)return;var zone=$(\"result\");var cursor_pos_top=$(\"cursor_pos\").cursor_top;if(show==\"bottom\")cursor_pos_top+=(Á.É[\"line_nb\"]-1)* Á.lineHeight;var max_height_visible=zone.clientHeight+zone.scrollTop;var miss_top=cursor_pos_top+Á.lineHeight-max_height_visible;if(miss_top>0){zone.scrollTop=zone.scrollTop+miss_top;}\nelse if(zone.scrollTop > cursor_pos_top){zone.scrollTop=cursor_pos_top;}var cursor_pos_left=$(\"cursor_pos\").cursor_left;var max_width_visible=zone.clientWidth+zone.scrollLeft;var miss_left=cursor_pos_left+10-max_width_visible;if(miss_left>0){zone.scrollLeft=zone.scrollLeft+miss_left+50;}\nelse if(zone.scrollLeft > cursor_pos_left){zone.scrollLeft=cursor_pos_left;}\nelse if(zone.scrollLeft==45){zone.scrollLeft=0;}};EA.Ä.check_undo=Ã(only_once){if(!eAs[Á.id])return Ì;if(Á.ÂFocused&&eAs[Á.id][\"displayed\"]==Ë){var text=Á.Â.Ê;if(Á.previous.Æ<=1)Á.switchClassSticky($(\"undo\"),'editAreaButtonDisabled',Ë);if(!Á.previous[Á.previous.Æ-1]||Á.previous[Á.previous.Æ-1][\"text\"] !=text){Á.previous.push({\"text\":text,\"selStart\":Á.Â.selectionStart,\"selEnd\":Á.Â.selectionEnd});if(Á.previous.Æ > Á.Å[\"max_undo\"]+1)Á.previous.shift();}if(Á.previous.Æ >=2)Á.switchClassSticky($(\"undo\"),'editAreaButtonNormal',Ì);}if(!only_once)setTimeout(\"eA.check_undo()\",3000);};EA.Ä.undo=Ã(){if(Á.previous.Æ > 0){if(Á.nav['isIE'])Á.getIESelection();Á.next.push({\"text\":Á.Â.Ê,\"selStart\":Á.Â.selectionStart,\"selEnd\":Á.Â.selectionEnd});var prev=Á.previous.pop();if(prev[\"text\"]==Á.Â.Ê&&Á.previous.Æ > 0)prev=Á.previous.pop();Á.Â.Ê=prev[\"text\"];Á.last_undo=prev[\"text\"];Á.area_select(prev[\"selStart\"],prev[\"selEnd\"]-prev[\"selStart\"]);Á.switchClassSticky($(\"redo\"),'editAreaButtonNormal',Ì);Á.resync_highlight(Ë);Á.check_file_changes();}};EA.Ä.redo=Ã(){if(Á.next.Æ > 0){var next=Á.next.pop();Á.previous.push(next);Á.Â.Ê=next[\"text\"];Á.last_undo=next[\"text\"];Á.area_select(next[\"selStart\"],next[\"selEnd\"]-next[\"selStart\"]);Á.switchClassSticky($(\"undo\"),'editAreaButtonNormal',Ì);Á.resync_highlight(Ë);Á.check_file_changes();}if(Á.next.Æ==0)Á.switchClassSticky($(\"redo\"),'editAreaButtonDisabled',Ë);};EA.Ä.check_redo=Ã(){if(eA.next.Æ==0||eA.Â.Ê!=eA.last_undo){eA.next=new Array();eA.switchClassSticky($(\"redo\"),'editAreaButtonDisabled',Ë);}\nelse{Á.switchClassSticky($(\"redo\"),'editAreaButtonNormal',Ì);}};EA.Ä.switchClass=Ã(element,class_name,lock_state){var lockChanged=Ì;if (typeof(lock_state)!=\"undefined\"&&element !=null){element.classLock=lock_state;lockChanged=Ë;}if (element !=null&&(lockChanged||!element.classLock)){element.oldClassName=element.className;element.className=class_name;}};EA.Ä.restoreAndSwitchClass=Ã(element,class_name){if (element !=null&&!element.classLock){Á.restoreClass(element);Á.switchClass(element,class_name);}};EA.Ä.restoreClass=Ã(element){if (element !=null&&element.oldClassName&&!element.classLock){element.className=element.oldClassName;element.oldClassName=null;}};EA.Ä.setClassLock=Ã(element,lock_state){if (element !=null)element.classLock=lock_state;};EA.Ä.switchClassSticky=Ã(element,class_name,lock_state){var lockChanged=Ì;if (typeof(lock_state)!=\"undefined\"&&element !=null){element.classLock=lock_state;lockChanged=Ë;}if (element !=null&&(lockChanged||!element.classLock)){element.className=class_name;element.oldClassName=class_name;}};EA.Ä.scroll_page=Ã(params){var dir=params[\"dir\"];var shift_pressed=params[\"shift\"];screen_height=$(\"result\").clientHeight;var lines=Á.Â.Ê.split(\"\\n\");var new_pos=0;var Æ=0;var char_left=0;var line_nb=0;if(dir==\"up\"){var scroll_line=Math.ceil((screen_height -30)/Á.lineHeight);if(Á.É[\"selec_direction\"]==\"up\"){for(line_nb=0;line_nb< Math.min(Á.É[\"line_start\"]-scroll_line,lines.Æ);line_nb++){new_pos+=lines[line_nb].Æ+1;}char_left=Math.min(lines[Math.min(lines.Æ-1,line_nb)].Æ,Á.É[\"curr_pos\"]-1);if(shift_pressed)Æ=Á.É[\"selectionEnd\"]-new_pos-char_left;Á.area_select(new_pos+char_left,Æ);view=\"top\";}\nelse{view=\"bottom\";for(line_nb=0;line_nb< Math.min(Á.É[\"line_start\"]+Á.É[\"line_nb\"]-1-scroll_line,lines.Æ);line_nb++){new_pos+=lines[line_nb].Æ+1;}char_left=Math.min(lines[Math.min(lines.Æ-1,line_nb)].Æ,Á.É[\"curr_pos\"]-1);if(shift_pressed){start=Math.min(Á.É[\"selectionStart\"],new_pos+char_left);Æ=Math.max(new_pos+char_left,Á.É[\"selectionStart\"] )-start;if(new_pos+char_left < Á.É[\"selectionStart\"])view=\"top\";}\nelse start=new_pos+char_left;Á.area_select(start,Æ);}}\nelse{var scroll_line=Math.floor((screen_height-30)/Á.lineHeight);if(Á.É[\"selec_direction\"]==\"down\"){view=\"bottom\";for(line_nb=0;line_nb< Math.min(Á.É[\"line_start\"]+Á.É[\"line_nb\"]-2+scroll_line,lines.Æ);line_nb++){if(line_nb==Á.É[\"line_start\"]-1)char_left=Á.É[\"selectionStart\"] -new_pos;new_pos+=lines[line_nb].Æ+1;}if(shift_pressed){Æ=Math.abs(Á.É[\"selectionStart\"]-new_pos);Æ+=Math.min(lines[Math.min(lines.Æ-1,line_nb)].Æ,Á.É[\"curr_pos\"]);Á.area_select(Math.min(Á.É[\"selectionStart\"],new_pos),Æ);}\nelse{Á.area_select(new_pos+char_left,0);}}\nelse{view=\"top\";for(line_nb=0;line_nb< Math.min(Á.É[\"line_start\"]+scroll_line-1,lines.Æ,lines.Æ);line_nb++){if(line_nb==Á.É[\"line_start\"]-1)char_left=Á.É[\"selectionStart\"] -new_pos;new_pos+=lines[line_nb].Æ+1;}if(shift_pressed){Æ=Math.abs(Á.É[\"selectionEnd\"]-new_pos-char_left);Æ+=Math.min(lines[Math.min(lines.Æ-1,line_nb)].Æ,Á.É[\"curr_pos\"])-char_left-1;Á.area_select(Math.min(Á.É[\"selectionEnd\"],new_pos+char_left),Æ);if(new_pos+char_left > Á.É[\"selectionEnd\"])view=\"bottom\";}\nelse{Á.area_select(new_pos+char_left,0);}}}Á.check_line_selection();Á.scroll_to_view(view);};EA.Ä.start_resize=Ã(e){È.eAL.resize[\"id\"]=eA.id;È.eAL.resize[\"start_x\"]=(e)? e.pageX:event.x+document.body.scrollLeft;È.eAL.resize[\"start_y\"]=(e)? e.pageY:event.y+document.body.scrollTop;if(eA.nav['isIE']){eA.Â.focus();eA.getIESelection();}È.eAL.resize[\"selectionStart\"]=eA.Â.selectionStart;È.eAL.resize[\"selectionEnd\"]=eA.Â.selectionEnd;È.eAL.start_resize_area();};EA.Ä.toggle_full_screen=Ã(to){if(typeof(to)==\"undefined\")to=!Á.fullscreen['isFull'];var old=Á.fullscreen['isFull'];Á.fullscreen['isFull']=to;var icon=$(\"fullscreen\");if(to&&to!=old){var selStart=Á.Â.selectionStart;var selEnd=Á.Â.selectionEnd;var html=È.document.getElementsByTagName(\"html\")[0];var frame=È.document.getElementById(\"frame_\"+Á.id);Á.fullscreen['old_overflow']=È.get_css_property(html,\"overflow\");Á.fullscreen['old_height']=È.get_css_property(html,\"height\");Á.fullscreen['old_width']=È.get_css_property(html,\"width\");Á.fullscreen['old_scrollTop']=html.scrollTop;Á.fullscreen['old_scrollLeft']=html.scrollLeft;Á.fullscreen['old_zIndex']=È.get_css_property(frame,\"z-index\");if(Á.nav['isOpera']){html.Ç.height=\"100%\";html.Ç.width=\"100%\";}html.Ç.overflow=\"hidden\";html.scrollTop=0;html.scrollLeft=0;frame.Ç.position=\"absolute\";frame.Ç.width=html.clientWidth+\"px\";frame.Ç.height=html.clientHeight+\"px\";frame.Ç.display=\"block\";frame.Ç.zIndex=\"999999\";frame.Ç.top=\"0px\";frame.Ç.left=\"0px\";frame.Ç.top=\"-\"+È.calculeOffsetTop(frame)+\"px\";frame.Ç.left=\"-\"+È.calculeOffsetLeft(frame)+\"px\";Á.switchClassSticky(icon,'editAreaButtonSelected',Ì);Á.fullscreen['allow_resize']=Á.resize_allowed;Á.allow_resize(Ì);if(Á.nav['isFirefox']){È.eAL.execCommand(Á.id,\"update_size();\");Á.area_select(selStart,selEnd-selStart);Á.scroll_to_view();Á.focus();}\nelse{setTimeout(\"È.eAL.execCommand('\"+Á.id +\"','update_size();');eA.focus();\",10);}}\nelse if(to!=old){var selStart=Á.Â.selectionStart;var selEnd=Á.Â.selectionEnd;var frame=È.document.getElementById(\"frame_\"+Á.id);frame.Ç.position=\"static\";frame.Ç.zIndex=Á.fullscreen['old_zIndex'];var html=È.document.getElementsByTagName(\"html\")[0];if(Á.nav['isOpera']){html.Ç.height=\"auto\";html.Ç.width=\"auto\";html.Ç.overflow=\"auto\";}\nelse if(Á.nav['isIE']&&È!=top){html.Ç.overflow=\"auto\";}\nelse html.Ç.overflow=Á.fullscreen['old_overflow'];html.scrollTop=Á.fullscreen['old_scrollTop'];html.scrollTop=Á.fullscreen['old_scrollLeft'];È.eAL.hide(Á.id);È.eAL.show(Á.id);Á.switchClassSticky(icon,'editAreaButtonNormal',Ì);if(Á.fullscreen['allow_resize'])Á.allow_resize(Á.fullscreen['allow_resize']);if(Á.nav['isFirefox']){Á.area_select(selStart,selEnd-selStart);setTimeout(\"eA.scroll_to_view();\",10);}}};EA.Ä.allow_resize=Ã(allow){var resize=$(\"resize_area\");if(allow){resize.Ç.visibility=\"visible\";È.eAL.add_event(resize,\"mouseup\",eA.start_resize);}\nelse{resize.Ç.visibility=\"hidden\";È.eAL.remove_event(resize,\"mouseup\",eA.start_resize);}Á.resize_allowed=allow;};EA.Ä.change_syntax=Ã(new_syntax,is_waiting){if(new_syntax==Á.Å['syntax'])return Ë;var founded=Ì;for(var i=0;i<Á.syntax_list.Æ;i++){if(Á.syntax_list[i]==new_syntax)founded=Ë;}if(founded==Ë){if(!È.eAL.load_syntax[new_syntax]){if(!is_waiting)È.eAL.load_script(È.eAL.baseURL+\"reg_syntax/\"+new_syntax+\".js\");setTimeout(\"eA.change_syntax('\"+new_syntax +\"',Ë);\",100);Á.show_waiting_screen();}\nelse{if(!Á.allready_used_syntax[new_syntax]){È.eAL.init_syntax_regexp();Á.add_Ç(È.eAL.syntax[new_syntax][\"Çs\"]);Á.allready_used_syntax[new_syntax]=Ë;}var sel=$(\"syntax_selection\");if(sel&&sel.Ê!=new_syntax){for(var i=0;i<sel.Æ;i++){if(sel.options[i].Ê&&sel.options[i].Ê==new_syntax)sel.options[i].selected=Ë;}}Á.Å['syntax']=new_syntax;Á.resync_highlight(Ë);Á.hide_waiting_screen();return Ë;}}return Ì;};EA.Ä.set_editable=Ã(is_editable){if(is_editable){document.body.className=\"\";Á.Â.readOnly=Ì;Á.is_editable=Ë;}\nelse{document.body.className=\"non_editable\";Á.Â.readOnly=Ë;Á.is_editable=Ì;}if(eAs[Á.id][\"displayed\"]==Ë)Á.update_size();};EA.Ä.set_wrap_text=Ã(to){Á.Å['wrap_text']=to;if(Á.Å['wrap_text']){wrap_mode='soft';Á.container.className+=' wrap_text';}\nelse{wrap_mode='off';Á.container.className=Á.container.className.replace(/ wrap_text/g,'');}var t=Á.Â;t.wrap=wrap_mode;t.setAttribute('wrap',wrap_mode);if(!Á.nav['isIE']){var start=t.selectionStart,end=t.selectionEnd;var parNod=t.ÈNode,nxtSib=t.nextSibling;parNod.removeChild(t);parNod.insertBefore(t,nxtSib);Á.area_select(start,end-start);}};EA.Ä.open_file=Ã(Å){if(Å['id']!=\"undefined\"){var id=Å['id'];var new_file=new Object();new_file['id']=id;new_file['title']=id;new_file['text']=\"\";new_file['É']=\"\";new_file['last_text_to_highlight']=\"\";new_file['last_hightlighted_text']=\"\";new_file['previous']=new Array();new_file['next']=new Array();new_file['last_undo']=\"\";new_file['smooth_selection']=Á.Å['smooth_selection'];new_file['do_highlight']=Á.Å['start_highlight'];new_file['syntax']=Á.Å['syntax'];new_file['scroll_top']=0;new_file['scroll_left']=0;new_file['selection_start']=0;new_file['selection_end']=0;new_file['edited']=Ì;new_file['font_size']=Á.Å[\"font_size\"];new_file['font_family']=Á.Å[\"font_family\"];new_file['toolbar']={'links':{},'selects':{}};new_file['compare_edited_text']=new_file['text'];Á.files[id]=new_file;Á.update_file(id,Å);Á.files[id]['compare_edited_text']=Á.files[id]['text'];var html_id='tab_file_'+encodeURIComponent(id);Á.filesIdAssoc[html_id]=id;Á.files[id]['html_id']=html_id;if(!$(Á.files[id]['html_id'])&&id!=\"\"){Á.tab_browsing_area.Ç.display=\"block\";var elem=document.createElement('li');elem.id=Á.files[id]['html_id'];var close=\"<img src=\\\"\"+È.eAL.baseURL +\"images/close.gif\\\" title=\\\"\"+Á.get_translation('close_tab','word')+\"\\\" onclick=\\\"eA.execCommand('close_file',eA.filesIdAssoc['\"+html_id +\"']);return Ì;\\\" class=\\\"hidden\\\" onmouseover=\\\"Á.className=''\\\" onmouseout=\\\"Á.className='hidden'\\\" />\";elem.innerHTML=\"<a onclick=\\\"javascript:eA.execCommand('switch_to_file',eA.filesIdAssoc['\"+html_id +\"']);\\\" selec=\\\"none\\\"><b><span><strong class=\\\"edited\\\">*</strong>\"+Á.files[id]['title']+close +\"</span></b></a>\";$('tab_browsing_list').appendChild(elem);var elem=document.createElement('text');Á.update_size();}if(id!=\"\")Á.execCommand('file_open',Á.files[id]);Á.switch_to_file(id,Ë);return Ë;}\nelse return Ì;};EA.Ä.close_file=Ã(id){if(Á.files[id]){Á.save_file(id);if(Á.execCommand('file_close',Á.files[id])!==Ì){var li=$(Á.files[id]['html_id']);li.ÈNode.removeChild(li);if(id==Á.curr_file){var next_file=\"\";var is_next=Ì;for(var i in Á.files){if(is_next){next_file=i;break;}\nelse if(i==id)is_next=Ë;\nelse next_file=i;}Á.switch_to_file(next_file);}delete (Á.files[id]);Á.update_size();}}};EA.Ä.save_file=Ã(id){if(Á.files[id]){var save=Á.files[id];save['É']=Á.É;save['last_text_to_highlight']=Á.last_text_to_highlight;save['last_hightlighted_text']=Á.last_hightlighted_text;save['previous']=Á.previous;save['next']=Á.next;save['last_undo']=Á.last_undo;save['smooth_selection']=Á.smooth_selection;save['do_highlight']=Á.do_highlight;save['syntax']=Á.Å['syntax'];save['text']=Á.Â.Ê;save['scroll_top']=Á.result.scrollTop;save['scroll_left']=Á.result.scrollLeft;save['selection_start']=Á.É[\"selectionStart\"];save['selection_end']=Á.É[\"selectionEnd\"];save['font_size']=Á.Å[\"font_size\"];save['font_family']=Á.Å[\"font_family\"];save['toolbar']={'links':{},'selects':{}};var links=$(\"toolbar_1\").getElementsByTagName(\"a\");for(var i=0;i<links.Æ;i++){if(links[i].getAttribute('fileSpecific')=='yes'){var save_butt=new Object();var img=links[i].getElementsByTagName('img')[0];save_butt['classLock']=img.classLock;save_butt['className']=img.className;save_butt['oldClassName']=img.oldClassName;save['toolbar']['links'][links[i].id]=save_butt;}}var selects=$(\"toolbar_1\").getElementsByTagName(\"select\");for(var i=0;i<selects.Æ;i++){if(selects[i].getAttribute('fileSpecific')=='yes'){save['toolbar']['selects'][selects[i].id]=selects[i].Ê;}}Á.files[id]=save;return save;}\nelse return Ì;};EA.Ä.update_file=Ã(id,new_Ês){for(var i in new_Ês){Á.files[id][i]=new_Ês[i];}};EA.Ä.display_file=Ã(id){if(id==''){Á.Â.readOnly=Ë;Á.tab_browsing_area.Ç.display=\"none\";$(\"no_file_selected\").Ç.display=\"block\";Á.result.className=\"empty\";if(!Á.files[''])Á.open_file({id:''});}\nelse{Á.result.className=\"\";Á.Â.readOnly=!Á.is_editable;$(\"no_file_selected\").Ç.display=\"none\";Á.tab_browsing_area.Ç.display=\"block\";}Á.check_redo(Ë);Á.check_undo(Ë);Á.curr_file=id;var lis=Á.tab_browsing_area.getElementsByTagName('li');for(var i=0;i<lis.Æ;i++){if(lis[i].id==Á.files[id]['html_id'])lis[i].className='selected';\nelse lis[i].className='';}var new_file=Á.files[id];Á.Â.Ê=new_file['text'];Á.set_font(new_file['font_family'],new_file['font_size']);Á.area_select(new_file['É']['selection_start'],new_file['É']['selection_end']-new_file['É']['selection_start']);Á.manage_size(Ë);Á.result.scrollTop=new_file['scroll_top'];Á.result.scrollLeft=new_file['scroll_left'];Á.previous=new_file['previous'];Á.next=new_file['next'];Á.last_undo=new_file['last_undo'];Á.check_redo(Ë);Á.check_undo(Ë);Á.execCommand(\"change_highlight\",new_file['do_highlight']);Á.execCommand(\"change_syntax\",new_file['syntax']);Á.execCommand(\"change_smooth_selection_mode\",new_file['smooth_selection']);var links=new_file['toolbar']['links'];for(var i in links){if(img=$(i).getElementsByTagName('img')[0]){var save_butt=new Object();img.classLock=links[i]['classLock'];img.className=links[i]['className'];img.oldClassName=links[i]['oldClassName'];}}var selects=new_file['toolbar']['selects'];for(var i in selects){var options=$(i).options;for(var j=0;j<options.Æ;j++){if(options[j].Ê==selects[i])$(i).options[j].selected=Ë;}}};EA.Ä.switch_to_file=Ã(file_to_show,force_refresh){if(file_to_show!=Á.curr_file||force_refresh){Á.save_file(Á.curr_file);if(Á.curr_file!='')Á.execCommand('file_switch_off',Á.files[Á.curr_file]);Á.display_file(file_to_show);if(file_to_show!='')Á.execCommand('file_switch_on',Á.files[file_to_show]);}};EA.Ä.get_file=Ã(id){if(id==Á.curr_file)Á.save_file(id);return Á.files[id];};EA.Ä.get_all_files=Ã(){tmp_files=Á.files;Á.save_file(Á.curr_file);if(tmp_files[''])delete(Á.files['']);return tmp_files;};EA.Ä.check_file_changes=Ã(){var id=Á.curr_file;if(Á.files[id]&&Á.files[id]['compare_edited_text']!=undefined){if(Á.files[id]['compare_edited_text'].Æ==Á.Â.Ê.Æ&&Á.files[id]['compare_edited_text']==Á.Â.Ê){if(Á.files[id]['edited']!=Ì)Á.set_file_edited_mode(id,Ì);}\nelse{if(Á.files[id]['edited']!=Ë)Á.set_file_edited_mode(id,Ë);}}};EA.Ä.set_file_edited_mode=Ã(id,to){if(Á.files[id]&&$(Á.files[id]['html_id'])){var link=$(Á.files[id]['html_id']).getElementsByTagName('a')[0];if(to==Ë){link.className='edited';}\nelse{link.className='';if(id==Á.curr_file)text=Á.Â.Ê;\nelse text=Á.files[id]['text'];Á.files[id]['compare_edited_text']=text;}Á.files[id]['edited']=to;}};EA.Ä.set_show_line_colors=Ã(new_Ê){Á.show_line_colors=new_Ê;if(new_Ê)Á.selection_field.className	+=' show_colors';\nelse Á.selection_field.className=Á.selection_field.className.replace(/ show_colors/g,'' );};var EA_keys={8:\"Retour arriere\",9:\"Tabulation\",12:\"Milieu (pave numerique)\",13:\"Entrer\",16:\"Shift\",17:\"Ctrl\",18:\"Alt\",19:\"Pause\",20:\"Verr Maj\",27:\"Esc\",32:\"Space\",33:\"Page up\",34:\"Page down\",35:\"End\",36:\"Begin\",37:\"Left\",38:\"Up\",39:\"Right\",40:\"Down\",44:\"Impr ecran\",45:\"Inser\",46:\"Suppr\",91:\"Menu Demarrer Windows / touche pomme Mac\",92:\"Menu Demarrer Windows\",93:\"Menu contextuel Windows\",112:\"F1\",113:\"F2\",114:\"F3\",115:\"F4\",116:\"F5\",117:\"F6\",118:\"F7\",119:\"F8\",120:\"F9\",121:\"F10\",122:\"F11\",123:\"F12\",144:\"Verr Num\",145:\"Arret defil\"};Ã keyDown(e){if(!e){e=event;}for(var i in eA.plugins){if(typeof(eA.plugins[i].onkeydown)==\"Ã\"){if(eA.plugins[i].onkeydown(e)===Ì){if(eA.nav['isIE'])e.keyCode=0;return Ì;}}}var target_id=(e.target||e.srcElement).id;var use=Ì;if (EA_keys[e.keyCode])letter=EA_keys[e.keyCode];\nelse letter=String.fromCharCode(e.keyCode);var low_letter=letter.toLowerCase();if(letter==\"Page up\"&&!eA.nav['isOpera']){eA.execCommand(\"scroll_page\",{\"dir\":\"up\",\"shift\":ShiftPressed(e)});use=Ë;}\nelse if(letter==\"Page down\"&&!eA.nav['isOpera']){eA.execCommand(\"scroll_page\",{\"dir\":\"down\",\"shift\":ShiftPressed(e)});use=Ë;}\nelse if(eA.is_editable==Ì){return Ë;}\nelse if(letter==\"Tabulation\"&&target_id==\"Â\"&&!CtrlPressed(e)&&!AltPressed(e)){if(ShiftPressed(e))eA.execCommand(\"invert_tab_selection\");\nelse eA.execCommand(\"tab_selection\");use=Ë;if(eA.nav['isOpera']||(eA.nav['isFirefox']&&eA.nav['isMacOS']))setTimeout(\"eA.execCommand('focus');\",1);}\nelse if(letter==\"Entrer\"&&target_id==\"Â\"){if(eA.press_enter())use=Ë;}\nelse if(letter==\"Entrer\"&&target_id==\"area_search\"){eA.execCommand(\"area_search\");use=Ë;}\nelse  if(letter==\"Esc\"){eA.execCommand(\"close_all_inline_popup\",e);use=Ë;}\nelse if(CtrlPressed(e)&&!AltPressed(e)&&!ShiftPressed(e)){switch(low_letter){case \"f\":eA.execCommand(\"area_search\");use=Ë;break;case \"r\":eA.execCommand(\"area_replace\");use=Ë;break;case \"q\":eA.execCommand(\"close_all_inline_popup\",e);use=Ë;break;case \"h\":eA.execCommand(\"change_highlight\");use=Ë;break;case \"g\":setTimeout(\"eA.execCommand('go_to_line');\",5);use=Ë;break;case \"e\":eA.execCommand(\"show_help\");use=Ë;break;case \"z\":use=Ë;eA.execCommand(\"undo\");break;case \"y\":use=Ë;eA.execCommand(\"redo\");break;default:break;}}if(eA.next.Æ > 0){setTimeout(\"eA.check_redo();\",10);}setTimeout(\"eA.check_file_changes();\",10);if(use){if(eA.nav['isIE'])e.keyCode=0;return Ì;}return Ë;};Ã AltPressed(e){if (window.event){return (window.event.altKey);}\nelse{if(e.modifiers)return (e.altKey||(e.modifiers % 2));\nelse return e.altKey;}};Ã CtrlPressed(e){if (window.event){return (window.event.ctrlKey);}\nelse{return (e.ctrlKey||(e.modifiers==2)||(e.modifiers==3)||(e.modifiers>5));}};Ã ShiftPressed(e){if (window.event){return (window.event.shiftKey);}\nelse{return (e.shiftKey||(e.modifiers>3));}};	EA.Ä.show_search=Ã(){if($(\"area_search_replace\").Ç.visibility==\"visible\"){Á.hidden_search();}\nelse{Á.open_inline_popup(\"area_search_replace\");var text=Á.area_get_selection();var search=text.split(\"\\n\")[0];$(\"area_search\").Ê=search;$(\"area_search\").focus();}};EA.Ä.hidden_search=Ã(){Á.close_inline_popup(\"area_search_replace\");};EA.Ä.area_search=Ã(mode){if(!mode)mode=\"search\";$(\"area_search_msg\").innerHTML=\"\";var search=$(\"area_search\").Ê;Á.Â.focus();Á.Â.ÂFocused=Ë;var infos=Á.get_selection_infos();var start=infos[\"selectionStart\"];var pos=-1;var pos_begin=-1;var Æ=search.Æ;if($(\"area_search_replace\").Ç.visibility!=\"visible\"){Á.show_search();return;}if(search.Æ==0){$(\"area_search_msg\").innerHTML=Á.get_translation(\"search_field_empty\");return;}if(mode!=\"replace\" ){if($(\"area_search_reg_exp\").checked)start++;\nelse start+=search.Æ;}if($(\"area_search_reg_exp\").checked){var opt=\"m\";if(!$(\"area_search_match_case\").checked)opt+=\"i\";var reg=new RegExp(search,opt);pos=infos[\"full_text\"].substr(start).search(reg);pos_begin=infos[\"full_text\"].search(reg);if(pos!=-1){pos+=start;Æ=infos[\"full_text\"].substr(start).match(reg)[0].Æ;}\nelse if(pos_begin!=-1){Æ=infos[\"full_text\"].match(reg)[0].Æ;}}\nelse{if($(\"area_search_match_case\").checked){pos=infos[\"full_text\"].indexOf(search,start);pos_begin=infos[\"full_text\"].indexOf(search);}\nelse{pos=infos[\"full_text\"].toLowerCase().indexOf(search.toLowerCase(),start);pos_begin=infos[\"full_text\"].toLowerCase().indexOf(search.toLowerCase());}}if(pos==-1&&pos_begin==-1){$(\"area_search_msg\").innerHTML=\"<strong>\"+search+\"</strong> \"+Á.get_translation(\"not_found\");return;}\nelse if(pos==-1&&pos_begin !=-1){begin=pos_begin;$(\"area_search_msg\").innerHTML=Á.get_translation(\"restart_search_at_begin\");}\nelse begin=pos;if(mode==\"replace\"&&pos==infos[\"indexOfCursor\"]){var replace=$(\"area_replace\").Ê;var new_text=\"\";if($(\"area_search_reg_exp\").checked){var opt=\"m\";if(!$(\"area_search_match_case\").checked)opt+=\"i\";var reg=new RegExp(search,opt);new_text=infos[\"full_text\"].substr(0,begin)+infos[\"full_text\"].substr(start).replace(reg,replace);}\nelse{new_text=infos[\"full_text\"].substr(0,begin)+replace+infos[\"full_text\"].substr(begin+Æ);}Á.Â.Ê=new_text;Á.area_select(begin,Æ);Á.area_search();}\nelse Á.area_select(begin,Æ);};EA.Ä.area_replace=Ã(){Á.area_search(\"replace\");};EA.Ä.area_replace_all=Ã(){var base_text=Á.Â.Ê;var search=$(\"area_search\").Ê;var replace=$(\"area_replace\").Ê;if(search.Æ==0){$(\"area_search_msg\").innerHTML=Á.get_translation(\"search_field_empty\");return;}var new_text=\"\";var nb_change=0;if($(\"area_search_reg_exp\").checked){var opt=\"mg\";if(!$(\"area_search_match_case\").checked)opt+=\"i\";var reg=new RegExp(search,opt);nb_change=infos[\"full_text\"].match(reg).Æ;new_text=infos[\"full_text\"].replace(reg,replace);}\nelse{if($(\"area_search_match_case\").checked){var tmp_tab=base_text.split(search);nb_change=tmp_tab.Æ -1;new_text=tmp_tab.join(replace);}\nelse{var lower_Ê=base_text.toLowerCase();var lower_search=search.toLowerCase();var start=0;var pos=lower_Ê.indexOf(lower_search);while(pos!=-1){nb_change++;new_text+=Á.Â.Ê.substring(start,pos)+replace;start=pos+search.Æ;pos=lower_Ê.indexOf(lower_search,pos+1);}new_text+=Á.Â.Ê.substring(start);}}if(new_text==base_text){$(\"area_search_msg\").innerHTML=\"<strong>\"+search+\"</strong> \"+Á.get_translation(\"not_found\");}\nelse{Á.Â.Ê=new_text;$(\"area_search_msg\").innerHTML=\"<strong>\"+nb_change+\"</strong> \"+Á.get_translation(\"occurrence_replaced\");setTimeout(\"eA.Â.focus();eA.Â.ÂFocused=Ë;\",100);}}; EA.Ä.change_highlight=Ã(change_to){if(Á.Å[\"syntax\"].Æ==0&&change_to==Ì){Á.switchClassSticky($(\"highlight\"),'editAreaButtonDisabled',Ë);Á.switchClassSticky($(\"reset_highlight\"),'editAreaButtonDisabled',Ë);return Ì;}if(Á.do_highlight==change_to)return Ì;if(Á.nav['isIE'])Á.getIESelection();var pos_start=Á.Â.selectionStart;var pos_end=Á.Â.selectionEnd;if(Á.do_highlight===Ë||change_to==Ì)Á.disable_highlight();\nelse Á.enable_highlight();Á.Â.focus();Á.Â.selectionStart=pos_start;Á.Â.selectionEnd=pos_end;if(Á.nav['isIE'])Á.setIESelection();};EA.Ä.disable_highlight=Ã(displayOnly){Á.selection_field.innerHTML=\"\";Á.content_highlight.Ç.visibility=\"hidden\";var new_Obj=Á.content_highlight.cloneNode(Ì);new_Obj.innerHTML=\"\";Á.content_highlight.ÈNode.insertBefore(new_Obj,Á.content_highlight);Á.content_highlight.ÈNode.removeChild(Á.content_highlight);Á.content_highlight=new_Obj;var old_class=È.getAttribute(Á.Â,\"class\");if(old_class){var new_class=old_class.replace(\"hidden\",\"\");È.setAttribute(Á.Â,\"class\",new_class);}Á.Â.Ç.backgroundColor=\"transÈ\";Á.switchClassSticky($(\"highlight\"),'editAreaButtonNormal',Ë);Á.switchClassSticky($(\"reset_highlight\"),'editAreaButtonDisabled',Ë);Á.do_highlight=Ì;Á.switchClassSticky($(\"change_smooth_selection\"),'editAreaButtonSelected',Ë);if(typeof(Á.smooth_selection_before_highlight)!=\"undefined\"&&Á.smooth_selection_before_highlight===Ì){Á.change_smooth_selection_mode(Ì);}};EA.Ä.enable_highlight=Ã(){Á.show_waiting_screen();Á.content_highlight.Ç.visibility=\"visible\";var new_class=È.getAttribute(Á.Â,\"class\")+\" hidden\";È.setAttribute(Á.Â,\"class\",new_class);if(Á.nav['isIE'])Á.Â.Ç.backgroundColor=\"#FFFFFF\";Á.switchClassSticky($(\"highlight\"),'editAreaButtonSelected',Ì);Á.switchClassSticky($(\"reset_highlight\"),'editAreaButtonNormal',Ì);Á.smooth_selection_before_highlight=Á.smooth_selection;if(!Á.smooth_selection)Á.change_smooth_selection_mode(Ë);Á.switchClassSticky($(\"change_smooth_selection\"),'editAreaButtonDisabled',Ë);Á.do_highlight=Ë;Á.resync_highlight();Á.hide_waiting_screen();};EA.Ä.maj_highlight=Ã(infos){if(Á.last_highlight_base_text==infos[\"full_text\"]&&Á.resync_highlight!==Ë)return;if(infos[\"full_text\"].indexOf(\"\\r\")!=-1)text_to_highlight=infos[\"full_text\"].replace(/\\r/g,\"\");\nelse text_to_highlight=infos[\"full_text\"];var start_line_pb=-1;var end_line_pb=-1;var stay_begin=\"\";var stay_end=\"\";var debug_opti=\"\";var date=new Date();var tps_start=date.getTime();var tps_middle_opti=date.getTime();if(Á.reload_highlight===Ë){Á.reload_highlight=Ì;}\nelse if(text_to_highlight.Æ==0){text_to_highlight=\"\\n \";}\nelse{var base_step=200;var cpt=0;var end=Math.min(text_to_highlight.Æ,Á.last_text_to_highlight.Æ);var step=base_step;while(cpt<end&&step>=1){if(Á.last_text_to_highlight.substr(cpt,step)==text_to_highlight.substr(cpt,step)){cpt+=step;}\nelse{step=Math.floor(step/2);}}var pos_start_change=cpt;var line_start_change=text_to_highlight.substr(0,pos_start_change).split(\"\\n\").Æ -1;cpt_last=Á.last_text_to_highlight.Æ;cpt=text_to_highlight.Æ;step=base_step;while(cpt>=0&&cpt_last>=0&&step>=1){if(Á.last_text_to_highlight.substr(cpt_last-step,step)==text_to_highlight.substr(cpt-step,step)){cpt-=step;cpt_last-=step;}\nelse{step=Math.floor(step/2);}}var pos_new_end_change=cpt;var pos_last_end_change=cpt_last;if(pos_new_end_change<=pos_start_change){if(Á.last_text_to_highlight.Æ < text_to_highlight.Æ){pos_new_end_change=pos_start_change+text_to_highlight.Æ-Á.last_text_to_highlight.Æ;pos_last_end_change=pos_start_change;}\nelse{pos_last_end_change=pos_start_change+Á.last_text_to_highlight.Æ-text_to_highlight.Æ;pos_new_end_change=pos_start_change;}}var change_new_text=text_to_highlight.substring(pos_start_change,pos_new_end_change);var change_last_text=Á.last_text_to_highlight.substring(pos_start_change,pos_last_end_change);var line_new_end_change=text_to_highlight.substr(0,pos_new_end_change).split(\"\\n\").Æ -1;var line_last_end_change=Á.last_text_to_highlight.substr(0,pos_last_end_change).split(\"\\n\").Æ -1;var change_new_text_line=text_to_highlight.split(\"\\n\").slice(line_start_change,line_new_end_change+1).join(\"\\n\");var change_last_text_line=Á.last_text_to_highlight.split(\"\\n\").slice(line_start_change,line_last_end_change+1).join(\"\\n\");var trace_new=Á.get_syntax_trace(change_new_text_line);var trace_last=Á.get_syntax_trace(change_last_text_line);if(trace_new==trace_last){date=new Date();tps_middle_opti=date.getTime();stay_begin=Á.last_hightlighted_text.split(\"\\n\").slice(0,line_start_change).join(\"\\n\");if(line_start_change>0)stay_begin+=\"\\n\";stay_end=Á.last_hightlighted_text.split(\"\\n\").slice(line_last_end_change+1).join(\"\\n\");if(stay_end.Æ>0)stay_end=\"\\n\"+stay_end;if(stay_begin.Æ==0&&pos_last_end_change==-1)change_new_text_line+=\"\\n\";text_to_highlight=change_new_text_line;}if(Á.Å[\"debug\"]){debug_opti=(trace_new==trace_last)?\"Optimisation\":\"No optimisation\";debug_opti+=\" start:\"+pos_start_change +\"(\"+line_start_change+\")\";debug_opti+=\" end_new:\"+pos_new_end_change+\"(\"+line_new_end_change+\")\";debug_opti+=\" end_last:\"+pos_last_end_change+\"(\"+line_last_end_change+\")\";debug_opti+=\"\\nchanged_text:\"+change_new_text+\" => trace:\"+trace_new;debug_opti+=\"\\nchanged_last_text:\"+change_last_text+\" => trace:\"+trace_last;debug_opti+=\"\\nchanged_line:\"+change_new_text_line;debug_opti+=\"\\nlast_changed_line:\"+change_last_text_line;debug_opti+=\"\\nstay_begin:\"+stay_begin.slice(-200);debug_opti+=\"\\nstay_end:\"+stay_end;debug_opti+=\"\\n\";}}date=new Date();tps_end_opti=date.getTime();var updated_highlight=Á.colorize_text(text_to_highlight);date=new Date();tps2=date.getTime();var hightlighted_text=stay_begin+updated_highlight+stay_end;date=new Date();inner1=date.getTime();var new_Obj=Á.content_highlight.cloneNode(Ì);if(Á.nav['isIE']||Á.nav['isOpera']||Á.nav['isFirefox'] >=3)new_Obj.innerHTML=\"<pre><span class='\"+Á.Å[\"syntax\"] +\"'>\"+hightlighted_text.replace(\"\\n\",\"<br/>\")+\"</span></pre>\";\nelse new_Obj.innerHTML=\"<span class='\"+Á.Å[\"syntax\"] +\"'>\"+hightlighted_text +\"</span>\";Á.content_highlight.ÈNode.replaceChild(new_Obj,Á.content_highlight);Á.content_highlight=new_Obj;if(infos[\"full_text\"].indexOf(\"\\r\")!=-1)Á.last_text_to_highlight=infos[\"full_text\"].replace(/\\r/g,\"\");\nelse Á.last_text_to_highlight=infos[\"full_text\"];Á.last_hightlighted_text=hightlighted_text;date=new Date();tps3=date.getTime();if(Á.Å[\"debug\"]){tot1=tps_end_opti-tps_start;tot_middle=tps_end_opti-tps_middle_opti;tot2=tps2-tps_end_opti;tps_join=inner1-tps2;tps_td2=tps3-inner1;Á.debug.Ê=\"Tps optimisation \"+tot1+\" (second part:\"+tot_middle+\")| tps reg exp:\"+tot2+\" | tps join:\"+tps_join;Á.debug.Ê+=\" | tps update highlight content:\"+tps_td2+\"(\"+tps3+\")\\n\";Á.debug.Ê+=debug_opti;}};EA.Ä.resync_highlight=Ã(reload_now){Á.reload_highlight=Ë;Á.last_highlight_base_text=\"\";Á.focus();if(reload_now)Á.check_line_selection(Ì);}; EA.Ä.comment_or_quote=Ã(){var new_class=\"\";var close_tag=\"\";for(var i in È.eAL.syntax[eA.current_code_lang][\"quotes\"]){if(EA.Ä.comment_or_quote.arguments[0].indexOf(i)==0){new_class=\"quotesmarks\";close_tag=È.eAL.syntax[eA.current_code_lang][\"quotes\"][i];}}if(new_class.Æ==0){for(var i in È.eAL.syntax[eA.current_code_lang][\"comments\"]){if(EA.Ä.comment_or_quote.arguments[0].indexOf(i)==0){new_class=\"comments\";close_tag=È.eAL.syntax[eA.current_code_lang][\"comments\"][i];}}}if(close_tag==\"\\n\"){return \"µ__\"+new_class +\"__µ\"+EA.Ä.comment_or_quote.arguments[0].replace(/(\\r?\\n)?$/m,\"µ_END_µ$1\");}\nelse{reg=new RegExp(È.eAL.get_escaped_regexp(close_tag)+\"$\",\"m\");if(EA.Ä.comment_or_quote.arguments[0].search(reg)!=-1)return \"µ__\"+new_class +\"__µ\"+EA.Ä.comment_or_quote.arguments[0]+\"µ_END_µ\";\nelse return \"µ__\"+new_class +\"__µ\"+EA.Ä.comment_or_quote.arguments[0];}};EA.Ä.get_syntax_trace=Ã(text){if(Á.Å[\"syntax\"].Æ>0&&È.eAL.syntax[Á.Å[\"syntax\"]][\"syntax_trace_regexp\"])return text.replace(È.eAL.syntax[Á.Å[\"syntax\"]][\"syntax_trace_regexp\"],\"$3\");};EA.Ä.colorize_text=Ã(text){text=\" \"+text;if(Á.Å[\"syntax\"].Æ>0)text=Á.apply_syntax(text,Á.Å[\"syntax\"]);return text.substr(1).replace(/&/g,\"&amp;\").replace(/</g,\"&lt;\").replace(/>/g,\"&gt;\").replace(/µ_END_µ/g,\"</span>\").replace(/µ__([a-zA-Z0-9]+)__µ/g,\"<span class='$1'>\");};EA.Ä.apply_syntax=Ã(text,lang){Á.current_code_lang=lang;if(!È.eAL.syntax[lang])return text;if(È.eAL.syntax[lang][\"custom_regexp\"]['before']){for(var i in È.eAL.syntax[lang][\"custom_regexp\"]['before']){var convert=\"$1µ__\"+È.eAL.syntax[lang][\"custom_regexp\"]['before'][i]['class'] +\"__µ$2µ_END_µ$3\";text=text.replace(È.eAL.syntax[lang][\"custom_regexp\"]['before'][i]['regexp'],convert);}}if(È.eAL.syntax[lang][\"comment_or_quote_reg_exp\"]){text=text.replace(È.eAL.syntax[lang][\"comment_or_quote_reg_exp\"],Á.comment_or_quote);}if(È.eAL.syntax[lang][\"keywords_reg_exp\"]){for(var i in È.eAL.syntax[lang][\"keywords_reg_exp\"]){text=text.replace(È.eAL.syntax[lang][\"keywords_reg_exp\"][i],'µ__'+i+'__µ$2µ_END_µ');}}if(È.eAL.syntax[lang][\"delimiters_reg_exp\"]){text=text.replace(È.eAL.syntax[lang][\"delimiters_reg_exp\"],'µ__delimiters__µ$1µ_END_µ');}if(È.eAL.syntax[lang][\"operators_reg_exp\"]){text=text.replace(È.eAL.syntax[lang][\"operators_reg_exp\"],'µ__operators__µ$1µ_END_µ');}if(È.eAL.syntax[lang][\"custom_regexp\"]['after']){for(var i in È.eAL.syntax[lang][\"custom_regexp\"]['after']){var convert=\"$1µ__\"+È.eAL.syntax[lang][\"custom_regexp\"]['after'][i]['class'] +\"__µ$2µ_END_µ$3\";text=text.replace(È.eAL.syntax[lang][\"custom_regexp\"]['after'][i]['regexp'],convert);}}return text;};var editArea= eA;EditArea=EA;</script>".replace(/Á/g,'this').replace(/Â/g,'textarea').replace(/Ã/g,'function').replace(/Ä/g,'prototype').replace(/Å/g,'settings').replace(/Æ/g,'length').replace(/Ç/g,'style').replace(/È/g,'parent').replace(/É/g,'last_selection').replace(/Ê/g,'value').replace(/Ë/g,'true').replace(/Ì/g,'false');
+editAreaLoader.template= "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\"> <html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" > <head> <title>EditArea</title> <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" /> [__CSSRULES__] [__JSCODE__] </head> <body> <div id='editor'> <div class='area_toolbar' id='toolbar_1'>[__TOOLBAR__]</div> <div class='area_toolbar' id='tab_browsing_area'><ul id='tab_browsing_list' class='menu'> <li> </li> </ul></div> <div id='result'> <div id='no_file_selected'></div> <div id='container'> <div id='cursor_pos' class='edit_area_cursor'>&nbsp;</div> <div id='end_bracket' class='edit_area_cursor'>&nbsp;</div> <div id='selection_field'></div> <div id='line_number' selec='none'></div> <div id='content_highlight'></div> <div id='test_font_size'></div> <textarea id='textarea' wrap='off' onchange='editArea.execCommand(\"onchange\");' onfocus='javascript:editArea.textareaFocused=true;' onblur='javascript:editArea.textareaFocused=false;'> </textarea> </div> </div> <div class='area_toolbar' id='toolbar_2'> <table class='statusbar' cellspacing='0' cellpadding='0'> <tr> <td class='total' selec='none'>{$position}:</td> <td class='infos' selec='none'> {$line_abbr} <span  id='linePos'>0</span>, {$char_abbr} <span id='currPos'>0</span> </td> <td class='total' selec='none'>{$total}:</td> <td class='infos' selec='none'> {$line_abbr} <span id='nbLine'>0</span>, {$char_abbr} <span id='nbChar'>0</span> </td> <td class='resize'> <span id='resize_area'><img src='[__BASEURL__]images/statusbar_resize.gif' alt='resize' selec='none'></span> </td> </tr> </table> </div> </div> <div id='processing'> <div id='processing_text'> {$processing} </div> </div> <div id='area_search_replace' class='editarea_popup'> <table cellspacing='2' cellpadding='0' style='width: 100%'> <tr> <td selec='none'>{$search}</td> <td><input type='text' id='area_search' /></td> <td id='close_area_search_replace'> <a onclick='Javascript:editArea.execCommand(\"hidden_search\")'><img selec='none' src='[__BASEURL__]images/close.gif' alt='{$close_popup}' title='{$close_popup}' /></a><br /> </tr><tr> <td selec='none'>{$replace}</td> <td><input type='text' id='area_replace' /></td> <td><img id='move_area_search_replace' onmousedown='return parent.start_move_element(event,\"area_search_replace\", parent.frames[\"frame_\"+editArea.id]);'  src='[__BASEURL__]images/move.gif' alt='{$move_popup}' title='{$move_popup}' /></td> </tr> </table> <div class='button'> <input type='checkbox' id='area_search_match_case' /><label for='area_search_match_case' selec='none'>{$match_case}</label> <input type='checkbox' id='area_search_reg_exp' /><label for='area_search_reg_exp' selec='none'>{$reg_exp}</label> <br /> <a onclick='Javascript:editArea.execCommand(\"area_search\")' selec='none'>{$find_next}</a> <a onclick='Javascript:editArea.execCommand(\"area_replace\")' selec='none'>{$replace}</a> <a onclick='Javascript:editArea.execCommand(\"area_replace_all\")' selec='none'>{$replace_all}</a><br /> </div> <div id='area_search_msg' selec='none'></div> </div> <div id='edit_area_help' class='editarea_popup'> <div class='close_popup'> <a onclick='Javascript:editArea.execCommand(\"close_all_inline_popup\")'><img src='[__BASEURL__]images/close.gif' alt='{$close_popup}' title='{$close_popup}' /></a> </div> <div><h2>Editarea [__EA_VERSION__]</h2><br /> <h3>{$shortcuts}:</h3> {$tab}: {$add_tab}<br /> {$shift}+{$tab}: {$remove_tab}<br /> {$ctrl}+f: {$search_command}<br /> {$ctrl}+r: {$replace_command}<br /> {$ctrl}+h: {$highlight}<br /> {$ctrl}+g: {$go_to_line}<br /> {$ctrl}+z: {$undo}<br /> {$ctrl}+y: {$redo}<br /> {$ctrl}+e: {$help}<br /> {$ctrl}+q, {$esc}: {$close_popup}<br /> {$accesskey} E: {$toggle}<br /> <br /> <em>{$about_notice}</em> <br /><div class='copyright'>&copy; Christophe Dolivet 2007-2008</div> </div> </div> </div> </body> </html> ";
+editAreaLoader.iframe_css= "<style>body,html{margin:0;padding:0;height:100%;border:none;overflow:hidden;background-color:#FFF;}body,html,table,form,textarea{font:12px monospace,sans-serif;}#editor{border:solid #888 1px;overflow:visible;}#result{z-index:4;overflow-x:auto;overflow-y:scroll;border-top:solid #888 1px;border-bottom:solid #888 1px;position:relative;clear:both;}#result.empty{overflow:hidden;}#container{overflow:hidden;border:solid blue 0;position:relative;z-index:10;padding:0 5px 0 45px;}#textarea{position:relative;top:0;left:0;margin:0;padding:0;width:100%;height:100%;overflow:hidden;z-index:7;border-width:0;background-color:transparent;}#textarea,#textarea:hover{outline:none;}#content_highlight{white-space:pre;margin:0;padding:0;position:absolute;z-index:4;overflow:visible;}#selection_field{margin:0;background-color:#E1F2F9;height:1px;position:absolute;z-index:5;top:-100px;padding:0;white-space:pre;overflow:hidden;}#selection_field.show_colors{z-index:3;background-color:#EDF9FC;color:transparent;}#container.wrap_text #content_highlight,#container.wrap_text #selection_field{white-space:pre-wrap;white-space:-moz-pre-wrap !important;white-space:-pre-wrap;white-space:-o-pre-wrap;word-wrap:break-word;width:99%;}#line_number{position:absolute;overflow:hidden;border-right:solid black 1px;z-index:8;width:38px;padding:0 5px 0 0;margin:0 0 0 -45px;text-align:right;color:#AAAAAA;}#test_font_size{padding:0;margin:0;visibility:hidden;position:absolute;white-space:pre;}pre{margin:0;padding:0;}.hidden{opacity:0.2;filter:alpha(opacity=20);}#result .edit_area_cursor{position:absolute;z-index:6;background-color:#FF6633;top:-100px;margin:1px 0 0 0;}#result .edit_area_selection_field .overline{background-color:#996600;}.editarea_popup{border:solid 1px #888888;background-color:#ECE9D8;width:250px;padding:4px;position:absolute;visibility:hidden;z-index:15;top:-500px;}.editarea_popup,.editarea_popup table{font-family:sans-serif;font-size:10pt;}.editarea_popup img{border:0;}.editarea_popup .close_popup{float:right;line-height:16px;border:0;padding:0;}.editarea_popup h1,.editarea_popup h2,.editarea_popup h3,.editarea_popup h4,.editarea_popup h5,.editarea_popup h6{margin:0;padding:0;}.editarea_popup .copyright{text-align:right;}div#area_search_replace{}div#area_search_replace img{border:0;}div#area_search_replace div.button{text-align:center;line-height:1.7em;}div#area_search_replace .button a{cursor:pointer;border:solid 1px #888888;background-color:#DEDEDE;text-decoration:none;padding:0 2px;color:#000000;white-space:nowrap;}div#area_search_replace a:hover{background-color:#EDEDED;}div#area_search_replace  #move_area_search_replace{cursor:move;border:solid 1px #888;}div#area_search_replace  #close_area_search_replace{text-align:right;vertical-align:top;white-space:nowrap;}div#area_search_replace  #area_search_msg{height:18px;overflow:hidden;border-top:solid 1px #888;margin-top:3px;}#edit_area_help{width:350px;}#edit_area_help div.close_popup{float:right;}.area_toolbar{width:100%;margin:0;padding:0;background-color:#ECE9D8;text-align:center;}.area_toolbar,.area_toolbar table{font:11px sans-serif;}.area_toolbar img{border:0;vertical-align:middle;}.area_toolbar input{margin:0;padding:0;}.area_toolbar select{font-family:'MS Sans Serif',sans-serif,Verdana,Arial;font-size:7pt;font-weight:normal;margin:2px 0 0 0 ;padding:0;vertical-align:top;background-color:#F0F0EE;}table.statusbar{width:100%;}.area_toolbar td.infos{text-align:center;width:130px;border-right:solid 1px #888;border-width:0 1px 0 0;padding:0;}.area_toolbar td.total{text-align:right;width:50px;padding:0;}.area_toolbar td.resize{text-align:right;}.area_toolbar span#resize_area{cursor:nw-resize;visibility:hidden;}.editAreaButtonNormal,.editAreaButtonOver,.editAreaButtonDown,.editAreaSeparator,.editAreaSeparatorLine,.editAreaButtonDisabled,.editAreaButtonSelected {border:0; margin:0; padding:0; background:transparent;margin-top:0;margin-left:1px;padding:0;}.editAreaButtonNormal {border:1px solid #ECE9D8 !important;cursor:pointer;}.editAreaButtonOver {border:1px solid #0A246A !important;cursor:pointer;background-color:#B6BDD2;}.editAreaButtonDown {cursor:pointer;border:1px solid #0A246A !important;background-color:#8592B5;}.editAreaButtonSelected {border:1px solid #C0C0BB !important;cursor:pointer;background-color:#F4F2E8;}.editAreaButtonDisabled {filter:progid:DXImageTransform.Microsoft.Alpha(opacity=30);-moz-opacity:0.3;opacity:0.3;border:1px solid #F0F0EE !important;cursor:pointer;}.editAreaSeparatorLine {margin:1px 2px;background-color:#C0C0BB;width:2px;height:18px;}#processing{display:none;background-color:#ECE9D8;border:solid #888 1px;position:absolute;top:0;left:0;width:100%;height:100%;z-index:100;text-align:center;}#processing_text{position:absolute;left:50%;top:50%;width:200px;height:20px;margin-left:-100px;margin-top:-10px;text-align:center;}#tab_browsing_area{display:none;background-color:#CCC9A8;border-top:1px solid #888;text-align:left;margin:0;}#tab_browsing_list {padding:0;margin:0;list-style-type:none;white-space:nowrap;}#tab_browsing_list li {float:left;margin:-1px;}#tab_browsing_list a {position:relative;display:block;text-decoration:none;float:left;cursor:pointer;line-height:14px;}#tab_browsing_list a span {display:block;color:#000;background:#ECE9D8;border:1px solid #888;border-width:1px 1px 0;text-align:center;padding:2px 2px 1px 4px;position:relative;}#tab_browsing_list a b {display:block;border-bottom:2px solid #617994;}#tab_browsing_list a .edited {display:none;}#tab_browsing_list a.edited .edited {display:inline;}#tab_browsing_list a img{margin-left:7px;}#tab_browsing_list a.edited img{margin-left:3px;}#tab_browsing_list a:hover span {background:#F4F2E8;border-color:#0A246A;}#tab_browsing_list .selected a span{background:#046380;color:#FFF;}#no_file_selected{height:100%;width:150%;background:#CCC;display:none;z-index:20;position:absolute;}.non_editable #editor{border-width:0 1px;}.non_editable .area_toolbar{display:none;}#auto_completion_area{background:#FFF;border:solid 1px #888;position:absolute;z-index:15;width:280px;height:180px;overflow:auto;display:none;}#auto_completion_area a,#auto_completion_area a:visited{display:block;padding:0 2px 1px;color:#000;text-decoration:none;}#auto_completion_area a:hover,#auto_completion_area a:focus,#auto_completion_area a.focus{background:#D6E1FE;text-decoration:none;}#auto_completion_area ul{margin:0;padding:0;list-style:none inside;}#auto_completion_area li{padding:0;}#auto_completion_area .prefix{font-style:italic;padding:0 3px;}</style>";
Index: /tags/2.0.2/plugins/LocalFilesEditor/editarea/images/index.php
===================================================================
--- /tags/2.0.2/plugins/LocalFilesEditor/editarea/images/index.php	(revision 3278)
+++ /tags/2.0.2/plugins/LocalFilesEditor/editarea/images/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/plugins/LocalFilesEditor/editarea/index.php
===================================================================
--- /tags/2.0.2/plugins/LocalFilesEditor/editarea/index.php	(revision 3278)
+++ /tags/2.0.2/plugins/LocalFilesEditor/editarea/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/plugins/LocalFilesEditor/editarea/langs/cs.js
===================================================================
--- /tags/2.0.2/plugins/LocalFilesEditor/editarea/langs/cs.js	(revision 3278)
+++ /tags/2.0.2/plugins/LocalFilesEditor/editarea/langs/cs.js	(revision 3278)
@@ -0,0 +1,65 @@
+editAreaLoader.lang["cs"]={
+new_document: "Nový dokument",
+search_button: "Najdi a nahraď",
+search_command: "Hledej další / otevři vyhledávací pole",
+search: "Hledej",
+replace: "Nahraď",
+replace_command: "Nahraď / otevři vyhledávací pole",
+find_next: "Najdi další",
+replace_all: "Nahraď vše",
+reg_exp: "platné výrazy",
+match_case: "vyhodnocené výrazy",
+not_found: "nenalezené.",
+occurrence_replaced: "výskyty nahrazené.",
+search_field_empty: "Pole vyhledávání je prázdné",
+restart_search_at_begin: "Dosažen konec souboru, začínám od začátku.",
+move_popup: "Přesuň vyhledávací okno",
+font_size: "--Velikost textu--",
+go_to_line: "Přejdi na řádek",
+go_to_line_prompt: "Přejdi na řádek:",
+undo: "krok zpět",
+redo: "znovu",
+change_smooth_selection: "Povolit nebo zakázat některé ze zobrazených funkcí (účelnější zobrazení požaduje větší zatížení procesoru)",
+highlight: "Zvýrazňování syntaxe zap./vyp.",
+reset_highlight: "Obnovit zvýraznění (v případě nesrovnalostí)",
+help: "O programu",
+save: "Uložit",
+load: "Otevřít",
+line_abbr: "Ř.",
+char_abbr: "S.",
+position: "Pozice",
+total: "Celkem",
+close_popup: "Zavřít okno",
+shortcuts: "Zkratky",
+add_tab: "Přidat tabulování textu",
+remove_tab: "Odtsranit tabulování textu",
+about_notice: "Upozornění! Funkce zvýrazňování textu je k dispozici pouze pro malý text",
+toggle: "Přepnout editor",
+accesskey: "Přístupová klávesa",
+tab: "Záložka",
+shift: "Shift",
+ctrl: "Ctrl",
+esc: "Esc",
+processing: "Zpracovávám ...",
+fullscreen: "Celá obrazovka",
+syntax_selection: "--vyber zvýrazňovač--",
+syntax_css: "CSS",
+syntax_html: "HTML",
+syntax_js: "Javascript",
+syntax_php: "Php",
+syntax_python: "Python",
+syntax_vb: "Visual Basic",
+syntax_xml: "Xml",
+syntax_c: "C",
+syntax_cpp: "CPP",
+syntax_basic: "Basic",
+syntax_pas: "Pascal",
+syntax_brainfuck: "Brainfuck",
+syntax_sql: "SQL",
+syntax_ruby: "Ruby",
+syntax_robotstxt: "Robots txt",
+syntax_tsql: "T-SQL",
+syntax_perl: "Perl",
+syntax_coldfusion: "Coldfusion",
+close_tab: "Close file"
+};
Index: /tags/2.0.2/plugins/LocalFilesEditor/editarea/langs/de.js
===================================================================
--- /tags/2.0.2/plugins/LocalFilesEditor/editarea/langs/de.js	(revision 3278)
+++ /tags/2.0.2/plugins/LocalFilesEditor/editarea/langs/de.js	(revision 3278)
@@ -0,0 +1,65 @@
+editAreaLoader.lang["de"]={
+new_document: "Neues Dokument",
+search_button: "Suchen und Ersetzen",
+search_command: "Weitersuchen / &ouml;ffne Suchfeld",
+search: "Suchen",
+replace: "Ersetzen",
+replace_command: "Ersetzen / &ouml;ffne Suchfeld",
+find_next: "Weitersuchen",
+replace_all: "Ersetze alle Treffer",
+reg_exp: "regul&auml;re Ausdr&uuml;cke",
+match_case: "passt auf den Begriff<br />",
+not_found: "Nicht gefunden.",
+occurrence_replaced: "Die Vorkommen wurden ersetzt.",
+search_field_empty: "Leeres Suchfeld",
+restart_search_at_begin: "Ende des zu durchsuchenden Bereiches erreicht. Es wird die Suche von Anfang an fortgesetzt.", //find a shorter translation
+move_popup: "Suchfenster bewegen",
+font_size: "--Schriftgr&ouml;&szlig;e--",
+go_to_line: "Gehe zu Zeile",
+go_to_line_prompt: "Gehe zu Zeilennummmer:",
+undo: "R&uuml;ckg&auml;ngig",
+redo: "Wiederherstellen",
+change_smooth_selection: "Aktiviere/Deaktiviere einige Features (weniger Bildschirmnutzung aber mehr CPU-Belastung)",
+highlight: "Syntax Highlighting an- und ausschalten",
+reset_highlight: "Highlighting zur&uuml;cksetzen (falls mit Text nicht konform)",
+help: "Info",
+save: "Speichern",
+load: "&Ouml;ffnen",
+line_abbr: "Ln",
+char_abbr: "Ch",
+position: "Position",
+total: "Gesamt",
+close_popup: "Popup schlie&szlig;en",
+shortcuts: "Shortcuts",
+add_tab: "Tab zum Text hinzuf&uuml;gen",
+remove_tab: "Tab aus Text entfernen",
+about_notice: "Bemerkung: Syntax Highlighting ist nur f&uuml;r kurze Texte",
+toggle: "Editor an- und ausschalten",
+accesskey: "Accesskey",
+tab: "Tab",
+shift: "Shift",
+ctrl: "Ctrl",
+esc: "Esc",
+processing: "In Bearbeitung...",
+fullscreen: "Full-Screen",
+syntax_selection: "--Syntax--",
+syntax_css: "CSS",
+syntax_html: "HTML",
+syntax_js: "Javascript",
+syntax_php: "Php",
+syntax_python: "Python",
+syntax_vb: "Visual Basic",
+syntax_xml: "Xml",
+syntax_c: "C",
+syntax_cpp: "CPP",
+syntax_basic: "Basic",
+syntax_pas: "Pascal",
+syntax_brainfuck: "Brainfuck",
+syntax_sql: "SQL",
+syntax_ruby: "Ruby",
+syntax_robotstxt: "Robots txt",
+syntax_tsql: "T-SQL",
+syntax_perl: "Perl",
+syntax_coldfusion: "Coldfusion",
+close_tab: "Close file"
+};
Index: /tags/2.0.2/plugins/LocalFilesEditor/editarea/langs/dk.js
===================================================================
--- /tags/2.0.2/plugins/LocalFilesEditor/editarea/langs/dk.js	(revision 3278)
+++ /tags/2.0.2/plugins/LocalFilesEditor/editarea/langs/dk.js	(revision 3278)
@@ -0,0 +1,65 @@
+editAreaLoader.lang["dk"]={
+new_document: "nyt tomt dokument",
+search_button: "s&oslash;g og erstat",
+search_command: "find n&aelig;ste / &aring;ben s&oslash;gefelt",
+search: "s&oslash;g",
+replace: "erstat",
+replace_command: "erstat / &aring;ben s&oslash;gefelt",
+find_next: "find n&aelig;ste",
+replace_all: "erstat alle",
+reg_exp: "regular expressions",
+match_case: "forskel på store/sm&aring; bogstaver<br />",
+not_found: "not found.",
+occurrence_replaced: "occurences replaced.",
+search_field_empty: "Search field empty",
+restart_search_at_begin: "End of area reached. Restart at begin.",
+move_popup: "flyt søgepopup",
+font_size: "--Skriftstørrelse--",
+go_to_line: "g&aring; til linie",
+go_to_line_prompt: "gå til linienummer:",
+undo: "fortryd",
+redo: "gentag",
+change_smooth_selection: "sl&aring; display funktioner til/fra (smartere display men mere CPU kr&aelig;vende)",
+highlight: "sl&aring; syntax highlight til/fra",
+reset_highlight: "nulstil highlight (hvis den er desynkroniseret fra teksten)",
+help: "om",
+save: "gem",
+load: "hent",
+line_abbr: "Ln",
+char_abbr: "Ch",
+position: "Position",
+total: "Total",
+close_popup: "luk popup",
+shortcuts: "Genveje",
+add_tab: "tilf&oslash;j tabulation til tekst",
+remove_tab: "fjern tabulation fra tekst",
+about_notice: "Husk: syntax highlight funktionen b&oslash;r kun bruge til sm&aring; tekster",
+toggle: "Sl&aring; editor til / fra",
+accesskey: "Accesskey",
+tab: "Tab",
+shift: "Skift",
+ctrl: "Ctrl",
+esc: "Esc",
+processing: "Processing...",
+fullscreen: "fullscreen",
+syntax_selection: "--Syntax--",
+syntax_css: "CSS",
+syntax_html: "HTML",
+syntax_js: "Javascript",
+syntax_php: "Php",
+syntax_python: "Python",
+syntax_vb: "Visual Basic",
+syntax_xml: "Xml",
+syntax_c: "C",
+syntax_cpp: "CPP",
+syntax_basic: "Basic",
+syntax_pas: "Pascal",
+syntax_brainfuck: "Brainfuck",
+syntax_sql: "SQL",
+syntax_ruby: "Ruby",
+syntax_robotstxt: "Robots txt",
+syntax_tsql: "T-SQL",
+syntax_perl: "Perl",
+syntax_coldfusion: "Coldfusion",
+close_tab: "Close file"
+};
Index: /tags/2.0.2/plugins/LocalFilesEditor/editarea/langs/en.js
===================================================================
--- /tags/2.0.2/plugins/LocalFilesEditor/editarea/langs/en.js	(revision 3278)
+++ /tags/2.0.2/plugins/LocalFilesEditor/editarea/langs/en.js	(revision 3278)
@@ -0,0 +1,65 @@
+editAreaLoader.lang["en"]={
+new_document: "new empty document",
+search_button: "search and replace",
+search_command: "search next / open search area",
+search: "search",
+replace: "replace",
+replace_command: "replace / open search area",
+find_next: "find next",
+replace_all: "replace all",
+reg_exp: "regular expressions",
+match_case: "match case",
+not_found: "not found.",
+occurrence_replaced: "occurences replaced.",
+search_field_empty: "Search field empty",
+restart_search_at_begin: "End of area reached. Restart at begin.",
+move_popup: "move search popup",
+font_size: "--Font size--",
+go_to_line: "go to line",
+go_to_line_prompt: "go to line number:",
+undo: "undo",
+redo: "redo",
+change_smooth_selection: "enable/disable some display features (smarter display but more CPU charge)",
+highlight: "toggle syntax highlight on/off",
+reset_highlight: "reset highlight (if desyncronized from text)",
+help: "about",
+save: "save",
+load: "load",
+line_abbr: "Ln",
+char_abbr: "Ch",
+position: "Position",
+total: "Total",
+close_popup: "close popup",
+shortcuts: "Shortcuts",
+add_tab: "add tabulation to text",
+remove_tab: "remove tabulation to text",
+about_notice: "Notice: syntax highlight function is only for small text",
+toggle: "Toggle editor",
+accesskey: "Accesskey",
+tab: "Tab",
+shift: "Shift",
+ctrl: "Ctrl",
+esc: "Esc",
+processing: "Processing...",
+fullscreen: "fullscreen",
+syntax_selection: "--Syntax--",
+syntax_css: "CSS",
+syntax_html: "HTML",
+syntax_js: "Javascript",
+syntax_php: "Php",
+syntax_python: "Python",
+syntax_vb: "Visual Basic",
+syntax_xml: "Xml",
+syntax_c: "C",
+syntax_cpp: "CPP",
+syntax_basic: "Basic",
+syntax_pas: "Pascal",
+syntax_brainfuck: "Brainfuck",
+syntax_sql: "SQL",
+syntax_ruby: "Ruby",
+syntax_robotstxt: "Robots txt",
+syntax_tsql: "T-SQL",
+syntax_perl: "Perl",
+syntax_coldfusion: "Coldfusion",
+close_tab: "Close file"
+};
Index: /tags/2.0.2/plugins/LocalFilesEditor/editarea/langs/es.js
===================================================================
--- /tags/2.0.2/plugins/LocalFilesEditor/editarea/langs/es.js	(revision 3278)
+++ /tags/2.0.2/plugins/LocalFilesEditor/editarea/langs/es.js	(revision 3278)
@@ -0,0 +1,62 @@
+editAreaLoader.lang["es"]={
+new_document: "nuevo documento vacío",
+search_button: "buscar y reemplazar",
+search_command: "buscar siguiente / abrir área de búsqueda",
+search: "buscar",
+replace: "reemplazar",
+replace_command: "reemplazar / abrir área de búsqueda",
+find_next: "encontrar siguiente",
+replace_all: "reemplazar todos",
+reg_exp: "expresiones regulares",
+match_case: "coincidir capitalización",
+not_found: "no encontrado.",
+occurrence_replaced: "ocurrencias reemplazadas.",
+search_field_empty: "Campo de búsqueda vacío",
+restart_search_at_begin: "Se ha llegado al final del área. Se va a seguir desde el principio.",
+move_popup: "mover la ventana de búsqueda",
+font_size: "--Tamaño de la fuente--",
+go_to_line: "ir a la línea",
+go_to_line_prompt: "ir a la línea número:",
+undo: "deshacer",
+redo: "rehacer",
+change_smooth_selection: "activar/desactivar algunas características de visualización (visualización más inteligente pero más carga de CPU)",
+highlight: "intercambiar resaltado de sintaxis",
+reset_highlight: "reinicializar resaltado (si no esta sincronizado con el texto)",
+help: "acerca",
+save: "guardar",
+load: "cargar",
+line_abbr: "Ln",
+char_abbr: "Ch",
+position: "Posición",
+total: "Total",
+close_popup: "recuadro de cierre",
+shortcuts: "Atajos",
+add_tab: "añadir tabulado al texto",
+remove_tab: "borrar tabulado del texto",
+about_notice: "Aviso: el resaltado de sintaxis sólo funciona para texto pequeño",
+toggle: "Cambiar editor",
+accesskey: "Tecla de acceso",
+tab: "Tab",
+shift: "Mayúsc",
+ctrl: "Ctrl",
+esc: "Esc",
+processing: "Procesando...",
+fullscreen: "pantalla completa",
+syntax_selection: "--Syntax--",
+syntax_css: "CSS",
+syntax_html: "HTML",
+syntax_js: "Javascript",
+syntax_php: "Php",
+syntax_python: "Python",
+syntax_vb: "Visual Basic",
+syntax_xml: "Xml",
+syntax_c: "C",
+syntax_cpp: "CPP",
+syntax_basic: "Basic",
+syntax_pas: "Pascal",
+syntax_brainfuck: "Brainfuck",
+syntax_sql: "SQL",
+syntax_ruby: "Ruby",
+syntax_coldfusion: "Coldfusion",
+close_tab: "Close file"
+};
Index: /tags/2.0.2/plugins/LocalFilesEditor/editarea/langs/fr.js
===================================================================
--- /tags/2.0.2/plugins/LocalFilesEditor/editarea/langs/fr.js	(revision 3278)
+++ /tags/2.0.2/plugins/LocalFilesEditor/editarea/langs/fr.js	(revision 3278)
@@ -0,0 +1,65 @@
+editAreaLoader.lang["fr"]={
+new_document: "nouveau document (efface le contenu)",
+search_button: "rechercher / remplacer",
+search_command: "rechercher suivant / ouvrir la fen&ecirc;tre de recherche",
+search: "rechercher",
+replace: "remplacer",
+replace_command: "remplacer / ouvrir la fen&ecirc;tre de recherche",
+find_next: "rechercher",
+replace_all: "tout remplacer",
+reg_exp: "expr. r&eacute;guli&egrave;re",
+match_case: "respecter la casse",
+not_found: "pas trouv&eacute;.",
+occurrence_replaced: "remplacements &eacute;ffectu&eacute;s.",
+search_field_empty: "Le champ de recherche est vide.",
+restart_search_at_begin: "Fin du texte atteint, poursuite au d&eacute;but.",
+move_popup: "d&eacute;placer la fen&ecirc;tre de recherche",
+font_size: "--Taille police--",
+go_to_line: "aller &agrave; la ligne",
+go_to_line_prompt: "aller a la ligne numero:",
+undo: "annuler",
+redo: "refaire",
+change_smooth_selection: "activer/d&eacute;sactiver des fonctions d'affichage (meilleur affichage mais plus de charge processeur)",
+highlight: "activer/d&eacute;sactiver la coloration syntaxique",
+reset_highlight: "r&eacute;initialiser la coloration syntaxique (si d&eacute;syncronis&eacute;e du texte)",
+help: "&agrave; propos",
+save: "sauvegarder",
+load: "charger",
+line_abbr: "Ln",
+char_abbr: "Ch",
+position: "Position",
+total: "Total",
+close_popup: "fermer le popup",
+shortcuts: "Racourcis clavier",
+add_tab: "ajouter une tabulation dans le texte",
+remove_tab: "retirer une tabulation dans le texte",
+about_notice: "Note: la coloration syntaxique n'est pr&eacute;vue que pour de courts textes.",
+toggle: "basculer l'&eacute;diteur",
+accesskey: "Accesskey",
+tab: "Tab",
+shift: "Maj",
+ctrl: "Ctrl",
+esc: "Esc",
+processing: "chargement...",
+fullscreen: "plein &eacute;cran",
+syntax_selection: "--Syntaxe--",
+syntax_css: "CSS",
+syntax_html: "HTML",
+syntax_js: "Javascript",
+syntax_php: "Php",
+syntax_python: "Python",
+syntax_vb: "Visual Basic",
+syntax_xml: "Xml",
+syntax_c: "C",
+syntax_cpp: "CPP",
+syntax_basic: "Basic",
+syntax_pas: "Pascal",
+syntax_brainfuck: "Brainfuck",
+syntax_sql: "SQL",
+syntax_ruby: "Ruby",
+syntax_robotstxt: "Robots txt",
+syntax_tsql: "T-SQL",
+syntax_perl: "Perl",
+syntax_coldfusion: "Coldfusion",
+close_tab: "Fermer le fichier"
+};
Index: /tags/2.0.2/plugins/LocalFilesEditor/editarea/langs/hr.js
===================================================================
--- /tags/2.0.2/plugins/LocalFilesEditor/editarea/langs/hr.js	(revision 3278)
+++ /tags/2.0.2/plugins/LocalFilesEditor/editarea/langs/hr.js	(revision 3278)
@@ -0,0 +1,65 @@
+editAreaLoader.lang["hr"]={
+new_document: "Novi dokument",
+search_button: "Traži i izmijeni",
+search_command: "Traži dalje / Otvori prozor za traženje",
+search: "Traži",
+replace: "Izmijeni",
+replace_command: "Izmijeni / Otvori prozor za traženje",
+find_next: "Traži dalje",
+replace_all: "Izmjeni sve",
+reg_exp: "Regularni izrazi",
+match_case: "Bitna vel. slova",
+not_found: "nije naðeno.",
+occurrence_replaced: "izmjenjenih.",
+search_field_empty: "Prazno polje za traženje!",
+restart_search_at_begin: "Došao do kraja. Poèeo od poèetka.",
+move_popup: "Pomakni prozor",
+font_size: "--Velièina teksta--",
+go_to_line: "Odi na redak",
+go_to_line_prompt: "Odi na redak:",
+undo: "Vrati natrag",
+redo: "Napravi ponovo",
+change_smooth_selection: "Ukljuèi/iskljuèi neke moguænosti prikaza (pametniji prikaz, ali zagušeniji CPU)",
+highlight: "Ukljuèi/iskljuèi bojanje sintakse",
+reset_highlight: "Ponovi kolorizaciju (ako je nesinkronizirana s tekstom)",
+help: "O edit_area",
+save: "Spremi",
+load: "Uèitaj",
+line_abbr: "Ln",
+char_abbr: "Zn",
+position: "Pozicija",
+total: "Ukupno",
+close_popup: "Zatvori prozor",
+shortcuts: "Kratice",
+add_tab: "Dodaj tabulaciju",
+remove_tab: "Makni tabulaciju",
+about_notice: "Napomena: koloriziranje sintakse je samo za kratke kodove",
+toggle: "Prebaci naèin ureðivanja",
+accesskey: "Accesskey",
+tab: "Tab",
+shift: "Shift",
+ctrl: "Ctrl",
+esc: "Esc",
+processing: "Procesiram...",
+fullscreen: "Cijeli prozor",
+syntax_selection: "--Syntax--",
+syntax_css: "CSS",
+syntax_html: "HTML",
+syntax_js: "Javascript",
+syntax_php: "Php",
+syntax_python: "Python",
+syntax_vb: "Visual Basic",
+syntax_xml: "Xml",
+syntax_c: "C",
+syntax_cpp: "CPP",
+syntax_basic: "Basic",
+syntax_pas: "Pascal",
+syntax_brainfuck: "Brainfuck",
+syntax_sql: "SQL",
+syntax_ruby: "Ruby",
+syntax_robotstxt: "Robots txt",
+syntax_tsql: "T-SQL",
+syntax_perl: "Perl",
+syntax_coldfusion: "Coldfusion",
+close_tab: "Close file"
+};
Index: /tags/2.0.2/plugins/LocalFilesEditor/editarea/langs/index.php
===================================================================
--- /tags/2.0.2/plugins/LocalFilesEditor/editarea/langs/index.php	(revision 3278)
+++ /tags/2.0.2/plugins/LocalFilesEditor/editarea/langs/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/plugins/LocalFilesEditor/editarea/langs/it.js
===================================================================
--- /tags/2.0.2/plugins/LocalFilesEditor/editarea/langs/it.js	(revision 3278)
+++ /tags/2.0.2/plugins/LocalFilesEditor/editarea/langs/it.js	(revision 3278)
@@ -0,0 +1,65 @@
+editAreaLoader.lang["it"]={
+new_document: "nuovo documento vuoto",
+search_button: "cerca e sostituisci",
+search_command: "trova successivo / apri finestra di ricerca",
+search: "cerca",
+replace: "sostituisci",
+replace_command: "sostituisci / apri finestra di ricerca",
+find_next: "trova successivo",
+replace_all: "sostituisci tutti",
+reg_exp: "espressioni regolari",
+match_case: "confronta maiuscole/minuscole<br />",
+not_found: "non trovato.",
+occurrence_replaced: "occorrenze sostituite.",
+search_field_empty: "Campo ricerca vuoto",
+restart_search_at_begin: "Fine del testo raggiunta. Ricomincio dall'inizio.",
+move_popup: "sposta popup di ricerca",
+font_size: "-- Dimensione --",
+go_to_line: "vai alla linea",
+go_to_line_prompt: "vai alla linea numero:",
+undo: "annulla",
+redo: "ripeti",
+change_smooth_selection: "abilita/disabilita alcune caratteristiche della visualizzazione",
+highlight: "abilita/disabilita colorazione della sintassi",
+reset_highlight: "aggiorna colorazione (se non sincronizzata)",
+help: "informazioni su...",
+save: "salva",
+load: "carica",
+line_abbr: "Ln",
+char_abbr: "Ch",
+position: "Posizione",
+total: "Totale",
+close_popup: "chiudi popup",
+shortcuts: "Scorciatoie",
+add_tab: "aggiungi tabulazione",
+remove_tab: "rimuovi tabulazione",
+about_notice: "Avviso: la colorazione della sintassi vale solo con testo piccolo",
+toggle: "Abilita/disabilita editor",
+accesskey: "Accesskey",
+tab: "Tab",
+shift: "Shift",
+ctrl: "Ctrl",
+esc: "Esc",
+processing: "In corso...",
+fullscreen: "fullscreen",
+syntax_selection: "--Syntax--",
+syntax_css: "CSS",
+syntax_html: "HTML",
+syntax_js: "Javascript",
+syntax_php: "Php",
+syntax_python: "Python",
+syntax_vb: "Visual Basic",
+syntax_xml: "Xml",
+syntax_c: "C",
+syntax_cpp: "CPP",
+syntax_basic: "Basic",
+syntax_pas: "Pascal",
+syntax_brainfuck: "Brainfuck",
+syntax_sql: "SQL",
+syntax_ruby: "Ruby",
+syntax_robotstxt: "Robots txt",
+syntax_tsql: "T-SQL",
+syntax_perl: "Perl",
+syntax_coldfusion: "Coldfusion",
+close_tab: "Close file"
+};
Index: /tags/2.0.2/plugins/LocalFilesEditor/editarea/langs/ja.js
===================================================================
--- /tags/2.0.2/plugins/LocalFilesEditor/editarea/langs/ja.js	(revision 3278)
+++ /tags/2.0.2/plugins/LocalFilesEditor/editarea/langs/ja.js	(revision 3278)
@@ -0,0 +1,65 @@
+editAreaLoader.lang["ja"]={
+new_document: "新規作成",
+search_button: "検索・置換",
+search_command: "次を検索 / 検索窓を表示",
+search: "検索",
+replace: "置換",
+replace_command: "置換 / 置換窓を表示",
+find_next: "次を検索",
+replace_all: "全置換",
+reg_exp: "正規表現",
+match_case: "大文字小文字の区別",
+not_found: "見つかりません。",
+occurrence_replaced: "置換しました。",
+search_field_empty: "検索対象文字列が空です。",
+restart_search_at_begin: "終端に達しました、始めに戻ります",
+move_popup: "検索窓を移動",
+font_size: "--フォントサイズ--",
+go_to_line: "指定行へ移動",
+go_to_line_prompt: "指定行へ移動します:",
+undo: "元に戻す",
+redo: "やり直し",
+change_smooth_selection: "スムース表示の切り替え（CPUを使います）",
+highlight: "構文強調表示の切り替え",
+reset_highlight: "構文強調表示のリセット",
+help: "ヘルプを表示",
+save: "保存",
+load: "読み込み",
+line_abbr: "行",
+char_abbr: "文字",
+position: "位置",
+total: "合計",
+close_popup: "ポップアップを閉じる",
+shortcuts: "ショートカット",
+add_tab: "タブを挿入する",
+remove_tab: "タブを削除する",
+about_notice: "注意：構文強調表示は短いテキストでしか有効に機能しません。",
+toggle: "テキストエリアとeditAreaの切り替え",
+accesskey: "アクセスキー",
+tab: "Tab",
+shift: "Shift",
+ctrl: "Ctrl",
+esc: "Esc",
+processing: "処理中です...",
+fullscreen: "fullscreen",
+syntax_selection: "--Syntax--",
+syntax_css: "CSS",
+syntax_html: "HTML",
+syntax_js: "Javascript",
+syntax_php: "Php",
+syntax_python: "Python",
+syntax_vb: "Visual Basic",
+syntax_xml: "Xml",
+syntax_c: "C",
+syntax_cpp: "CPP",
+syntax_basic: "Basic",
+syntax_pas: "Pascal",
+syntax_brainfuck: "Brainfuck",
+syntax_sql: "SQL",
+syntax_ruby: "Ruby",
+syntax_robotstxt: "Robots txt",
+syntax_tsql: "T-SQL",
+syntax_perl: "Perl",
+syntax_coldfusion: "Coldfusion",
+close_tab: "Close file"
+};
Index: /tags/2.0.2/plugins/LocalFilesEditor/editarea/langs/mk.js
===================================================================
--- /tags/2.0.2/plugins/LocalFilesEditor/editarea/langs/mk.js	(revision 3278)
+++ /tags/2.0.2/plugins/LocalFilesEditor/editarea/langs/mk.js	(revision 3278)
@@ -0,0 +1,65 @@
+editAreaLoader.lang["mk"]={
+new_document: "Нов документ",
+search_button: "Најди и замени",
+search_command: "Барај следно / Отвори нов прозорец за пребарување",
+search: "Барај",
+replace: "Замени",
+replace_command: "Замени / Отвори прозорец за пребарување",
+find_next: "најди следно",
+replace_all: "Замени ги сите",
+reg_exp: "Регуларни изрази",
+match_case: "Битна е големината на буквите",
+not_found: "не е пронајдено.",
+occurrence_replaced: "замени.",
+search_field_empty: "Полето за пребарување е празно",
+restart_search_at_begin: "Крај на областа. Стартувај од почеток.",
+move_popup: "Помести го прозорецот",
+font_size: "--Големина на текстот--",
+go_to_line: "Оди на линија",
+go_to_line_prompt: "Оди на линија со број:",
+undo: "Врати",
+redo: "Повтори",
+change_smooth_selection: "Вклучи/исклучи некои карактеристики за приказ (попаметен приказ, но поголемо оптеретување за процесорот)",
+highlight: "Вклучи/исклучи осветлување на синтакса",
+reset_highlight: "Ресетирај го осветлувањето на синтакса (доколку е десинхронизиранo со текстот)",
+help: "За",
+save: "Зачувај",
+load: "Вчитај",
+line_abbr: "Лн",
+char_abbr: "Зн",
+position: "Позиција",
+total: "Вкупно",
+close_popup: "Затвори го прозорецот",
+shortcuts: "Кратенки",
+add_tab: "Додај табулација на текстот",
+remove_tab: "Отстрани ја табулацијата",
+about_notice: "Напомена: Осветлувањето на синтанса е само за краток текст",
+toggle: "Смени начин на уредување",
+accesskey: "Accesskey",
+tab: "Tab",
+shift: "Shift",
+ctrl: "Ctrl",
+esc: "Esc",
+processing: "Обработувам...",
+fullscreen: "Цел прозорец",
+syntax_selection: "--Синтакса--",
+syntax_css: "CSS",
+syntax_html: "HTML",
+syntax_js: "Javascript",
+syntax_php: "Php",
+syntax_python: "Python",
+syntax_vb: "Visual Basic",
+syntax_xml: "Xml",
+syntax_c: "C",
+syntax_cpp: "CPP",
+syntax_basic: "Basic",
+syntax_pas: "Pascal",
+syntax_brainfuck: "Brainfuck",
+syntax_sql: "SQL",
+syntax_ruby: "Ruby",
+syntax_robotstxt: "Robots txt",
+syntax_tsql: "T-SQL",
+syntax_perl: "Perl",
+syntax_coldfusion: "Coldfusion",
+close_tab: "Избери датотека"
+};
Index: /tags/2.0.2/plugins/LocalFilesEditor/editarea/langs/nl.js
===================================================================
--- /tags/2.0.2/plugins/LocalFilesEditor/editarea/langs/nl.js	(revision 3278)
+++ /tags/2.0.2/plugins/LocalFilesEditor/editarea/langs/nl.js	(revision 3278)
@@ -0,0 +1,65 @@
+editAreaLoader.lang["nl"]={
+new_document: "nieuw leeg document",
+search_button: "zoek en vervang",
+search_command: "zoek volgende / zoekscherm openen",
+search: "zoek",
+replace: "vervang",
+replace_command: "vervang / zoekscherm openen",
+find_next: "volgende vinden",
+replace_all: "alles vervangen",
+reg_exp: "reguliere expressies",
+match_case: "hoofdletter gevoelig",
+not_found: "niet gevonden.",
+occurrence_replaced: "object vervangen.",
+search_field_empty: "Zoek veld leeg",
+restart_search_at_begin: "Niet meer instanties gevonden, begin opnieuw",
+move_popup: "versleep zoek scherm",
+font_size: "--Letter grootte--",
+go_to_line: "Ga naar regel",
+go_to_line_prompt: "Ga naar regel nummer:",
+undo: "Ongedaan maken",
+redo: "Opnieuw doen",
+change_smooth_selection: "zet wat schermopties aan/uit (kan langzamer zijn)",
+highlight: "zet syntax highlight aan/uit",
+reset_highlight: "reset highlight (indien gedesynchronizeerd)",
+help: "informatie",
+save: "opslaan",
+load: "laden",
+line_abbr: "Ln",
+char_abbr: "Ch",
+position: "Positie",
+total: "Totaal",
+close_popup: "Popup sluiten",
+shortcuts: "Snelkoppelingen",
+add_tab: "voeg tabs toe in tekst",
+remove_tab: "verwijder tabs uit tekst",
+about_notice: "Notitie: syntax highlight functie is alleen voor kleine tekst",
+toggle: "geavanceerde bewerkingsopties",
+accesskey: "Accessknop",
+tab: "Tab",
+shift: "Shift",
+ctrl: "Ctrl",
+esc: "Esc",
+processing: "Verwerken...",
+fullscreen: "fullscreen",
+syntax_selection: "--Syntax--",
+syntax_css: "CSS",
+syntax_html: "HTML",
+syntax_js: "Javascript",
+syntax_php: "Php",
+syntax_python: "Python",
+syntax_vb: "Visual Basic",
+syntax_xml: "Xml",
+syntax_c: "C",
+syntax_cpp: "CPP",
+syntax_basic: "Basic",
+syntax_pas: "Pascal",
+syntax_brainfuck: "Brainfuck",
+syntax_sql: "SQL",
+syntax_ruby: "Ruby",
+syntax_robotstxt: "Robots txt",
+syntax_tsql: "T-SQL",
+syntax_perl: "Perl",
+syntax_coldfusion: "Coldfusion",
+close_tab: "Close file"
+};
Index: /tags/2.0.2/plugins/LocalFilesEditor/editarea/langs/pl.js
===================================================================
--- /tags/2.0.2/plugins/LocalFilesEditor/editarea/langs/pl.js	(revision 3278)
+++ /tags/2.0.2/plugins/LocalFilesEditor/editarea/langs/pl.js	(revision 3278)
@@ -0,0 +1,65 @@
+editAreaLoader.lang["pl"]={
+new_document: "nowy dokument",
+search_button: "znajdź i zamień",
+search_command: "znajdź następny",
+search: "znajdź",
+replace: "zamień",
+replace_command: "zamień",
+find_next: "następny",
+replace_all: "zamień wszystko",
+reg_exp: "wyrażenie regularne",
+match_case: "uwzględnij wielkość liter<br />",
+not_found: "nie znaleziono.",
+occurrence_replaced: "wystąpień zamieniono.",
+search_field_empty: "Nie wprowadzono tekstu",
+restart_search_at_begin: "Koniec dokumentu. Wyszukiwanie od początku.",
+move_popup: "przesuń okienko wyszukiwania",
+font_size: "Rozmiar",
+go_to_line: "idź do linii",
+go_to_line_prompt: "numer linii:",
+undo: "cofnij",
+redo: "przywróć",
+change_smooth_selection: "włącz/wyłącz niektóre opcje wyglądu (zaawansowane opcje wyglądu obciążają procesor)",
+highlight: "włącz/wyłącz podświetlanie składni",
+reset_highlight: "odśwież podświetlanie składni (jeśli rozsynchronizowało się z tekstem)",
+help: "o programie",
+save: "zapisz",
+load: "otwórz",
+line_abbr: "Ln",
+char_abbr: "Zn",
+position: "Pozycja",
+total: "W sumie",
+close_popup: "zamknij okienko",
+shortcuts: "Skróty klawiaturowe",
+add_tab: "dodaj wcięcie do zaznaczonego tekstu",
+remove_tab: "usuń wcięcie",
+about_notice: "Uwaga: podświetlanie składni nie jest zalecane dla długich tekstów",
+toggle: "Włącz/wyłącz edytor",
+accesskey: "Alt+",
+tab: "Tab",
+shift: "Shift",
+ctrl: "Ctrl",
+esc: "Esc",
+processing: "Przetwarzanie...",
+fullscreen: "fullscreen",
+syntax_selection: "--Syntax--",
+syntax_css: "CSS",
+syntax_html: "HTML",
+syntax_js: "Javascript",
+syntax_php: "Php",
+syntax_python: "Python",
+syntax_vb: "Visual Basic",
+syntax_xml: "Xml",
+syntax_c: "C",
+syntax_cpp: "CPP",
+syntax_basic: "Basic",
+syntax_pas: "Pascal",
+syntax_brainfuck: "Brainfuck",
+syntax_sql: "SQL",
+syntax_ruby: "Ruby",
+syntax_robotstxt: "Robots txt",
+syntax_tsql: "T-SQL",
+syntax_perl: "Perl",
+syntax_coldfusion: "Coldfusion",
+close_tab: "Close file"
+};
Index: /tags/2.0.2/plugins/LocalFilesEditor/editarea/langs/pt.js
===================================================================
--- /tags/2.0.2/plugins/LocalFilesEditor/editarea/langs/pt.js	(revision 3278)
+++ /tags/2.0.2/plugins/LocalFilesEditor/editarea/langs/pt.js	(revision 3278)
@@ -0,0 +1,65 @@
+editAreaLoader.lang["pt"]={
+new_document: "Novo documento",
+search_button: "Localizar e substituir",
+search_command: "Localizar próximo",
+search: "Localizar",
+replace: "Substituir",
+replace_command: "Substituir",
+find_next: "Localizar",
+replace_all: "Subst. tudo",
+reg_exp: "Expressões regulares",
+match_case: "Diferenciar maiúsculas e minúsculas",
+not_found: "Não encontrado.",
+occurrence_replaced: "Ocorrências substituidas",
+search_field_empty: "Campo localizar vazio.",
+restart_search_at_begin: "Fim das ocorrências. Recomeçar do inicio.",
+move_popup: "Mover janela",
+font_size: "--Tamanho da fonte--",
+go_to_line: "Ir para linha",
+go_to_line_prompt: "Ir para a linha:",
+undo: "Desfazer",
+redo: "Refazer",
+change_smooth_selection: "Opções visuais",
+highlight: "Cores de sintaxe",
+reset_highlight: "Resetar cores (se não sincronizado)",
+help: "Sobre",
+save: "Salvar",
+load: "Carregar",
+line_abbr: "Ln",
+char_abbr: "Ch",
+position: "Posição",
+total: "Total",
+close_popup: "Fechar",
+shortcuts: "Shortcuts",
+add_tab: "Adicionar tabulação",
+remove_tab: "Remover tabulação",
+about_notice: "Atenção: Cores de sintaxe são indicados somente para textos pequenos",
+toggle: "Exibir editor",
+accesskey: "Accesskey",
+tab: "Tab",
+shift: "Shift",
+ctrl: "Ctrl",
+esc: "Esc",
+processing: "Processando...",
+fullscreen: "fullscreen",
+syntax_selection: "--Syntax--",
+syntax_css: "CSS",
+syntax_html: "HTML",
+syntax_js: "Javascript",
+syntax_php: "Php",
+syntax_python: "Python",
+syntax_vb: "Visual Basic",
+syntax_xml: "Xml",
+syntax_c: "C",
+syntax_cpp: "CPP",
+syntax_basic: "Basic",
+syntax_pas: "Pascal",
+syntax_brainfuck: "Brainfuck",
+syntax_sql: "SQL",
+syntax_ruby: "Ruby",
+syntax_robotstxt: "Robots txt",
+syntax_tsql: "T-SQL",
+syntax_perl: "Perl",
+syntax_coldfusion: "Coldfusion",
+close_tab: "Close file"
+};
Index: /tags/2.0.2/plugins/LocalFilesEditor/editarea/langs/ru.js
===================================================================
--- /tags/2.0.2/plugins/LocalFilesEditor/editarea/langs/ru.js	(revision 3278)
+++ /tags/2.0.2/plugins/LocalFilesEditor/editarea/langs/ru.js	(revision 3278)
@@ -0,0 +1,65 @@
+editAreaLoader.lang["ru"]={
+new_document: "новый пустой документ",
+search_button: "поиск и замена",
+search_command: "искать следующий / открыть панель поиска",
+search: "поиск",
+replace: "замена",
+replace_command: "заменить / открыть панель поиска",
+find_next: "найти следующее",
+replace_all: "заменить все",
+reg_exp: "регулярное выражение",
+match_case: "учитывать регистр",
+not_found: "не найдено.",
+occurrence_replaced: "вхождение заменено.",
+search_field_empty: "Поле поиска пустое",
+restart_search_at_begin: "Достигнут конец документа. Начинаю с начала.",
+move_popup: "переместить окно поиска",
+font_size: "--Размер шрифта--",
+go_to_line: "перейти к строке",
+go_to_line_prompt: "перейти к строке номер:",
+undo: "отменить",
+redo: "вернуть",
+change_smooth_selection: "включить/отключить некоторые функции просмотра (более красиво, но больше использует процессор)",
+highlight: "переключить подсветку синтаксиса включена/выключена",
+reset_highlight: "восстановить подсветку (если разсинхронизирована от текста)",
+help: "о программе",
+save: "сохранить",
+load: "загрузить",
+line_abbr: "Стр",
+char_abbr: "Стлб",
+position: "Позиция",
+total: "Всего",
+close_popup: "закрыть всплывающее окно",
+shortcuts: "Горячие клавиши",
+add_tab: "добавить табуляцию в текст",
+remove_tab: "убрать табуляцию из текста",
+about_notice: "Внимание: функция подсветки синтаксиса только для небольших текстов",
+toggle: "Переключить редактор",
+accesskey: "Горячая клавиша",
+tab: "Tab",
+shift: "Shift",
+ctrl: "Ctrl",
+esc: "Esc",
+processing: "Обработка...",
+fullscreen: "полный экран",
+syntax_selection: "--Синтакс--",
+syntax_css: "CSS",
+syntax_html: "HTML",
+syntax_js: "Javascript",
+syntax_php: "Php",
+syntax_python: "Python",
+syntax_vb: "Visual Basic",
+syntax_xml: "Xml",
+syntax_c: "C",
+syntax_cpp: "CPP",
+syntax_basic: "Basic",
+syntax_pas: "Pascal",
+syntax_brainfuck: "Brainfuck",
+syntax_sql: "SQL",
+syntax_ruby: "Ruby",
+syntax_robotstxt: "Robots txt",
+syntax_tsql: "T-SQL",
+syntax_perl: "Perl",
+syntax_coldfusion: "Coldfusion",
+close_tab: "Закрыть файл"
+};
Index: /tags/2.0.2/plugins/LocalFilesEditor/editarea/langs/sk.js
===================================================================
--- /tags/2.0.2/plugins/LocalFilesEditor/editarea/langs/sk.js	(revision 3278)
+++ /tags/2.0.2/plugins/LocalFilesEditor/editarea/langs/sk.js	(revision 3278)
@@ -0,0 +1,65 @@
+editAreaLoader.lang["sk"]={
+new_document: "nový prázdy dokument",
+search_button: "vyhľadaj a nahraď",
+search_command: "hľadaj ďalsšie / otvor vyhľadávacie pole",
+search: "hľadaj",
+replace: "nahraď",
+replace_command: "nahraď / otvor vyhľadávacie pole",
+find_next: "nájdi ďalšie",
+replace_all: "nahraď všetko",
+reg_exp: "platné výrazy",
+match_case: "zhodujúce sa výrazy",
+not_found: "nenájdené.",
+occurrence_replaced: "výskyty nahradené.",
+search_field_empty: "Pole vyhľadávanie je prádzne",
+restart_search_at_begin: "End of area reached. Restart at begin.",
+move_popup: "presuň vyhľadávacie okno",
+font_size: "--Veľkosť textu--",
+go_to_line: "prejdi na riadok",
+go_to_line_prompt: "prejdi na riadok:",
+undo: "krok späť",
+redo: "prepracovať",
+change_smooth_selection: "povoliť/zamietnúť niektoré zo zobrazených funkcií (účelnejšie zobrazenie vyžaduje  väčšie zaťaženie procesora CPU)",
+highlight: "prepnúť zvýrazňovanie syntaxe zap/vyp",
+reset_highlight: "zrušiť zvýrazňovanie (ak je nesynchronizované s textom)",
+help: "o programe",
+save: "uložiť",
+load: "načítať",
+line_abbr: "Ln",
+char_abbr: "Ch",
+position: "Pozícia",
+total: "Spolu",
+close_popup: "zavrieť okno",
+shortcuts: "Skratky",
+add_tab: "pridať tabulovanie textu",
+remove_tab: "odstrániť tabulovanie textu",
+about_notice: "Upozornenie: funkcia zvýrazňovania syntaxe je dostupná iba pre malý text",
+toggle: "Prepnúť editor",
+accesskey: "Accesskey",
+tab: "Záložka",
+shift: "Shift",
+ctrl: "Ctrl",
+esc: "Esc",
+processing: "Spracúvam...",
+fullscreen: "cel=a obrazovka",
+syntax_selection: "--Vyber Syntax--",
+syntax_css: "CSS",
+syntax_html: "HTML",
+syntax_js: "Javascript",
+syntax_php: "Php",
+syntax_python: "Python",
+syntax_vb: "Visual Basic",
+syntax_xml: "Xml",
+syntax_c: "C",
+syntax_cpp: "CPP",
+syntax_basic: "Basic",
+syntax_pas: "Pascal",
+syntax_brainfuck: "Brainfuck",
+syntax_sql: "SQL",
+syntax_ruby: "Ruby",
+syntax_robotstxt: "Robots txt",
+syntax_tsql: "T-SQL",
+syntax_perl: "Perl",
+syntax_coldfusion: "Coldfusion",
+close_tab: "Close file"
+};
Index: /tags/2.0.2/plugins/LocalFilesEditor/editarea/reg_syntax/css.js
===================================================================
--- /tags/2.0.2/plugins/LocalFilesEditor/editarea/reg_syntax/css.js	(revision 3278)
+++ /tags/2.0.2/plugins/LocalFilesEditor/editarea/reg_syntax/css.js	(revision 3278)
@@ -0,0 +1,84 @@
+editAreaLoader.load_syntax["css"] = {
+	'COMMENT_SINGLE' : {1 : '@'}
+	,'COMMENT_MULTI' : {'/*' : '*/'}
+	,'QUOTEMARKS' : ['"', "'"]
+	,'KEYWORD_CASE_SENSITIVE' : false
+	,'KEYWORDS' : {
+		'attributes' : [
+			'aqua', 'azimuth', 'background-attachment', 'background-color',
+			'background-image', 'background-position', 'background-repeat',
+			'background', 'border-bottom-color', 'border-bottom-style',
+			'border-bottom-width', 'border-left-color', 'border-left-style',
+			'border-left-width', 'border-right', 'border-right-color',
+			'border-right-style', 'border-right-width', 'border-top-color',
+			'border-top-style', 'border-top-width','border-bottom', 'border-collapse',
+			'border-left', 'border-width', 'border-color', 'border-spacing',
+			'border-style', 'border-top', 'border',  'caption-side',
+			'clear', 'clip', 'color', 'content', 'counter-increment', 'counter-reset',
+			'cue-after', 'cue-before', 'cue', 'cursor', 'direction', 'display',
+			'elevation', 'empty-cells', 'float', 'font-family', 'font-size',
+			'font-size-adjust', 'font-stretch', 'font-style', 'font-variant',
+			'font-weight', 'font', 'height', 'letter-spacing', 'line-height',
+			'list-style', 'list-style-image', 'list-style-position', 'list-style-type',
+			'margin-bottom', 'margin-left', 'margin-right', 'margin-top', 'margin',
+			'marker-offset', 'marks', 'max-height', 'max-width', 'min-height',
+			'min-width', 'opacity', 'orphans', 'outline', 'outline-color', 'outline-style',
+			'outline-width', 'overflow', 'padding-bottom', 'padding-left',
+			'padding-right', 'padding-top', 'padding', 'page', 'page-break-after',
+			'page-break-before', 'page-break-inside', 'pause-after', 'pause-before',
+			'pause', 'pitch', 'pitch-range',  'play-during', 'position', 'quotes',
+			'richness', 'right', 'size', 'speak-header', 'speak-numeral', 'speak-punctuation',
+			'speak', 'speech-rate', 'stress', 'table-layout', 'text-align', 'text-decoration',
+			'text-indent', 'text-shadow', 'text-transform', 'top', 'unicode-bidi',
+			'vertical-align', 'visibility', 'voice-family', 'volume', 'white-space', 'widows',
+			'width', 'word-spacing', 'z-index', 'bottom', 'left'
+		]
+		,'values' : [
+			'above', 'absolute', 'always', 'armenian', 'aural', 'auto', 'avoid',
+			'baseline', 'behind', 'below', 'bidi-override', 'black', 'blue', 'blink', 'block', 'bold', 'bolder', 'both',
+			'capitalize', 'center-left', 'center-right', 'center', 'circle', 'cjk-ideographic', 
+            'close-quote', 'collapse', 'condensed', 'continuous', 'crop', 'crosshair', 'cross', 'cursive',
+			'dashed', 'decimal-leading-zero', 'decimal', 'default', 'digits', 'disc', 'dotted', 'double',
+			'e-resize', 'embed', 'extra-condensed', 'extra-expanded', 'expanded',
+			'fantasy', 'far-left', 'far-right', 'faster', 'fast', 'fixed', 'fuchsia',
+			'georgian', 'gray', 'green', 'groove', 'hebrew', 'help', 'hidden', 'hide', 'higher',
+			'high', 'hiragana-iroha', 'hiragana', 'icon', 'inherit', 'inline-table', 'inline',
+			'inset', 'inside', 'invert', 'italic', 'justify', 'katakana-iroha', 'katakana',
+			'landscape', 'larger', 'large', 'left-side', 'leftwards', 'level', 'lighter', 'lime', 'line-through', 'list-item', 'loud', 'lower-alpha', 'lower-greek', 'lower-roman', 'lowercase', 'ltr', 'lower', 'low',
+			'maroon', 'medium', 'message-box', 'middle', 'mix', 'monospace',
+			'n-resize', 'narrower', 'navy', 'ne-resize', 'no-close-quote', 'no-open-quote', 'no-repeat', 'none', 'normal', 'nowrap', 'nw-resize',
+			'oblique', 'olive', 'once', 'open-quote', 'outset', 'outside', 'overline',
+			'pointer', 'portrait', 'purple', 'px',
+			'red', 'relative', 'repeat-x', 'repeat-y', 'repeat', 'rgb', 'ridge', 'right-side', 'rightwards',
+			's-resize', 'sans-serif', 'scroll', 'se-resize', 'semi-condensed', 'semi-expanded', 'separate', 'serif', 'show', 'silent', 'silver', 'slow', 'slower', 'small-caps', 'small-caption', 'smaller', 'soft', 'solid', 'spell-out', 'square',
+			'static', 'status-bar', 'super', 'sw-resize',
+			'table-caption', 'table-cell', 'table-column', 'table-column-group', 'table-footer-group', 'table-header-group', 'table-row', 'table-row-group', 'teal', 'text', 'text-bottom', 'text-top', 'thick', 'thin', 'transparent',
+			'ultra-condensed', 'ultra-expanded', 'underline', 'upper-alpha', 'upper-latin', 'upper-roman', 'uppercase', 'url',
+			'visible',
+			'w-resize', 'wait', 'white', 'wider',
+			'x-fast', 'x-high', 'x-large', 'x-loud', 'x-low', 'x-small', 'x-soft', 'xx-large', 'xx-small',
+			'yellow', 'yes'
+		]
+		,'specials' : [
+			'important'
+		]
+	}
+	,'OPERATORS' :[
+		':', ';', '!', '.', '#'
+	]
+	,'DELIMITERS' :[
+		'{', '}'
+	]
+	,'STYLES' : {
+		'COMMENTS': 'color: #AAAAAA;'
+		,'QUOTESMARKS': 'color: #6381F8;'
+		,'KEYWORDS' : {
+			'attributes' : 'color: #48BDDF;'
+			,'values' : 'color: #2B60FF;'
+			,'specials' : 'color: #FF0000;'
+			}
+		,'OPERATORS' : 'color: #FF00FF;'
+		,'DELIMITERS' : 'color: #60CA00;'
+				
+	}
+};
Index: /tags/2.0.2/plugins/LocalFilesEditor/editarea/reg_syntax/html.js
===================================================================
--- /tags/2.0.2/plugins/LocalFilesEditor/editarea/reg_syntax/html.js	(revision 3278)
+++ /tags/2.0.2/plugins/LocalFilesEditor/editarea/reg_syntax/html.js	(revision 3278)
@@ -0,0 +1,53 @@
+/*
+* last update: 2006-08-24
+*/
+
+editAreaLoader.load_syntax["html"] = {
+	'COMMENT_SINGLE' : {}
+	,'COMMENT_MULTI' : {
+    '<!--' : '-->',
+    '{*' : '*}'
+  }
+	,'QUOTEMARKS' : {1: "'", 2: '"'}
+	,'KEYWORD_CASE_SENSITIVE' : false
+	,'KEYWORDS' : {
+	}
+	,'OPERATORS' :[
+	]
+	,'DELIMITERS' :[
+	]
+	,'REGEXPS' : {
+		'doctype' : {
+			'search' : '()(<!DOCTYPE[^>]*>)()'
+			,'class' : 'doctype'
+			,'modifiers' : ''
+			,'execute' : 'before' // before or after
+		}
+		,'tags' : {
+			'search' : '(<)(/?[a-z][^ \r\n\t>]*)([^>]*>)'
+			,'class' : 'tags'
+			,'modifiers' : 'gi'
+			,'execute' : 'before' // before or after
+		}
+		,'attributes' : {
+			'search' : '( |\n|\r|\t)([^ \r\n\t=]+)(=)'
+			,'class' : 'attributes'
+			,'modifiers' : 'g'
+			,'execute' : 'before' // before or after
+		}
+	}
+	,'STYLES' : {
+		'COMMENTS': 'color: #AAAAAA;'
+		,'QUOTESMARKS': 'color: #6381F8;'
+		,'KEYWORDS' : {
+			}
+		,'OPERATORS' : 'color: #E775F0;'
+		,'DELIMITERS' : ''
+		,'REGEXPS' : {
+			'attributes': 'color: #B1AC41;'
+			,'tags': 'color: #E62253;'
+			,'doctype': 'color: #8DCFB5;'
+			,'test': 'color: #00FF00;'
+		}	
+	}		
+};
Index: /tags/2.0.2/plugins/LocalFilesEditor/editarea/reg_syntax/index.php
===================================================================
--- /tags/2.0.2/plugins/LocalFilesEditor/editarea/reg_syntax/index.php	(revision 3278)
+++ /tags/2.0.2/plugins/LocalFilesEditor/editarea/reg_syntax/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/plugins/LocalFilesEditor/editarea/reg_syntax/php.js
===================================================================
--- /tags/2.0.2/plugins/LocalFilesEditor/editarea/reg_syntax/php.js	(revision 3278)
+++ /tags/2.0.2/plugins/LocalFilesEditor/editarea/reg_syntax/php.js	(revision 3278)
@@ -0,0 +1,156 @@
+editAreaLoader.load_syntax["php"] = {
+	'COMMENT_SINGLE' : {1 : '//', 2 : '#'}
+	,'COMMENT_MULTI' : {'/*' : '*/'}
+	,'QUOTEMARKS' : {1: "'", 2: '"'}
+	,'KEYWORD_CASE_SENSITIVE' : false
+	,'KEYWORDS' : {
+		'statements' : [
+			'include', 'require', 'include_once', 'require_once',
+			'for', 'foreach', 'as', 'if', 'elseif', 'else', 'while', 'do', 'endwhile',
+            'endif', 'switch', 'case', 'endswitch',
+			'return', 'break', 'continue'
+		]
+		,'reserved' : [
+			'_GET', '_POST', '_SESSION', '_SERVER', '_FILES', '_ENV', '_COOKIE', '_REQUEST',
+			'null', '__LINE__', '__FILE__',
+			'false', '&lt;?php', '?&gt;', '&lt;?',
+			'&lt;script language', '&lt;/script&gt;',
+			'true', 'var', 'default',
+			'function', 'class', 'new', '&amp;new', 'this',
+			'__FUNCTION__', '__CLASS__', '__METHOD__', 'PHP_VERSION',
+			'PHP_OS', 'DEFAULT_INCLUDE_PATH', 'PEAR_INSTALL_DIR', 'PEAR_EXTENSION_DIR',
+			'PHP_EXTENSION_DIR', 'PHP_BINDIR', 'PHP_LIBDIR', 'PHP_DATADIR', 'PHP_SYSCONFDIR',
+			'PHP_LOCALSTATEDIR', 'PHP_CONFIG_FILE_PATH', 'PHP_OUTPUT_HANDLER_START', 'PHP_OUTPUT_HANDLER_CONT',
+			'PHP_OUTPUT_HANDLER_END', 'E_ERROR', 'E_WARNING', 'E_PARSE', 'E_NOTICE',
+			'E_CORE_ERROR', 'E_CORE_WARNING', 'E_COMPILE_ERROR', 'E_COMPILE_WARNING', 'E_USER_ERROR',
+			'E_USER_WARNING', 'E_USER_NOTICE', 'E_ALL'
+			
+		]
+		,'functions' : [
+			'func_num_args', 'func_get_arg', 'func_get_args', 'strlen', 'strcmp', 'strncmp', 'strcasecmp', 'strncasecmp', 'each', 'error_reporting', 'define', 'defined',
+			'trigger_error', 'user_error', 'set_error_handler', 'restore_error_handler', 'get_declared_classes', 'get_loaded_extensions',
+			'extension_loaded', 'get_extension_funcs', 'debug_backtrace',
+			'constant', 'bin2hex', 'sleep', 'usleep', 'time', 'mktime', 'gmmktime', 'strftime', 'gmstrftime', 'strtotime', 'date', 'gmdate', 'getdate', 'localtime', 'checkdate', 'flush', 'wordwrap', 'htmlspecialchars', 'htmlentities', 'html_entity_decode', 'md5', 'md5_file', 'crc32', 'getimagesize', 'image_type_to_mime_type', 'phpinfo', 'phpversion', 'phpcredits', 'strnatcmp', 'strnatcasecmp', 'substr_count', 'strspn', 'strcspn', 'strtok', 'strtoupper', 'strtolower', 'strpos', 'strrpos', 'strrev', 'hebrev', 'hebrevc', 'nl2br', 'basename', 'dirname', 'pathinfo', 'stripslashes', 'stripcslashes', 'strstr', 'stristr', 'strrchr', 'str_shuffle', 'str_word_count', 'strcoll', 'substr', 'substr_replace', 'quotemeta', 'ucfirst', 'ucwords', 'strtr', 'addslashes', 'addcslashes', 'rtrim', 'str_replace', 'str_repeat', 'count_chars', 'chunk_split', 'trim', 'ltrim', 'strip_tags', 'similar_text', 'explode', 'implode', 'setlocale', 'localeconv',
+			'parse_str', 'str_pad', 'chop', 'strchr', 'sprintf', 'printf', 'vprintf', 'vsprintf', 'sscanf', 'fscanf', 'parse_url', 'urlencode', 'urldecode', 'rawurlencode', 'rawurldecode', 'readlink', 'linkinfo', 'link', 'unlink', 'exec', 'system', 'escapeshellcmd', 'escapeshellarg', 'passthru', 'shell_exec', 'proc_open', 'proc_close', 'rand', 'srand', 'getrandmax', 'mt_rand', 'mt_srand', 'mt_getrandmax', 'base64_decode', 'base64_encode', 'abs', 'ceil', 'floor', 'round', 'is_finite', 'is_nan', 'is_infinite', 'bindec', 'hexdec', 'octdec', 'decbin', 'decoct', 'dechex', 'base_convert', 'number_format', 'fmod', 'ip2long', 'long2ip', 'getenv', 'putenv', 'getopt', 'microtime', 'gettimeofday', 'getrusage', 'uniqid', 'quoted_printable_decode', 'set_time_limit', 'get_cfg_var', 'magic_quotes_runtime', 'set_magic_quotes_runtime', 'get_magic_quotes_gpc', 'get_magic_quotes_runtime',
+			'import_request_variables', 'error_log', 'serialize', 'unserialize', 'memory_get_usage', 'var_dump', 'var_export', 'debug_zval_dump', 'print_r','highlight_file', 'show_source', 'highlight_string', 'ini_get', 'ini_get_all', 'ini_set', 'ini_alter', 'ini_restore', 'get_include_path', 'set_include_path', 'restore_include_path', 'setcookie', 'header', 'headers_sent', 'connection_aborted', 'connection_status', 'ignore_user_abort', 'parse_ini_file', 'is_uploaded_file', 'move_uploaded_file', 'intval', 'floatval', 'doubleval', 'strval', 'gettype', 'settype', 'is_null', 'is_resource', 'is_bool', 'is_long', 'is_float', 'is_int', 'is_integer', 'is_double', 'is_real', 'is_numeric', 'is_string', 'is_array', 'is_object', 'is_scalar',
+			'ereg', 'ereg_replace', 'eregi', 'eregi_replace', 'split', 'spliti', 'join', 'sql_regcase', 'dl', 'pclose', 'popen', 'readfile', 'rewind', 'rmdir', 'umask', 'fclose', 'feof', 'fgetc', 'fgets', 'fgetss', 'fread', 'fopen', 'fpassthru', 'ftruncate', 'fstat', 'fseek', 'ftell', 'fflush', 'fwrite', 'fputs', 'mkdir', 'rename', 'copy', 'tempnam', 'tmpfile', 'file', 'file_get_contents', 'stream_select', 'stream_context_create', 'stream_context_set_params', 'stream_context_set_option', 'stream_context_get_options', 'stream_filter_prepend', 'stream_filter_append', 'fgetcsv', 'flock', 'get_meta_tags', 'stream_set_write_buffer', 'set_file_buffer', 'set_socket_blocking', 'stream_set_blocking', 'socket_set_blocking', 'stream_get_meta_data', 'stream_register_wrapper', 'stream_wrapper_register', 'stream_set_timeout', 'socket_set_timeout', 'socket_get_status', 'realpath', 'fnmatch', 'fsockopen', 'pfsockopen', 'pack', 'unpack', 'get_browser', 'crypt', 'opendir', 'closedir', 'chdir', 'getcwd', 'rewinddir', 'readdir', 'dir', 'glob', 'fileatime', 'filectime', 'filegroup', 'fileinode', 'filemtime', 'fileowner', 'fileperms', 'filesize', 'filetype', 'file_exists', 'is_writable', 'is_writeable', 'is_readable', 'is_executable', 'is_file', 'is_dir', 'is_link', 'stat', 'lstat', 'chown',
+			'touch', 'clearstatcache', 'mail', 'ob_start', 'ob_flush', 'ob_clean', 'ob_end_flush', 'ob_end_clean', 'ob_get_flush', 'ob_get_clean', 'ob_get_length', 'ob_get_level', 'ob_get_status', 'ob_get_contents', 'ob_implicit_flush', 'ob_list_handlers', 'ksort', 'krsort', 'natsort', 'natcasesort', 'asort', 'arsort', 'sort', 'rsort', 'usort', 'uasort', 'uksort', 'shuffle', 'array_walk', 'count', 'end', 'prev', 'next', 'reset', 'current', 'key', 'min', 'max', 'in_array', 'array_search', 'extract', 'compact', 'array_fill', 'range', 'array_multisort', 'array_push', 'array_pop', 'array_shift', 'array_unshift', 'array_splice', 'array_slice', 'array_merge', 'array_merge_recursive', 'array_keys', 'array_values', 'array_count_values', 'array_reverse', 'array_reduce', 'array_pad', 'array_flip', 'array_change_key_case', 'array_rand', 'array_unique', 'array_intersect', 'array_intersect_assoc', 'array_diff', 'array_diff_assoc', 'array_sum', 'array_filter', 'array_map', 'array_chunk', 'array_key_exists', 'pos', 'sizeof', 'key_exists', 'assert', 'assert_options', 'version_compare', 'ftok', 'str_rot13', 'aggregate',
+			'session_name', 'session_module_name', 'session_save_path', 'session_id', 'session_regenerate_id', 'session_decode', 'session_register', 'session_unregister', 'session_is_registered', 'session_encode',
+			'session_start', 'session_destroy', 'session_unset', 'session_set_save_handler', 'session_cache_limiter', 'session_cache_expire', 'session_set_cookie_params', 'session_get_cookie_params', 'session_write_close', 'preg_match', 'preg_match_all', 'preg_replace', 'preg_replace_callback', 'preg_split', 'preg_quote', 'preg_grep', 'overload', 'ctype_alnum', 'ctype_alpha', 'ctype_cntrl', 'ctype_digit', 'ctype_lower', 'ctype_graph', 'ctype_print', 'ctype_punct', 'ctype_space', 'ctype_upper', 'ctype_xdigit', 'virtual', 'apache_request_headers', 'apache_note', 'apache_lookup_uri', 'apache_child_terminate', 'apache_setenv', 'apache_response_headers', 'apache_get_version', 'getallheaders', 'mysql_connect', 'mysql_pconnect', 'mysql_close', 'mysql_select_db', 'mysql_create_db', 'mysql_drop_db', 'mysql_query', 'mysql_unbuffered_query', 'mysql_db_query', 'mysql_list_dbs', 'mysql_list_tables', 'mysql_list_fields', 'mysql_list_processes', 'mysql_error', 'mysql_errno', 'mysql_affected_rows', 'mysql_insert_id', 'mysql_result', 'mysql_num_rows', 'mysql_num_fields', 'mysql_fetch_row', 'mysql_fetch_array', 'mysql_fetch_assoc', 'mysql_fetch_object', 'mysql_data_seek', 'mysql_fetch_lengths', 'mysql_fetch_field', 'mysql_field_seek', 'mysql_free_result', 'mysql_field_name', 'mysql_field_table', 'mysql_field_len', 'mysql_field_type', 'mysql_field_flags', 'mysql_escape_string', 'mysql_real_escape_string', 'mysql_stat',
+			'mysql_thread_id', 'mysql_client_encoding', 'mysql_get_client_info', 'mysql_get_host_info', 'mysql_get_proto_info', 'mysql_get_server_info', 'mysql_info', 'mysql', 'mysql_fieldname', 'mysql_fieldtable', 'mysql_fieldlen', 'mysql_fieldtype', 'mysql_fieldflags', 'mysql_selectdb', 'mysql_createdb', 'mysql_dropdb', 'mysql_freeresult', 'mysql_numfields', 'mysql_numrows', 'mysql_listdbs', 'mysql_listtables', 'mysql_listfields', 'mysql_db_name', 'mysql_dbname', 'mysql_tablename', 'mysql_table_name', 'pg_connect', 'pg_pconnect', 'pg_close', 'pg_connection_status', 'pg_connection_busy', 'pg_connection_reset', 'pg_host', 'pg_dbname', 'pg_port', 'pg_tty', 'pg_options', 'pg_ping', 'pg_query', 'pg_send_query', 'pg_cancel_query', 'pg_fetch_result', 'pg_fetch_row', 'pg_fetch_assoc', 'pg_fetch_array', 'pg_fetch_object', 'pg_fetch_all', 'pg_affected_rows', 'pg_get_result', 'pg_result_seek', 'pg_result_status', 'pg_free_result', 'pg_last_oid', 'pg_num_rows', 'pg_num_fields', 'pg_field_name', 'pg_field_num', 'pg_field_size', 'pg_field_type', 'pg_field_prtlen', 'pg_field_is_null', 'pg_get_notify', 'pg_get_pid', 'pg_result_error', 'pg_last_error', 'pg_last_notice', 'pg_put_line', 'pg_end_copy', 'pg_copy_to', 'pg_copy_from',
+			'pg_trace', 'pg_untrace', 'pg_lo_create', 'pg_lo_unlink', 'pg_lo_open', 'pg_lo_close', 'pg_lo_read', 'pg_lo_write', 'pg_lo_read_all', 'pg_lo_import', 'pg_lo_export', 'pg_lo_seek', 'pg_lo_tell', 'pg_escape_string', 'pg_escape_bytea', 'pg_unescape_bytea', 'pg_client_encoding', 'pg_set_client_encoding', 'pg_meta_data', 'pg_convert', 'pg_insert', 'pg_update', 'pg_delete', 'pg_select', 'pg_exec', 'pg_getlastoid', 'pg_cmdtuples', 'pg_errormessage', 'pg_numrows', 'pg_numfields', 'pg_fieldname', 'pg_fieldsize', 'pg_fieldtype', 'pg_fieldnum', 'pg_fieldprtlen', 'pg_fieldisnull', 'pg_freeresult', 'pg_result', 'pg_loreadall', 'pg_locreate', 'pg_lounlink', 'pg_loopen', 'pg_loclose', 'pg_loread', 'pg_lowrite', 'pg_loimport', 'pg_loexport',
+			'echo', 'print', 'global', 'static', 'exit', 'array', 'empty', 'eval', 'isset', 'unset', 'die'
+
+		]
+	}
+	,'OPERATORS' :[
+		'+', '-', '/', '*', '=', '<', '>', '%', '!', '&&', '||'
+	]
+	,'DELIMITERS' :[
+		'(', ')', '[', ']', '{', '}'
+	]
+	,'REGEXPS' : {
+		// highlight all variables ($...)
+		'variables' : {
+			'search' : '()(\\$\\w+)()'
+			,'class' : 'variables'
+			,'modifiers' : 'g'
+			,'execute' : 'before' // before or after
+		}
+	}
+	,'STYLES' : {
+		'COMMENTS': 'color: #AAAAAA;'
+		,'QUOTESMARKS': 'color: #879EFA;'
+		,'KEYWORDS' : {
+			'reserved' : 'color: #48BDDF;'
+			,'functions' : 'color: #0040FD;'
+			,'statements' : 'color: #60CA00;'
+			}
+		,'OPERATORS' : 'color: #FF00FF;'
+		,'DELIMITERS' : 'color: #2B60FF;'
+		,'REGEXPS' : {
+			'variables' : 'color: #E0BD54;'
+		}		
+	}
+	,'AUTO_COMPLETION' :  {
+		"default": {	// the name of this definition group. It's posisble to have different rules inside the same definition file
+			"REGEXP": { "before_word": "[^a-zA-Z0-9_]|^"	// \\s|\\.|
+						,"possible_words_letters": "[a-zA-Z0-9_\$]+"
+						,"letter_after_word_must_match": "[^a-zA-Z0-9_]|$"
+						,"prefix_separator": "\\-\\>|\\:\\:"
+					}
+			,"CASE_SENSITIVE": true
+			,"MAX_TEXT_LENGTH": 100		// the maximum length of the text being analyzed before the cursor position
+			,"KEYWORDS": {
+					'': [	// the prefix of thoses items
+						/**
+						 * 0 : the keyword the user is typing
+						 * 1 : (optionnal) the string inserted in code ("{@}" being the new position of the cursor, "§" beeing the equivalent to the value the typed string indicated if the previous )
+						 * 		If empty the keyword will be displayed
+						 * 2 : (optionnal) the text that appear in the suggestion box (if empty, the string to insert will be displayed)
+						 */
+						 ['$_POST']
+			    		,['$_GET']
+			    		,['$_SESSION']
+			    		,['$_SERVER']
+			    		,['$_FILES']
+			    		,['$_ENV']
+			    		,['$_COOKIE']
+			    		,['$_REQUEST']
+			    		// magic methods
+			    		,['__construct', '§( {@} )']
+			    		,['__destruct', '§( {@} )']
+			    		,['__sleep', '§( {@} )']
+			    		,['__wakeup', '§( {@} )']
+			    		,['__toString', '§( {@} )']
+			    		// include
+			    		,['include', '§ "{@}";']
+			    		,['include_once', '§ "{@}";']
+			    		,['require', '§ "{@}";']
+			    		,['require_once', '§ "{@}";']
+			    		// statements
+			    		,['for', '§( {@} )']
+			    		,['foreach', '§( {@} )']
+			    		,['if', '§( {@} )']
+			    		,['elseif', '§( {@} )']
+			    		,['while', '§( {@} )']
+			    		,['switch', '§( {@} )']
+			    		,['break']
+			    		,['case']
+			    		,['continue']
+			    		,['do']
+			    		,['else']
+			    		,['endif']
+			    		,['endswitch']
+			    		,['endwhile']
+			    		,['return']
+			    		// function
+			    		,['unset', '§( {@} )']
+					]
+				}
+			}
+		,"live": {	
+			
+			// class NAME: /class\W+([a-z]+)\W+/gi
+			// method: /^(public|private|protected)?\s*function\s+([a-z][a-z0-9\_]*)\s*(\([^\{]*\))/gmi
+			// static: /^(public|private|protected)?\s+static\s+(public|private|protected)?\s*function\s+([a-z][a-z0-9\_]*)\s*(\([^\{]*\))/gmi 
+			// attributes: /(\$this\-\>|(?:var|public|protected|private)\W+\$)([a-z0-9\_]+)(?!\()\b/gi 
+			// 		v1 : /(\$this\-\>|var\W+|public\W+|protected\W+|private\W+)([a-z0-9\_]+)\W*(=|;)/gi 
+			// var type: /(\$(this\-\>)?[a-z0-9\_]+)\s*\=\s*new\s+([a-z0-9\_])+/gi 
+			
+			
+			"REGEXP": { "before_word": "[^a-zA-Z0-9_]|^"	// \\s|\\.|
+						,"possible_words_letters": "[a-zA-Z0-9_\$]+"
+						,"letter_after_word_must_match": "[^a-zA-Z0-9_]|$"
+						,"prefix_separator": "\\-\\>"
+					}
+			,"CASE_SENSITIVE": true
+			,"MAX_TEXT_LENGTH": 100		// the maximum length of the text being analyzed before the cursor position
+			,"KEYWORDS": {
+					'$this': [	// the prefix of thoses items
+						['test']
+					]
+				}
+			}
+	}
+};
Index: /tags/2.0.2/plugins/LocalFilesEditor/functions.inc.php
===================================================================
--- /tags/2.0.2/plugins/LocalFilesEditor/functions.inc.php	(revision 3278)
+++ /tags/2.0.2/plugins/LocalFilesEditor/functions.inc.php	(revision 3278)
@@ -0,0 +1,114 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+/**
+ * returns $code if php syntax is correct
+ * else return false
+ *
+ * @param string php code
+ */
+function eval_syntax($code)
+{
+  $code = str_replace(array('<?php', '?>'), '', $code);
+  if (function_exists('token_get_all'))
+  {
+    $b = 0;
+    foreach (token_get_all($code) as $token)
+    {
+      if ('{' == $token) ++$b;
+      else if ('}' == $token) --$b;
+    }
+    if ($b) return false;
+    else
+    {
+      ob_start();
+      $eval = eval('if(0){' . $code . '}');
+      ob_end_clean();
+      if ($eval === false) return false;
+    }
+  }
+  return '<?php' . $code . '?>';
+}
+
+/**
+ * returns true or false if $str is bool
+  * returns $str if $str is integer
+ * else "$str"
+ *
+ * @param string
+ */
+function editarea_quote($value)
+{
+  switch (gettype($value))
+  {
+    case "boolean":
+      return $value ? 'true' : 'false';
+    case "integer":
+      return $value;
+    default:
+      return '"'.$value.'"';
+  }
+}
+
+/**
+ * returns bak file for restore
+ * @param string
+ */
+function get_bak_file($file)
+{
+  if (get_extension($file) == 'php')
+  {
+    return substr_replace($file, '.bak', strrpos($file , '.'), 0);
+  }
+  else
+  {
+    return $file . '.bak';
+  }
+}
+
+/**
+ * returns dirs and subdirs
+ * retun array
+ * @param string
+ */
+function get_rec_dirs($path='')
+{
+  $options = array();
+  if (is_dir($path))
+  {
+    $fh = opendir($path);
+    while ($file = readdir($fh))
+    {
+      $pathfile = $path . '/' . $file;
+      if ($file != '.' and $file != '..' and $file != '.svn' and is_dir($pathfile))
+      {
+        $options[$pathfile] = str_replace(array('./', '/'), array('', ' / '), $pathfile);
+        $options = array_merge($options, get_rec_dirs($pathfile));
+      }
+    }
+    closedir($fh);
+  }
+  return $options;
+}
+
+?>
Index: /tags/2.0.2/plugins/LocalFilesEditor/index.php
===================================================================
--- /tags/2.0.2/plugins/LocalFilesEditor/index.php	(revision 3278)
+++ /tags/2.0.2/plugins/LocalFilesEditor/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/plugins/LocalFilesEditor/language/de_DE/index.php
===================================================================
--- /tags/2.0.2/plugins/LocalFilesEditor/language/de_DE/index.php	(revision 3278)
+++ /tags/2.0.2/plugins/LocalFilesEditor/language/de_DE/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/plugins/LocalFilesEditor/language/de_DE/plugin.lang.php
===================================================================
--- /tags/2.0.2/plugins/LocalFilesEditor/language/de_DE/plugin.lang.php	(revision 3278)
+++ /tags/2.0.2/plugins/LocalFilesEditor/language/de_DE/plugin.lang.php	(revision 3278)
@@ -0,0 +1,56 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+$lang['locfiledit_onglet_localconf'] = 'Lokale Konfiguration';
+$lang['locfiledit_onglet_css'] = 'CSS';
+$lang['locfiledit_onglet_tpl'] = 'Vorlagen';
+$lang['locfiledit_onglet_lang'] = 'Sprachen';
+$lang['locfiledit_onglet_plug'] = 'Persönliche Plugin';
+$lang['locfiledit_cant_save'] = 'Aktuelle Datei ist nicht änderbar. Prüfen Sie ob ein Verzeichnis "include/" ist änderbar (chmod)';
+$lang['locfiledit_newfile'] = 'Die Datei ist nicht vorhanden und wird bei der Registrierung von localfile Editor';
+$lang['locfiledit_save_config'] = 'Datei geschrieben erfolgreich.';
+$lang['locfiledit_show_default'] = 'Anzeige Referenz-Datei: ';
+$lang['locfiledit_save_bak'] = 'Backup-Kopie wird auf Speichern.';
+$lang['locfiledit_saved_bak'] = 'Backup-Datei erstellt (%s)';
+$lang['locfiledit_save_file'] = 'Datei speichern';
+$lang['locfiledit_choose_file'] = 'Wählen die Datei auf der bearbeitet werden';
+$lang['locfiledit_edit'] = 'Bearbeiten';
+$lang['locfiledit_restore'] = 'Wiederherstellung der Backup-Datei';
+$lang['locfiledit_restore_confirm'] = 'Bitte bestätigen?
+Wiederherstellung wird nicht wirksam sein bis zum nächsten speichern.';
+$lang['locfiledit_bak_loaded1'] = 'Backup-Datei geladen werden.';
+$lang['locfiledit_bak_loaded2'] = 'Sie müssen Datei speichern zur Wiederherstellung es.';
+$lang['locfiledit_syntax_error'] = 'Syntax-Fehler! Datei kann nicht gespeichert werden.';
+$lang['locfiledit_enable_editarea'] = 'Aktivieren Bearbeiten Bereich';
+$lang['locfiledit_disable_editarea'] = 'Deaktivieren Bearbeiten Bereich';
+$lang['locfiledit_new_tpl'] = 'Erstellen eine neue Datei';
+$lang['locfiledit_new_filename'] = 'Dateiname';
+$lang['locfiledit_model'] = 'Modell';
+$lang['locfiledit_empty_page'] = 'Leere Seite';
+$lang['locfiledit_parent_directory'] = 'Eltern-Verzeichnis';
+$lang['locfiledit_filename_error'] = 'Verboten Zeichen in Dateinamen.';
+$lang['locfiledit_file_already_exists'] = 'Datei ist bereits vorhanden.';
+$lang['locfiledit_model_error'] = 'Sie müssen ein Modell wählen.';
+/* TODO */ $lang['locfiledit_empty_filename'] = 'You must fill file name.';
+
+?>
Index: /tags/2.0.2/plugins/LocalFilesEditor/language/en_UK/index.php
===================================================================
--- /tags/2.0.2/plugins/LocalFilesEditor/language/en_UK/index.php	(revision 3278)
+++ /tags/2.0.2/plugins/LocalFilesEditor/language/en_UK/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/plugins/LocalFilesEditor/language/en_UK/plugin.lang.php
===================================================================
--- /tags/2.0.2/plugins/LocalFilesEditor/language/en_UK/plugin.lang.php	(revision 3278)
+++ /tags/2.0.2/plugins/LocalFilesEditor/language/en_UK/plugin.lang.php	(revision 3278)
@@ -0,0 +1,56 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+$lang['locfiledit_onglet_localconf'] = 'Local config';
+$lang['locfiledit_onglet_css'] = 'CSS';
+$lang['locfiledit_onglet_tpl'] = 'Templates';
+$lang['locfiledit_onglet_lang'] = 'Languages';
+$lang['locfiledit_onglet_plug'] = 'Personal Plugin';
+$lang['locfiledit_cant_save'] = 'Current file isn\'t writeable. Check if a directory "include/" is writeable (chmod).';
+$lang['locfiledit_newfile'] = 'File is not existing and will be created by LocalFiles Editor';
+$lang['locfiledit_save_config'] = 'File written successfully.';
+$lang['locfiledit_show_default'] = 'Display reference file: ';
+$lang['locfiledit_save_bak'] = 'Backup copy will be created on save.';
+$lang['locfiledit_saved_bak'] = 'Backup file created (%s)';
+$lang['locfiledit_save_file'] = 'Save file';
+$lang['locfiledit_choose_file'] = 'Choose the file to be edited';
+$lang['locfiledit_edit'] = 'Edit';
+$lang['locfiledit_restore'] = 'Restore the backup file';
+$lang['locfiledit_restore_confirm'] = 'Please confirm?
+Restore won\'t be effective till next save.';
+$lang['locfiledit_bak_loaded1'] = 'Backup file loaded.';
+$lang['locfiledit_bak_loaded2'] = 'You must save file to restore it.';
+$lang['locfiledit_syntax_error'] = 'Syntax error! File can\'t be saved.';
+$lang['locfiledit_enable_editarea'] = 'Enable Editarea';
+$lang['locfiledit_disable_editarea'] = 'Disable Editarea';
+$lang['locfiledit_new_tpl'] = 'Create new file';
+$lang['locfiledit_new_filename'] = 'File name';
+$lang['locfiledit_model'] = 'Model';
+$lang['locfiledit_empty_page'] = 'Empty page';
+$lang['locfiledit_parent_directory'] = 'Parent directory';
+$lang['locfiledit_filename_error'] = 'Forbidden caraters in file name.';
+$lang['locfiledit_file_already_exists'] = 'File already exists.';
+$lang['locfiledit_model_error'] = 'You must choose a model.';
+$lang['locfiledit_empty_filename'] = 'You must fill file name.';
+
+?>
Index: /tags/2.0.2/plugins/LocalFilesEditor/language/es_ES/index.php
===================================================================
--- /tags/2.0.2/plugins/LocalFilesEditor/language/es_ES/index.php	(revision 3278)
+++ /tags/2.0.2/plugins/LocalFilesEditor/language/es_ES/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/plugins/LocalFilesEditor/language/es_ES/plugin.lang.php
===================================================================
--- /tags/2.0.2/plugins/LocalFilesEditor/language/es_ES/plugin.lang.php	(revision 3278)
+++ /tags/2.0.2/plugins/LocalFilesEditor/language/es_ES/plugin.lang.php	(revision 3278)
@@ -0,0 +1,56 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+$lang['locfiledit_onglet_localconf'] = 'Configuración local';
+$lang['locfiledit_onglet_css'] = 'CSS';
+$lang['locfiledit_onglet_tpl'] = 'Templates';
+$lang['locfiledit_onglet_lang'] = 'Idiomas';
+$lang['locfiledit_onglet_plug'] = 'Plugin personal';
+$lang['locfiledit_cant_save'] = 'Imposible escribir el fichero. Verifique los permisos (chmod) del expediente "include/".';
+$lang['locfiledit_newfile'] = 'El fichero no existe y será creado en el momento del registro por LocalFiles Editor';
+$lang['locfiledit_save_config'] = 'El fichero ha sido registrado.';
+$lang['locfiledit_show_default'] = 'Fijar el fichero ';
+$lang['locfiledit_save_bak'] = 'Una copia de salvaguardia del fichero será creada en el momento del registro';
+$lang['locfiledit_saved_bak'] = 'Una copia de salvaguardia ha sido creada (%s)';
+$lang['locfiledit_save_file'] = 'Registrar el fichero';
+$lang['locfiledit_choose_file'] = 'Escoja un fichero que hay que editar';
+$lang['locfiledit_edit'] = 'Editar';
+$lang['locfiledit_restore'] = 'Cargar el fichero de salvaguardia';
+$lang['locfiledit_restore_confirm'] = '¿ Desea cargar el fichero de salvaguardia?
+Usted deberá luego hacer clic Registrar para restaurarlo.';
+$lang['locfiledit_bak_loaded1'] = 'Fichero cargado de salvaguardia';
+$lang['locfiledit_bak_loaded2'] = 'Usted debe registrarlo para salvaguardarlo.';
+$lang['locfiledit_syntax_error'] = '¡ Error de sintaxis! Imposible registrar el fichero.';
+$lang['locfiledit_enable_editarea'] = 'Acelerar Editarea';
+$lang['locfiledit_disable_editarea'] = 'Desactivar Editarea ';
+$lang['locfiledit_new_tpl'] = 'Crear un nuevo fichero ';
+$lang['locfiledit_new_filename'] = 'Nombre del fichero ';
+$lang['locfiledit_model'] = 'Modelo ';
+$lang['locfiledit_empty_page'] = 'Página virgen';
+$lang['locfiledit_parent_directory'] = 'Expediente allegado';
+$lang['locfiledit_filename_error'] = 'Carácteres prohibidos en el nombre del fichero.';
+$lang['locfiledit_file_already_exists'] = 'El fichero ya existe.';
+$lang['locfiledit_model_error'] = 'Por favor, seleccione un modelo.';
+$lang['locfiledit_empty_filename'] = 'Por favor, indique un nombre de fichero.';
+
+?>
Index: /tags/2.0.2/plugins/LocalFilesEditor/language/fr_FR/index.php
===================================================================
--- /tags/2.0.2/plugins/LocalFilesEditor/language/fr_FR/index.php	(revision 3278)
+++ /tags/2.0.2/plugins/LocalFilesEditor/language/fr_FR/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/plugins/LocalFilesEditor/language/fr_FR/plugin.lang.php
===================================================================
--- /tags/2.0.2/plugins/LocalFilesEditor/language/fr_FR/plugin.lang.php	(revision 3278)
+++ /tags/2.0.2/plugins/LocalFilesEditor/language/fr_FR/plugin.lang.php	(revision 3278)
@@ -0,0 +1,56 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+$lang['locfiledit_onglet_localconf'] = 'Configuration locale';
+$lang['locfiledit_onglet_css'] = 'CSS';
+$lang['locfiledit_onglet_tpl'] = 'Templates';
+$lang['locfiledit_onglet_lang'] = 'Langues';
+$lang['locfiledit_onglet_plug'] = 'Plugin Personnel';
+$lang['locfiledit_cant_save'] = 'Impossible d\'écrire le fichier. Vérifiez les permissions (chmod) du dossier "include/".';
+$lang['locfiledit_newfile'] = 'Le fichier n\'existe pas et sera créé lors de l\'enregistrement par LocalFiles Editor';
+$lang['locfiledit_save_config'] = 'Le fichier a été enregistré.';
+$lang['locfiledit_show_default'] = 'Afficher le fichier ';
+$lang['locfiledit_save_bak'] = 'Une copie de sauvegarde du fichier sera créée lors de l\'enregistrement';
+$lang['locfiledit_saved_bak'] = 'Une copie de sauvegarde a été créée (%s)';
+$lang['locfiledit_save_file'] = 'Enregistrer le fichier';
+$lang['locfiledit_choose_file'] = 'Choisissez un fichier à éditer';
+$lang['locfiledit_edit'] = 'Editer';
+$lang['locfiledit_restore'] = 'Charger le fichier de sauvegarde';
+$lang['locfiledit_restore_confirm'] = 'Souaitez-vous charger le fichier de sauvegarde?
+Vous devrez ensuite cliquer sur Enregistrer pour le restaurer.';
+$lang['locfiledit_bak_loaded1'] = 'Fichier de sauvegarde chargé';
+$lang['locfiledit_bak_loaded2'] = 'Vous devez l\'enregistrer pour le sauvegarder.';
+$lang['locfiledit_syntax_error'] = 'Erreur de syntaxe! Impossible d\'enregistrer le fichier.';
+$lang['locfiledit_enable_editarea'] = 'Activer Editarea';
+$lang['locfiledit_disable_editarea'] = 'Désactiver Editarea';
+$lang['locfiledit_new_tpl'] = 'Créer un nouveau fichier';
+$lang['locfiledit_new_filename'] = 'Nom du fichier';
+$lang['locfiledit_model'] = 'Modèle';
+$lang['locfiledit_empty_page'] = 'Page vierge';
+$lang['locfiledit_parent_directory'] = 'Dossier parent';
+$lang['locfiledit_filename_error'] = 'Caractères interdits dans le nom du fichier.';
+$lang['locfiledit_file_already_exists'] = 'Le fichier existe déjà.';
+$lang['locfiledit_model_error'] = 'Veuillez sélectionner un modèle.';
+$lang['locfiledit_empty_filename'] = 'Veuillez indiquer un nom de fichier.';
+
+?>
Index: /tags/2.0.2/plugins/LocalFilesEditor/language/index.php
===================================================================
--- /tags/2.0.2/plugins/LocalFilesEditor/language/index.php	(revision 3278)
+++ /tags/2.0.2/plugins/LocalFilesEditor/language/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/plugins/LocalFilesEditor/language/it_IT/index.php
===================================================================
--- /tags/2.0.2/plugins/LocalFilesEditor/language/it_IT/index.php	(revision 3278)
+++ /tags/2.0.2/plugins/LocalFilesEditor/language/it_IT/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/plugins/LocalFilesEditor/language/it_IT/plugin.lang.php
===================================================================
--- /tags/2.0.2/plugins/LocalFilesEditor/language/it_IT/plugin.lang.php	(revision 3278)
+++ /tags/2.0.2/plugins/LocalFilesEditor/language/it_IT/plugin.lang.php	(revision 3278)
@@ -0,0 +1,56 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+$lang['locfiledit_onglet_localconf'] = 'Configurazione locale';
+$lang['locfiledit_onglet_css'] = 'CSS';
+$lang['locfiledit_onglet_tpl'] = 'Templates';
+$lang['locfiledit_onglet_lang'] = 'Lingue';
+$lang['locfiledit_onglet_plug'] = 'Plugin Personale';
+$lang['locfiledit_cant_save'] = 'È impossibile scrivere il file. Verificare i permessi (chmod) della directory.';
+$lang['locfiledit_newfile'] = 'Il file non esiste e sarà creato durante la fase di registrazione con LocalFiles Editor';
+$lang['locfiledit_save_config'] = 'Il file è stato salvato.';
+$lang['locfiledit_show_default'] = 'Visualizzare il file ';
+$lang['locfiledit_save_bak'] = 'Una copia di backup del file sarà creata durante la fase di registrazione';
+$lang['locfiledit_saved_bak'] = 'Una copia di backup è stata creata (%s)';
+$lang['locfiledit_save_file'] = 'Registrare il file';
+$lang['locfiledit_choose_file'] = 'Scegliere un file da editare';
+$lang['locfiledit_edit'] = 'Editare';
+$lang['locfiledit_restore'] = 'Caricare il file di backup';
+$lang['locfiledit_restore_confirm'] = 'Volete caricare il file di backup?
+Dovrete in seguito cliccare sù Registrare per restaurarlo.';
+$lang['locfiledit_bak_loaded1'] = 'Copia di backup caricata';
+$lang['locfiledit_bak_loaded2'] = 'Dovete registrarlo per salvarlo.';
+$lang['locfiledit_syntax_error'] = 'Errore di sintassi! Impossible di registrare il file.';
+$lang['locfiledit_enable_editarea'] = 'Attivare Editarea';
+$lang['locfiledit_disable_editarea'] = 'Disattivare Editarea';
+$lang['locfiledit_new_tpl'] = 'Creare un nuovo file';
+$lang['locfiledit_new_filename'] = 'Nom file';
+$lang['locfiledit_model'] = 'Modello';
+$lang['locfiledit_empty_page'] = 'Pagina vergine';
+$lang['locfiledit_parent_directory'] = 'Directory parente';
+$lang['locfiledit_filename_error'] = 'Caratteri vietati nel nome del file.';
+$lang['locfiledit_file_already_exists'] = 'Il file esiste già.';
+$lang['locfiledit_model_error'] = 'Selezionare un modello.';
+/* TODO */ $lang['locfiledit_empty_filename'] = 'Indicare un nome di file.';
+
+?>
Index: /tags/2.0.2/plugins/LocalFilesEditor/language/pl_PL/index.php
===================================================================
--- /tags/2.0.2/plugins/LocalFilesEditor/language/pl_PL/index.php	(revision 3278)
+++ /tags/2.0.2/plugins/LocalFilesEditor/language/pl_PL/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/plugins/LocalFilesEditor/language/pl_PL/plugin.lang.php
===================================================================
--- /tags/2.0.2/plugins/LocalFilesEditor/language/pl_PL/plugin.lang.php	(revision 3278)
+++ /tags/2.0.2/plugins/LocalFilesEditor/language/pl_PL/plugin.lang.php	(revision 3278)
@@ -0,0 +1,56 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+$lang['locfiledit_onglet_localconf'] = 'Konfiguracja lokalna';
+$lang['locfiledit_onglet_css'] = 'CSS';
+$lang['locfiledit_onglet_tpl'] = 'Szablony';
+$lang['locfiledit_onglet_lang'] = 'Języki';
+$lang['locfiledit_onglet_plug'] = 'Wtyczki własne';
+$lang['locfiledit_cant_save'] = 'W pliku nie można zapisywać zmian. Sprawdź czy katalog "include/" jest zapisywalny (chmod).';
+$lang['locfiledit_newfile'] = 'Plik nie istnieje i zostanie utworzony przez Edytora Plików Lokalnych';
+$lang['locfiledit_save_config'] = 'Plik został zapisany pomyślnie.';
+$lang['locfiledit_show_default'] = 'Pokaż plik referencyjny: ';
+$lang['locfiledit_save_bak'] = 'Kopia zapasowa zostanie utworzona podczas zapisywania zmian.';
+$lang['locfiledit_saved_bak'] = 'Plik kopii zapasowej utworzony (%s)';
+$lang['locfiledit_save_file'] = 'Zapisz plik';
+$lang['locfiledit_choose_file'] = 'Wybierz plik do edycji';
+$lang['locfiledit_edit'] = 'Edytuj';
+$lang['locfiledit_restore'] = 'Przywróć plik z kopii zapasowej';
+$lang['locfiledit_restore_confirm'] = 'Potwierdź proszę?
+Przywrócenie nie przyniesie efektu do następnego zapisu.';
+$lang['locfiledit_bak_loaded1'] = 'Plik kopii zapasowej wczytany.';
+$lang['locfiledit_bak_loaded2'] = 'Musisz zapisać plik aby go przywrócić.';
+$lang['locfiledit_syntax_error'] = 'Błąd skłądni! Plik nie może zostać zapisany.';
+$lang['locfiledit_enable_editarea'] = 'Włącz Pole Edycyjne';
+$lang['locfiledit_disable_editarea'] = 'Wyłącz Pole Edycyjne';
+$lang['locfiledit_new_tpl'] = 'Stwórz nowy plik';
+$lang['locfiledit_new_filename'] = 'Nazwa pliku';
+$lang['locfiledit_model'] = 'Model';
+$lang['locfiledit_empty_page'] = 'Pusta strona';
+$lang['locfiledit_parent_directory'] = 'Katalog nadrzędny';
+$lang['locfiledit_filename_error'] = 'Plik zawiera niedozwolone znaki.';
+$lang['locfiledit_file_already_exists'] = 'Plik już istnieje.';
+$lang['locfiledit_model_error'] = 'Musisz wybrać model.';
+$lang['locfiledit_empty_filename'] = 'Musisz wpisać nazwę pliku.';
+
+?>
Index: /tags/2.0.2/plugins/LocalFilesEditor/locfiledit.css
===================================================================
--- /tags/2.0.2/plugins/LocalFilesEditor/locfiledit.css	(revision 3278)
+++ /tags/2.0.2/plugins/LocalFilesEditor/locfiledit.css	(revision 3278)
@@ -0,0 +1,34 @@
+#LocalFilesEditor {
+  text-align: center;
+  margin: 0 2em;
+}
+
+#LocalFilesEditor .top_right  {
+  float: right;
+  margin-right: 1%;
+}
+
+#LocalFilesEditor B {
+  float: left;
+}
+
+#LocalFilesEditor TEXTAREA {
+  margin: 0.5em 0;
+  width: 99.5%;
+  float: left;
+}
+
+#LocalFilesEditor #editarea_buttons {
+  width: 100%;
+  float: left;
+  text-align: left;
+  display: none;
+}
+
+#LocalFilesEditor #hideedit {
+  display: none;
+}
+
+#LocalFilesEditor TD {
+  padding: 0.5em;
+}
Index: /tags/2.0.2/plugins/LocalFilesEditor/main.inc.php
===================================================================
--- /tags/2.0.2/plugins/LocalFilesEditor/main.inc.php	(revision 3278)
+++ /tags/2.0.2/plugins/LocalFilesEditor/main.inc.php	(revision 3278)
@@ -0,0 +1,46 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+/*
+Plugin Name: LocalFiles Editor
+Version: 2.0.2
+Description: Edit local files from administration panel / Editeur de fichiers locaux
+Plugin URI: http://piwigo.org/ext/extension_view.php?eid=144
+Author: Piwigo team
+Author URI: http://piwigo.org
+*/
+
+if (!defined('PHPWG_ROOT_PATH')) die('Hacking attempt!');
+define('LOCALEDIT_PATH' , PHPWG_PLUGINS_PATH . basename(dirname(__FILE__)) . '/');
+
+function localfiles_admin_menu($menu)
+{
+  array_push($menu, array(
+    'NAME' => 'LocalFiles Editor',
+    'URL' => get_admin_plugin_menu_link(LOCALEDIT_PATH . 'admin.php')));
+  return $menu;
+}
+
+add_event_handler('get_admin_plugin_menu_links', 'localfiles_admin_menu');
+
+?>
Index: /tags/2.0.2/plugins/LocalFilesEditor/maintain.inc.php
===================================================================
--- /tags/2.0.2/plugins/LocalFilesEditor/maintain.inc.php	(revision 3278)
+++ /tags/2.0.2/plugins/LocalFilesEditor/maintain.inc.php	(revision 3278)
@@ -0,0 +1,43 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+function plugin_install()
+{
+  global $prefixeTable;
+
+  $query = '
+INSERT INTO ' . CONFIG_TABLE . ' (param,value,comment)
+VALUES ("LocalFilesEditor" , "off" , "LocalFiles Editor plugin parameters");';
+
+  pwg_query($query);
+}
+
+function plugin_uninstall()
+{
+  global $prefixeTable;
+
+  $query = 'DELETE FROM ' . CONFIG_TABLE . ' WHERE param="LocalFilesEditor" LIMIT 1;';
+  pwg_query($query);
+}
+
+?>
Index: /tags/2.0.2/plugins/LocalFilesEditor/show_default.php
===================================================================
--- /tags/2.0.2/plugins/LocalFilesEditor/show_default.php	(revision 3278)
+++ /tags/2.0.2/plugins/LocalFilesEditor/show_default.php	(revision 3278)
@@ -0,0 +1,68 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+define('PHPWG_ROOT_PATH', '../../');
+define('IN_ADMIN', true);
+include_once(PHPWG_ROOT_PATH . 'include/common.inc.php');
+include_once(LOCALEDIT_PATH.'functions.inc.php');
+load_language('plugin.lang', LOCALEDIT_PATH);
+check_status(ACCESS_ADMINISTRATOR);
+
+if (isset($_GET['file']))
+{
+  $path = $_GET['file'];
+  if (!is_admin() or (!substr_count($path, 'config_default.inc.php') and !substr_count($path, '.lang.php')))
+  {
+  	die('Hacking attempt!');
+  }
+    
+  $template->set_filename('show_default', dirname(__FILE__) . '/show_default.tpl');
+  
+  // Editarea
+  $editarea_options = array(
+    'syntax' => 'php',
+    'start_highlight' => true,
+    'allow_toggle' => false,
+    'is_editable' => false,
+    'language' => substr($user['language'], 0, 2));
+
+  $file = file_get_contents(PHPWG_ROOT_PATH . $path);
+  $title = str_replace('/', ' / ', $path);
+
+  $template->assign(array(
+    'TITLE' => $title,
+    'DEFAULT_CONTENT' => $file,
+    'LOCALEDIT_PATH' => LOCALEDIT_PATH,
+    'LOAD_EDITAREA' => isset($conf['LocalFilesEditor']) ? $conf['LocalFilesEditor'] : 'on',
+    'EDITAREA_OPTIONS' => $editarea_options));
+
+  $page['body_id'] = 'thePopuphelpPage';
+
+  include(PHPWG_ROOT_PATH.'include/page_header.php');
+
+  $template->pparse('show_default');
+
+  include(PHPWG_ROOT_PATH.'include/page_tail.php');
+}
+
+?>
Index: /tags/2.0.2/plugins/LocalFilesEditor/show_default.tpl
===================================================================
--- /tags/2.0.2/plugins/LocalFilesEditor/show_default.tpl	(revision 3278)
+++ /tags/2.0.2/plugins/LocalFilesEditor/show_default.tpl	(revision 3278)
@@ -0,0 +1,44 @@
+{* $Id$ *}
+{html_head}
+<link rel="stylesheet" type="text/css" href="{$LOCALEDIT_PATH}locfiledit.css">
+<style type="text/css">#headbranch, #theHeader, #copyright {ldelim} display: none; }</style>
+{/html_head}
+{known_script id="jquery" src=$ROOT_URL|@cat:"template-common/lib/jquery.packed.js"}
+{known_script id="editarea" src=$LOCALEDIT_PATH|@cat:"editarea/edit_area_full.js"}
+<script type="text/javascript">
+var editarea = "{$LOAD_EDITAREA}";
+
+function loadEditarea() {ldelim} 
+  editAreaLoader.init({ldelim}
+    id: "text"
+    {foreach from=$EDITAREA_OPTIONS key=option item=value}
+    , {$option}: {$value|editarea_quote}
+    {/foreach}
+  });
+  jQuery("#showedit").hide();
+  jQuery("#hideedit").show();
+}
+
+function unloadEditarea() {ldelim} 
+  editAreaLoader.delete_instance("text");
+  jQuery("#hideedit").hide();
+  jQuery("#showedit").show();
+}
+</script>
+
+<div id="LocalFilesEditor">
+<h1>{$TITLE}</h1>
+
+<textarea id="text" rows="30" cols="90">{$DEFAULT_CONTENT}</textarea>
+
+<div id="editarea_buttons">
+<a href="javascript:loadEditarea();" id="showedit">[{'locfiledit_enable_editarea'|@translate}]</a>
+<a href="javascript:unloadEditarea();" id="hideedit">[{'locfiledit_disable_editarea'|@translate}]</a>
+</div>
+
+</div>
+
+<script type="text/javascript">
+jQuery("#editarea_buttons").show();
+if (editarea == "on") loadEditarea();
+</script>
Index: /tags/2.0.2/plugins/LocalFilesEditor/update_config.php
===================================================================
--- /tags/2.0.2/plugins/LocalFilesEditor/update_config.php	(revision 3278)
+++ /tags/2.0.2/plugins/LocalFilesEditor/update_config.php	(revision 3278)
@@ -0,0 +1,46 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+define('PHPWG_ROOT_PATH', '../../');
+include_once(PHPWG_ROOT_PATH . 'include/common.inc.php');
+include_once(LOCALEDIT_PATH.'functions.inc.php');
+check_status(ACCESS_ADMINISTRATOR);
+
+$possible_values = array('on', 'off');
+
+if (isset($_POST['editarea']) and in_array($_POST['editarea'], $possible_values))
+{
+  if (!isset($conf['LocalFilesEditor']))
+  {
+    include_once(LOCALEDIT_PATH.'maintain.inc.php');
+    plugin_install();
+  }
+  $query = '
+UPDATE ' . CONFIG_TABLE . '
+SET value = "' . $_POST['editarea'] . '"
+WHERE param="LocalFilesEditor"
+LIMIT 1';
+  pwg_query($query);
+}
+
+?>
Index: /tags/2.0.2/plugins/add_index/admin/index.php
===================================================================
--- /tags/2.0.2/plugins/add_index/admin/index.php	(revision 3278)
+++ /tags/2.0.2/plugins/add_index/admin/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/plugins/add_index/admin/main_page.php
===================================================================
--- /tags/2.0.2/plugins/add_index/admin/main_page.php	(revision 3278)
+++ /tags/2.0.2/plugins/add_index/admin/main_page.php	(revision 3278)
@@ -0,0 +1,202 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if ((!defined('PHPWG_ROOT_PATH')) or (!(defined('IN_ADMIN') and IN_ADMIN)))
+{
+  die('Hacking attempt!');
+}
+
+// +-----------------------------------------------------------------------+
+// | include                                                               |
+// +-----------------------------------------------------------------------+
+include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+include_once(PHPWG_ROOT_PATH.'include/common.inc.php');
+
+// +-----------------------------------------------------------------------+
+// | Check Access and exit when user status is not ok                      |
+// +-----------------------------------------------------------------------+
+check_status(ACCESS_ADMINISTRATOR);
+
+// +-----------------------------------------------------------------------+
+// | Functions                                                             |
+// +-----------------------------------------------------------------------+
+/**
+ * returns an array containing sub-directories
+ * recursive by default
+ *
+ * directories nammed ".svn" are omitted
+ *
+ * @param string $path
+ * @param bool $recursive
+ * @return array
+ */
+function get_add_index_directories($path, $recursive = true)
+{
+  $dirs = array();
+
+  if (is_dir($path))
+  {
+    if ($contents = opendir($path))
+    {
+      while (($node = readdir($contents)) !== false)
+      {
+        if (
+            is_dir($path.'/'.$node)
+            and $node != '.'
+            and $node != '..'
+            and $node != '.svn'
+           )
+        {
+          array_push($dirs, $path.'/'.$node);
+          if ($recursive)
+          {
+            $dirs = array_merge($dirs, get_add_index_directories($path.'/'.$node));
+          }
+        }
+      }
+    }
+  }
+
+  return $dirs;
+}
+
+// +-----------------------------------------------------------------------+
+// | Main                                                                  |
+// +-----------------------------------------------------------------------+
+// Compute values
+$index_file_src=$conf['add_index_source_directory_path'].$conf['add_index_filename'];
+$overwrite_file=isset($_GET['overwrite']);
+$site_id = (isset($_GET['site_id']) and is_numeric($_GET['site_id']) 
+            ? $_GET['site_id'] 
+            : 0);
+
+// Init values
+$add_index_results = array();
+$count_copy = 0;
+$count_skip = 0;
+$count_error = 0;
+
+if (@file_exists($index_file_src))
+{
+  $query = '
+select
+  galleries_url
+from
+  '.SITES_TABLE;
+  if (!empty($site_id))
+  {
+    $query .= '
+where
+  id = '.$site_id;
+  }
+    $query .= '
+order by
+ id';
+
+  $result = pwg_query($query);
+
+  if (mysql_num_rows($result) > 0)
+  {
+    while (list($galleries_url) = mysql_fetch_row($result))
+    {
+      if (!url_is_remote($galleries_url))
+      {
+        //echo $galleries_url.'<BR>';
+        foreach (get_add_index_directories($galleries_url) as $dir_galleries)
+        {
+          $file_dest = str_replace('//', '/', $dir_galleries.'/'.$conf['add_index_filename']);
+          if ($overwrite_file or !@file_exists($file_dest))
+          {
+            if (copy($index_file_src, $file_dest))
+            {
+              array_push($add_index_results,
+                sprintf(l10n('add_index_file_copied'), $file_dest));
+              $count_copy++;
+            }
+            else
+            {
+              array_push($page['errors'],
+                sprintf(l10n('add_index_file_not_copied'), $file_dest));
+              $count_error++;
+            }
+          }
+          else
+          {
+            $count_skip++;
+          }
+        }
+      }
+      else
+      {
+        if (!empty($site_id))
+        {
+          array_push($page['errors'],
+            sprintf(l10n('add_index_not_local_site'), 
+              $galleries_url, $site_id));
+        }
+      }
+    }
+  }
+
+  // Show always an result, defaut (0 copy, $count_copy == $count_skip == 0)
+  if (($count_copy != 0) or ($count_skip == 0))
+  {
+    array_push($add_index_results,
+      l10n_dec('add_index_nb_copied_file', 'add_index_nb_copied_files',
+        $count_copy));
+  }
+  if ($count_skip != 0)
+  {
+    array_push($add_index_results,
+      l10n_dec('add_index_nb_skipped_file', 'add_index_nb_skipped_files',
+        $count_skip));
+  }
+  if ($count_error != 0)
+  {
+    array_push($page['errors'],
+      l10n_dec('add_index_nb_not_copied_file', 'add_index_nb_not_copied_files',
+        $count_error));
+  }
+}
+else
+{
+  array_push($page['errors'],
+    sprintf(l10n('add_index_src_file_dont_exists'), $index_file_src));
+}
+
+// +-----------------------------------------------------------------------+
+// | template initialization                                               |
+// +-----------------------------------------------------------------------+
+$template->set_filenames(array('main_page' => dirname(__FILE__).'/main_page.tpl'));
+
+if (count($add_index_results) != 0)
+{
+  $template->assign('add_index_results', $add_index_results);
+}
+
+// +-----------------------------------------------------------------------+
+// | Sending html code                                                     |
+// +-----------------------------------------------------------------------+
+$template->assign_var_from_handle( 'ADMIN_CONTENT', 'main_page');
+
+?>
Index: /tags/2.0.2/plugins/add_index/admin/main_page.tpl
===================================================================
--- /tags/2.0.2/plugins/add_index/admin/main_page.tpl	(revision 3278)
+++ /tags/2.0.2/plugins/add_index/admin/main_page.tpl	(revision 3278)
@@ -0,0 +1,15 @@
+{* $Id$ *}
+
+<div class="titrePage">
+  <h2>{'Add_Index'|@translate}</h2>
+</div>
+
+{if isset($add_index_results)}
+<div>
+  <ul>
+    {foreach from=$add_index_results item=result}
+    <li>{$result}</li>
+    {/foreach}
+  </ul>
+</div>
+{/if}
Index: /tags/2.0.2/plugins/add_index/index.php
===================================================================
--- /tags/2.0.2/plugins/add_index/index.php	(revision 3278)
+++ /tags/2.0.2/plugins/add_index/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/plugins/add_index/language/de_DE/help/advanced_feature.html
===================================================================
--- /tags/2.0.2/plugins/add_index/language/de_DE/help/advanced_feature.html	(revision 3278)
+++ /tags/2.0.2/plugins/add_index/language/de_DE/help/advanced_feature.html	(revision 3278)
@@ -0,0 +1,7 @@
+<p>Funktionalität von AddIndex-Plugin:</p>
+<ul>
+  <li>
+    <strong>Hinzufügen und überschreiben "Index"-Dateien für alle lokalen Websites:</strong>
+    Überschreiben und kopieren die Datei ./include/index.php auf alle Unter-Verzeichnisse von lokalen Websites Gallerie .
+  </li>
+<ul>
Index: /tags/2.0.2/plugins/add_index/language/de_DE/help/index.php
===================================================================
--- /tags/2.0.2/plugins/add_index/language/de_DE/help/index.php	(revision 3278)
+++ /tags/2.0.2/plugins/add_index/language/de_DE/help/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/plugins/add_index/language/de_DE/help/site_manager.html
===================================================================
--- /tags/2.0.2/plugins/add_index/language/de_DE/help/site_manager.html	(revision 3278)
+++ /tags/2.0.2/plugins/add_index/language/de_DE/help/site_manager.html	(revision 3278)
@@ -0,0 +1,7 @@
+<p>Funktionalität von AddIndex-Plugin:</p>
+<ul>
+  <li>
+    <strong>Hinzufügen "Index"-Dateien für die lokale Website:</strong>
+    Kopieren die Datei ./include/index.php auf alle Unter-Verzeichnisse von ausgewählten lokalen Website.
+  </li>
+<ul>
Index: /tags/2.0.2/plugins/add_index/language/de_DE/index.php
===================================================================
--- /tags/2.0.2/plugins/add_index/language/de_DE/index.php	(revision 3278)
+++ /tags/2.0.2/plugins/add_index/language/de_DE/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/plugins/add_index/language/de_DE/plugin.lang.php
===================================================================
--- /tags/2.0.2/plugins/add_index/language/de_DE/plugin.lang.php	(revision 3278)
+++ /tags/2.0.2/plugins/add_index/language/de_DE/plugin.lang.php	(revision 3278)
@@ -0,0 +1,39 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+$lang['Add_Index'] = 'Hinzufügen "Index"-Dateien';
+$lang['Advanced_Add_Index'] = 'Hinzufügen und überschreiben "Index"-Dateien für alle lokalen Standorte';
+$lang['Manager_Add_Index'] = 'Hinzufügen "Index"';
+
+$lang['add_index_file_copied'] = '%s kopiert';
+$lang['add_index_file_not_copied'] = '%s nicht kopiert';
+$lang['add_index_not_local_site'] = '%s [%d] ist eine Remote-Website. Es ist kompatibel mit hinzufügen "Index"-Dateien.';
+$lang['add_index_nb_copied_file'] = '%d Datei kopiert';
+$lang['add_index_nb_copied_files'] = '%d Dateien kopiert';
+$lang['add_index_nb_skipped_file'] = '%d Datei übersprungen';
+$lang['add_index_nb_skipped_files'] = '%d Dateien übersprungen';
+$lang['add_index_nb_not_copied_file'] = '%d Datei nicht kopiert';
+$lang['add_index_nb_not_copied_files'] = '%d Dateien nicht kopiert';
+$lang['add_index_src_file_dont_exists'] = 'Quelldatei %s ist nicht vorhanden, kann nicht duplizieren diese Datei';
+
+?>
Index: /tags/2.0.2/plugins/add_index/language/en_UK/help/advanced_feature.html
===================================================================
--- /tags/2.0.2/plugins/add_index/language/en_UK/help/advanced_feature.html	(revision 3278)
+++ /tags/2.0.2/plugins/add_index/language/en_UK/help/advanced_feature.html	(revision 3278)
@@ -0,0 +1,7 @@
+<p>Functionality of AddIndex plugin:</p>
+<ul>
+  <li>
+    <strong>Add and overwrite "index" files for all local sites:</strong>
+    Overwrite copy the file ./include/index.php to all sub-directories of gallerie local sites.
+  </li>
+<ul>
Index: /tags/2.0.2/plugins/add_index/language/en_UK/help/index.php
===================================================================
--- /tags/2.0.2/plugins/add_index/language/en_UK/help/index.php	(revision 3278)
+++ /tags/2.0.2/plugins/add_index/language/en_UK/help/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/plugins/add_index/language/en_UK/help/site_manager.html
===================================================================
--- /tags/2.0.2/plugins/add_index/language/en_UK/help/site_manager.html	(revision 3278)
+++ /tags/2.0.2/plugins/add_index/language/en_UK/help/site_manager.html	(revision 3278)
@@ -0,0 +1,7 @@
+<p>Functionality of AddIndex plugin:</p>
+<ul>
+  <li>
+    <strong>Add "index" files for local site:</strong>
+    Copy the file ./include/index.php to all sub-directories of selected local site.
+  </li>
+<ul>
Index: /tags/2.0.2/plugins/add_index/language/en_UK/index.php
===================================================================
--- /tags/2.0.2/plugins/add_index/language/en_UK/index.php	(revision 3278)
+++ /tags/2.0.2/plugins/add_index/language/en_UK/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/plugins/add_index/language/en_UK/plugin.lang.php
===================================================================
--- /tags/2.0.2/plugins/add_index/language/en_UK/plugin.lang.php	(revision 3278)
+++ /tags/2.0.2/plugins/add_index/language/en_UK/plugin.lang.php	(revision 3278)
@@ -0,0 +1,39 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+$lang['Add_Index'] = 'Add "index" files';
+$lang['Advanced_Add_Index'] = 'Add and overwrite "index" files for all local sites';
+$lang['Manager_Add_Index'] = 'add "index"';
+
+$lang['add_index_file_copied'] = '%s copied';
+$lang['add_index_file_not_copied'] = '%s not copied';
+$lang['add_index_not_local_site'] = '%s [%d] is a remote site, it\`s compatible with add "index" files';
+$lang['add_index_nb_copied_file'] = '%d file copied';
+$lang['add_index_nb_copied_files'] = '%d files copied';
+$lang['add_index_nb_skipped_file'] = '%d file skipped';
+$lang['add_index_nb_skipped_files'] = '%d files skipped';
+$lang['add_index_nb_not_copied_file'] = '%d file not copied';
+$lang['add_index_nb_not_copied_files'] = '%d files not copied';
+$lang['add_index_src_file_dont_exists'] = 'Source file %s don\'t esists, cannot duplicate this file';
+
+?>
Index: /tags/2.0.2/plugins/add_index/language/es_ES/help/advanced_feature.html
===================================================================
--- /tags/2.0.2/plugins/add_index/language/es_ES/help/advanced_feature.html	(revision 3278)
+++ /tags/2.0.2/plugins/add_index/language/es_ES/help/advanced_feature.html	(revision 3278)
@@ -0,0 +1,7 @@
+<p>Funcionalidad del plugin AddIndex:</p>
+<ul>
+  <li>
+    <strong>Adición y aplastamiento de los ficheros "index" para todos los sitios locales :</strong>
+    Copia con aplastamiento el fichero ./include/index.php en todos los subficheros de las galerías de los sitios locales.
+  </li>
+</ul>
Index: /tags/2.0.2/plugins/add_index/language/es_ES/help/index.php
===================================================================
--- /tags/2.0.2/plugins/add_index/language/es_ES/help/index.php	(revision 3278)
+++ /tags/2.0.2/plugins/add_index/language/es_ES/help/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/plugins/add_index/language/es_ES/help/site_manager.html
===================================================================
--- /tags/2.0.2/plugins/add_index/language/es_ES/help/site_manager.html	(revision 3278)
+++ /tags/2.0.2/plugins/add_index/language/es_ES/help/site_manager.html	(revision 3278)
@@ -0,0 +1,7 @@
+<p>Funcionalidad del plugin AddIndex:</p>
+<ul>
+  <li>
+    <strong>Adición de los ficheros "index" para el sitio local:</strong>
+    Copia el fichero ./include/index.php en todos los subficheros del sitio seleccionado.
+  </li>
+</ul>
Index: /tags/2.0.2/plugins/add_index/language/es_ES/index.php
===================================================================
--- /tags/2.0.2/plugins/add_index/language/es_ES/index.php	(revision 3278)
+++ /tags/2.0.2/plugins/add_index/language/es_ES/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/plugins/add_index/language/es_ES/plugin.lang.php
===================================================================
--- /tags/2.0.2/plugins/add_index/language/es_ES/plugin.lang.php	(revision 3278)
+++ /tags/2.0.2/plugins/add_index/language/es_ES/plugin.lang.php	(revision 3278)
@@ -0,0 +1,39 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+$lang['Add_Index'] = 'Adición de los ficheros "index"';
+$lang['Advanced_Add_Index'] = 'Adición y aplastamiento de los ficheros "index" para todos los sitios locales';
+$lang['Manager_Add_Index'] = 'adición de "index"';
+
+$lang['add_index_file_copied'] = '%s copiado';
+$lang['add_index_file_not_copied'] = '%s no copiado';
+$lang['add_index_not_local_site'] = '%s [%d] es un sitio distante, no es compatible con la adición de ficheros "index"';
+$lang['add_index_nb_copied_file'] = '%d fichero copiado';
+$lang['add_index_nb_copied_files'] = '%d ficheros copiados';
+$lang['add_index_nb_skipped_file'] = '%d fichero que debe tratarse';
+$lang['add_index_nb_skipped_files'] = '%d ficheros que deben tratarse';
+$lang['add_index_nb_not_copied_file'] = '%d fichero no copiado';
+$lang['add_index_nb_not_copied_files'] = '%d ficheros no copiados';
+$lang['add_index_src_file_dont_exists'] = 'El fichero fuente no existe, la duplicación de este fichero no es posible';
+
+?>
Index: /tags/2.0.2/plugins/add_index/language/fr_FR/help/advanced_feature.html
===================================================================
--- /tags/2.0.2/plugins/add_index/language/fr_FR/help/advanced_feature.html	(revision 3278)
+++ /tags/2.0.2/plugins/add_index/language/fr_FR/help/advanced_feature.html	(revision 3278)
@@ -0,0 +1,7 @@
+<p>Fonctionnalité du plugin AddIndex:</p>
+<ul>
+  <li>
+    <strong>Ajout et écrasement des fichiers "index" pour tous les sites locaux :</strong>
+    Copie avec écrasement le fichier ./include/index.php dans tous les sous-répertoires des galeries des sites locaux.
+  </li>
+</ul>
Index: /tags/2.0.2/plugins/add_index/language/fr_FR/help/index.php
===================================================================
--- /tags/2.0.2/plugins/add_index/language/fr_FR/help/index.php	(revision 3278)
+++ /tags/2.0.2/plugins/add_index/language/fr_FR/help/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/plugins/add_index/language/fr_FR/help/site_manager.html
===================================================================
--- /tags/2.0.2/plugins/add_index/language/fr_FR/help/site_manager.html	(revision 3278)
+++ /tags/2.0.2/plugins/add_index/language/fr_FR/help/site_manager.html	(revision 3278)
@@ -0,0 +1,7 @@
+<p>Fonctionnalité du plugin AddIndex:</p>
+<ul>
+  <li>
+    <strong>Ajout des fichiers "index" pour le site local :</strong>
+    Copie le fichier ./include/index.php dans tous les sous-répertoires du site sélectionné.
+  </li>
+</ul>
Index: /tags/2.0.2/plugins/add_index/language/fr_FR/index.php
===================================================================
--- /tags/2.0.2/plugins/add_index/language/fr_FR/index.php	(revision 3278)
+++ /tags/2.0.2/plugins/add_index/language/fr_FR/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/plugins/add_index/language/fr_FR/plugin.lang.php
===================================================================
--- /tags/2.0.2/plugins/add_index/language/fr_FR/plugin.lang.php	(revision 3278)
+++ /tags/2.0.2/plugins/add_index/language/fr_FR/plugin.lang.php	(revision 3278)
@@ -0,0 +1,39 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+$lang['Add_Index'] = 'Ajout des fichiers "index"';
+$lang['Advanced_Add_Index'] = 'Ajout et écrasement des fichiers "index" pour tous les sites locaux';
+$lang['Manager_Add_Index'] = 'ajout des "index"';
+
+$lang['add_index_file_copied'] = '%s copié';
+$lang['add_index_file_not_copied'] = '%s non copié';
+$lang['add_index_not_local_site'] = '%s [%d] est un site distant, ce n\'est pas compatible avec l\'ajout de fichiers "index"';
+$lang['add_index_nb_copied_file'] = '%d fichier copié';
+$lang['add_index_nb_copied_files'] = '%d fichiers copiés';
+$lang['add_index_nb_skipped_file'] = '%d fichier à ne pas traiter';
+$lang['add_index_nb_skipped_files'] = '%d fichiers à ne pas traiter';
+$lang['add_index_nb_not_copied_file'] = '%d fichier non copié';
+$lang['add_index_nb_not_copied_files'] = '%d fichiers non copiés';
+$lang['add_index_src_file_dont_exists'] = 'Le fichier source n\'existe pas, la duplication de ce fichier n\'est pas possible';
+
+?>
Index: /tags/2.0.2/plugins/add_index/language/index.php
===================================================================
--- /tags/2.0.2/plugins/add_index/language/index.php	(revision 3278)
+++ /tags/2.0.2/plugins/add_index/language/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/plugins/add_index/language/it_IT/help/advanced_feature.html
===================================================================
--- /tags/2.0.2/plugins/add_index/language/it_IT/help/advanced_feature.html	(revision 3278)
+++ /tags/2.0.2/plugins/add_index/language/it_IT/help/advanced_feature.html	(revision 3278)
@@ -0,0 +1,7 @@
+<p>Funzionalità del plugin AddIndex:</p>
+<ul>
+  <li>
+    <strong>Aggiunge e sovrascrive i files "index" per tutti i siti locali:</strong>
+    Copia sovrascrivendo se necessario il file ./include/index.php in tutte le directory dei siti locali.
+  </li>
+<ul>
Index: /tags/2.0.2/plugins/add_index/language/it_IT/help/index.php
===================================================================
--- /tags/2.0.2/plugins/add_index/language/it_IT/help/index.php	(revision 3278)
+++ /tags/2.0.2/plugins/add_index/language/it_IT/help/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/plugins/add_index/language/it_IT/help/site_manager.html
===================================================================
--- /tags/2.0.2/plugins/add_index/language/it_IT/help/site_manager.html	(revision 3278)
+++ /tags/2.0.2/plugins/add_index/language/it_IT/help/site_manager.html	(revision 3278)
@@ -0,0 +1,7 @@
+<p>Funzionalità del plugin AddIndex:</p>
+<ul>
+  <li>
+    <strong>Aggiunge i files "index" per il sito locale:</strong>
+    Copia il file ./include/index.php in tutte le directory del sito selezzionato.
+  </li>
+<ul>
Index: /tags/2.0.2/plugins/add_index/language/it_IT/index.php
===================================================================
--- /tags/2.0.2/plugins/add_index/language/it_IT/index.php	(revision 3278)
+++ /tags/2.0.2/plugins/add_index/language/it_IT/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/plugins/add_index/language/it_IT/plugin.lang.php
===================================================================
--- /tags/2.0.2/plugins/add_index/language/it_IT/plugin.lang.php	(revision 3278)
+++ /tags/2.0.2/plugins/add_index/language/it_IT/plugin.lang.php	(revision 3278)
@@ -0,0 +1,39 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+$lang['Add_Index'] = 'Aggiunge dei files "index"';
+$lang['Advanced_Add_Index'] = 'Aggiunge e sovrascrive i files "index" per tutti i siti locali';
+$lang['Manager_Add_Index'] = 'Aggiunta dei "index"';
+
+$lang['add_index_file_copied'] = '%s copiati';
+$lang['add_index_file_not_copied'] = '%s non copiati';
+$lang['add_index_not_local_site'] = '%s [%d] è un sito remoto, non è compatibile con l\'aggiunta dei files "index"';
+$lang['add_index_nb_copied_file'] = '%d file copiato';
+$lang['add_index_nb_copied_files'] = '%d files copiati';
+$lang['add_index_nb_skipped_file'] = '%d file non trattato';
+$lang['add_index_nb_skipped_files'] = '%d files non trattati';
+$lang['add_index_nb_not_copied_file'] = '%d file non copiato';
+$lang['add_index_nb_not_copied_files'] = '%d files non copiati';
+$lang['add_index_src_file_dont_exists'] = 'Il file sorgente non esiste, impossibile dupplicarlo';
+
+?>
Index: /tags/2.0.2/plugins/add_index/language/pl_PL/help/advanced_feature.html
===================================================================
--- /tags/2.0.2/plugins/add_index/language/pl_PL/help/advanced_feature.html	(revision 3278)
+++ /tags/2.0.2/plugins/add_index/language/pl_PL/help/advanced_feature.html	(revision 3278)
@@ -0,0 +1,7 @@
+<p>Funkcjonalnoœæ wtyczki AddIndex:</p>
+<ul>
+  <li>
+    <strong>Aby dodaæ i nadpisaæ pliki "index" dla wszystkich stron lokalnych:</strong>
+    Nadpisz kopiê pliku ./include/index.php we wszystkich podkatalogach galerii lokalnej.
+  </li>
+<ul>
Index: /tags/2.0.2/plugins/add_index/language/pl_PL/help/index.php
===================================================================
--- /tags/2.0.2/plugins/add_index/language/pl_PL/help/index.php	(revision 3278)
+++ /tags/2.0.2/plugins/add_index/language/pl_PL/help/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/plugins/add_index/language/pl_PL/help/site_manager.html
===================================================================
--- /tags/2.0.2/plugins/add_index/language/pl_PL/help/site_manager.html	(revision 3278)
+++ /tags/2.0.2/plugins/add_index/language/pl_PL/help/site_manager.html	(revision 3278)
@@ -0,0 +1,7 @@
+<p>Funkcjonalność wtyczki AddIndex:</p>
+<ul>
+  <li>
+    <strong>Aby dodać pliki "index" dla strony lokalnej:</strong>
+    Skopiuj plik ./include/index.php do wszystkich podkatalogów wybranej strony.
+  </li>
+<ul>
Index: /tags/2.0.2/plugins/add_index/language/pl_PL/index.php
===================================================================
--- /tags/2.0.2/plugins/add_index/language/pl_PL/index.php	(revision 3278)
+++ /tags/2.0.2/plugins/add_index/language/pl_PL/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/plugins/add_index/language/pl_PL/plugin.lang.php
===================================================================
--- /tags/2.0.2/plugins/add_index/language/pl_PL/plugin.lang.php	(revision 3278)
+++ /tags/2.0.2/plugins/add_index/language/pl_PL/plugin.lang.php	(revision 3278)
@@ -0,0 +1,39 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+$lang['Add_Index'] = 'Dodaj pliki "index"';
+$lang['Advanced_Add_Index'] = 'Dodaj i nadpisz wszystkie pliki "index" we wszystkich lokalizacjach';
+$lang['Manager_Add_Index'] = 'dodaj "index"';
+
+$lang['add_index_file_copied'] = 'Skopiowano %s';
+$lang['add_index_file_not_copied'] = 'Nie skopiowano %s';
+$lang['add_index_not_local_site'] = '%s [%d] jest zdalną stroną i jest kompatybilna z plikami "index"';
+$lang['add_index_nb_copied_file'] = 'Skopiowano plik %d';
+$lang['add_index_nb_copied_files'] = 'Skopiowano %d plików';
+$lang['add_index_nb_skipped_file'] = 'Plik %d został pominięty';
+$lang['add_index_nb_skipped_files'] = 'Pominięto %d plików';
+$lang['add_index_nb_not_copied_file'] = 'Plik %d nie został skopiowany';
+$lang['add_index_nb_not_copied_files'] = 'Nie skopiowano %d plików';
+$lang['add_index_src_file_dont_exists'] = 'Plik źródłowy nie istnieje %s \- nie można powielić tego pliku';
+
+?>
Index: /tags/2.0.2/plugins/add_index/main.admin.inc.php
===================================================================
--- /tags/2.0.2/plugins/add_index/main.admin.inc.php	(revision 3278)
+++ /tags/2.0.2/plugins/add_index/main.admin.inc.php	(revision 3278)
@@ -0,0 +1,93 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if ((!defined('PHPWG_ROOT_PATH')) or (!(defined('IN_ADMIN') and IN_ADMIN)))
+{
+  die('Hacking attempt!');
+}
+
+class AdminAddIndex extends AddIndex
+{
+  function load_params()
+  {
+    global $conf;
+
+    // Name of index file (index.php or index.htm or index.html)
+    if (!isset($conf['add_index_filename']))
+    {
+      $conf['add_index_filename'] = 'index.php';
+    }
+    // Name of index file (index.php or index.htm or index.html)
+    if (!isset($conf['add_index_source_directory_path']))
+    {
+      // Name of the directoty use in order to copy index file
+      $conf['add_index_source_directory_path'] = PHPWG_ROOT_PATH.'include/';
+    }
+  }
+
+  function loading_lang()
+  {
+    load_language('plugin.lang', $this->path);
+  }
+
+  function get_admin_advanced_features_links($advanced_features)
+  {
+    array_push($advanced_features,
+      array
+      (
+        'CAPTION' => l10n('Advanced_Add_Index'),
+        'URL' => get_admin_plugin_menu_link(dirname(__FILE__).'/admin/main_page.php').'&amp;overwrite'
+      ));
+
+    return $advanced_features;
+  }
+
+  function get_admins_site_links($site_manager_plugin_links, $site_id, $is_remote)
+  {
+    if (!$is_remote)
+    {
+      array_push($site_manager_plugin_links,
+        array
+        (
+          'U_HREF' => get_admin_plugin_menu_link(dirname(__FILE__).'/admin/main_page.php').'&amp;site_id='.$site_id,
+          'U_CAPTION' => l10n('Manager_Add_Index'),
+          'U_HINT' => l10n('Add_Index')
+        ));
+    }
+
+    return $site_manager_plugin_links;
+  }
+}
+
+// Create object
+$add_index = new AdminAddIndex();
+
+// Load Add Index parameters
+$add_index->load_params();
+
+// Add events
+add_event_handler('loading_lang', array(&$add_index, 'loading_lang'));
+add_event_handler('get_admin_advanced_features_links', array(&$add_index, 'get_admin_advanced_features_links'));
+add_event_handler('get_admins_site_links', array(&$add_index, 'get_admins_site_links'), EVENT_HANDLER_PRIORITY_NEUTRAL, 3);
+
+?>
Index: /tags/2.0.2/plugins/add_index/main.base.inc.php
===================================================================
--- /tags/2.0.2/plugins/add_index/main.base.inc.php	(revision 3278)
+++ /tags/2.0.2/plugins/add_index/main.base.inc.php	(revision 3278)
@@ -0,0 +1,39 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+class AddIndex
+{
+  var $path;
+  
+  function AddIndex()
+  {
+    $this->path = dirname(__FILE__).'/';
+  }
+}
+
+?>
Index: /tags/2.0.2/plugins/add_index/main.inc.php
===================================================================
--- /tags/2.0.2/plugins/add_index/main.inc.php	(revision 3278)
+++ /tags/2.0.2/plugins/add_index/main.inc.php	(revision 3278)
@@ -0,0 +1,53 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 Piwigo team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+/*
+Plugin Name: Add Index
+Version: 2.0.2
+Description: Add file index.php file on all sub-directories of local galleries pictures. / Ajoute le fichier index.php sur les sous-répertoires de galeries d'images locales.
+Plugin URI: http://piwigo.org/ext/extension_view.php?eid=284
+Author: Piwigo team
+Author URI: http://piwigo.org
+*/
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+if (in_array(script_basename(), array('popuphelp', 'admin')))
+{
+  if (defined('IN_ADMIN') and IN_ADMIN)
+  {
+    include_once(dirname(__FILE__).'/'.'main.base.inc.php');
+    include_once(dirname(__FILE__).'/'.'main.admin.inc.php');
+  }
+  else
+  {
+    include_once(dirname(__FILE__).'/'.'main.base.inc.php');
+    include_once(dirname(__FILE__).'/'.'main.normal.inc.php');
+  }
+  set_plugin_data($plugin['id'], $add_index);
+}
+
+?>
Index: /tags/2.0.2/plugins/add_index/main.normal.inc.php
===================================================================
--- /tags/2.0.2/plugins/add_index/main.normal.inc.php	(revision 3278)
+++ /tags/2.0.2/plugins/add_index/main.normal.inc.php	(revision 3278)
@@ -0,0 +1,60 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+class NormalAddIndex extends AddIndex
+{
+  function get_popup_help_content($popup_help_content, $page)
+  {
+    if (in_array($page, array('advanced_feature', 'site_manager')))
+    {
+      $help_content =
+        load_language('help/'.$page.'.html', $this->path, array('return'=>true) );
+    }
+    else
+    {
+      $help_content = false;
+    }
+
+    if ($help_content == false)
+    {
+      return $popup_help_content;
+    }
+    else
+    {
+      return $popup_help_content.$help_content;
+    }
+  }
+}
+
+// Create object
+$add_index = new NormalAddIndex();
+
+// Add events
+add_event_handler('get_popup_help_content', array(&$add_index, 'get_popup_help_content'), EVENT_HANDLER_PRIORITY_NEUTRAL, 2);
+
+?>
Index: /tags/2.0.2/plugins/admin_advices/admin_advices.php
===================================================================
--- /tags/2.0.2/plugins/admin_advices/admin_advices.php	(revision 3278)
+++ /tags/2.0.2/plugins/admin_advices/admin_advices.php	(revision 3278)
@@ -0,0 +1,192 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 Piwigo team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+add_event_handler('loc_end_page_header', 'set_admin_advice_add_css' );
+
+// Add a XHTML tag in HEAD section
+function set_admin_advice_add_css()
+{
+  global $template, $page;
+  if ( isset($page['body_id']) and $page['body_id']=='theAdminPage'
+    and $page['page'] == 'intro'
+    )
+  {// This Plugin works only on the Admin page
+    $template->append(
+      'head_elements',
+      '<link rel="stylesheet" type="text/css" '
+                    . 'href="'.PHPWG_PLUGINS_PATH.'admin_advices/default-layout.css">'
+     );
+    add_event_handler('loc_begin_page_tail', 'set_admin_advice' );
+  }
+}
+
+// Build an advice on the Admin Intro page
+function set_admin_advice()
+{
+  global $page, $user, $template, $conf, $prefixeTable, $lang;
+  $my_path = dirname(__FILE__).'/';
+
+//  Include language advices
+  foreach ($conf as $key => $value)
+  {
+    if ( is_string($value) )
+    {
+      $bool = ($value == 'false') ? false : $value;
+      $bool = ($value == 'true') ? true : $bool;
+      $conf[$key] = $bool;
+    }
+  }
+  $adv = array();
+
+  include_once( $my_path."adv_set.php" );
+
+  $cases = range(0,count($lang['Adv_case'])-1);
+  srand ((double) microtime() * 10000000);
+  shuffle($cases);
+
+
+  $cond = false;  
+  foreach ($cases as $id)
+  {
+    if (!isset($adv['c'][$id])) $adv['c'][$id] = true;
+    if (!isset($adv['n'][$id])) $adv['c'][$id] = false;
+    if (!isset($lang['Adv_case'][$id])) $adv['c'][$id] = false;
+    $cond = $adv['c'][$id];
+    if ($cond) break;
+  }
+  $confk = $adv['n'][$id];
+  if (substr($confk,0,2) == '**') $confk = substr($confk,2);
+   else $confk = '$conf[' . "'$confk']";
+  $advice_text = (isset($adv['v'][$id])) ? $adv['v'][$id] : '';
+  $more = $lang['Adv_case'][$id];
+
+  $template->set_filenames(array(
+    'admin_advice' => $my_path.'admin_advices.tpl')
+    );
+
+// Mysql status
+  $result = pwg_query('SHOW TABLE STATUS ;');
+  $pwgspacef = $spacef = $pwgsize = $size = 0; 
+  $len = strlen($prefixeTable);
+  $check = array();
+  while ($row = mysql_fetch_array($result))
+  {
+    $size += ($row['Data_length'] + $row['Index_length']);
+    $spacef += $row['Data_free'];
+    if ( substr( $row['Name'], 0, $len ) == $prefixeTable ) { 
+      $pwgsize += ($row['Data_length'] + $row['Index_length']);
+      $pwgspacef += $row['Data_free'];
+      $check[] = (string) $row['Check_time'];
+    }
+  }
+  $size .= ' bytes';
+  $pwgsize .= ' bytes';
+  $spacef .= ' bytes';
+  $pwgspacef .= ' bytes';
+  if ($size > 1024) $size = round($size / 1024, 1) . ' Kb';
+  if ($size > 1024) $size = round($size / 1024, 1) . ' Mb';
+  if ($pwgsize > 1024) $pwgsize = round($pwgsize / 1024, 1) . ' Kb';
+  if ($pwgsize > 1024) $pwgsize = round($pwgsize / 1024, 1) . ' Mb';
+  if ($spacef > 1024) $spacef = round($spacef / 1024, 1) . ' Kb';
+  if ($spacef > 1024) $spacef = round($spacef / 1024, 1) . ' Mb';
+  if ($pwgspacef > 1024) $pwgspacef = round($pwgspacef / 1024, 1) . ' Kb';
+  if ($pwgspacef > 1024) $pwgspacef = round($pwgspacef / 1024, 1) . ' Mb';
+  $check = array_flip(array_flip($check));
+  rsort($check);
+  $end = end($check);
+  $prev = prev($check);
+  $first = $check[0];
+  $checkon = '';
+  if (empty($end)) $end = $prev;
+  if ($end == $first) $checkon .= 'Last table check on: %s';
+  else $checkon .= 'Most recent table check on: %s - oldest: %s';
+  $checkon = sprintf($checkon, $first, $end);
+  $template->assign(
+    array(
+      'prefixTable' => $prefixeTable,
+      'pwgsize' => $pwgsize,
+      'size' => $size,
+      'checked_tables' => $checkon,
+      'pwgspacef' => $pwgspacef,
+      'spacef' => $spacef,
+      'U_maintenance' => get_root_url()
+        . 'admin.php?page=maintenance&amp;action=database',
+      )
+    );
+
+//  If there is an advice
+  if ( $cond )
+  {
+
+// Random Thumbnail
+    $query = '
+SELECT *
+FROM '.IMAGES_TABLE.'
+ORDER BY RAND(NOW())
+LIMIT 0, 1
+;';
+    $result = pwg_query($query);
+    $row = mysql_fetch_assoc($result);
+    if ( is_array($row) )
+    {
+      $url_modify = get_root_url().'admin.php?page=picture_modify'
+                  .'&amp;image_id='.$row['id'];
+      $query = '
+SELECT * FROM '.IMAGE_TAG_TABLE.'
+WHERE image_id =  ' . $row['id'] .'
+;';
+      $tag_count = mysql_num_rows(pwg_query($query));
+      $template->assign('thumbnail',
+         array(
+           'IMAGE'              => get_thumbnail_url($row),
+           'IMAGE_ALT'          => $row['file'],
+           'IMAGE_TITLE'        => $row['name'],
+           'METADATA'           => (empty($row['date_metadata_update'])) ?
+                                   'un' : '',
+           'NAME'               => (empty($row['name'])) ?
+                                   'un' : '',
+           'COMMENT'            => (empty($row['comment'])) ?
+                                   'un' : '',
+           'AUTHOR'             => (empty($row['author'])) ?
+                                   'un' : '',
+           'CREATE_DATE'        => (empty($row['date_creation'])) ?
+                                   'un' : '',
+           'TAGS'               => ($tag_count == 0) ?
+                                   'un' : '',
+           'NUM_TAGS'           => $tag_count,
+           'U_MODIFY'           => $url_modify,
+         )
+       );
+    }
+    //$advice_text = array_shift($adv);
+    $template->assign(
+      array(
+        'ADVICE_ABOUT' => $confk,
+        'ADVICE_TEXT'  => $advice_text,
+         )
+      );
+  $template->assign('More', $more );
+  $template->pparse('admin_advice');
+  }  
+}
+?>
Index: /tags/2.0.2/plugins/admin_advices/admin_advices.tpl
===================================================================
--- /tags/2.0.2/plugins/admin_advices/admin_advices.tpl	(revision 3278)
+++ /tags/2.0.2/plugins/admin_advices/admin_advices.tpl	(revision 3278)
@@ -0,0 +1,73 @@
+<div class="content">
+
+  <h3>{'An_advice_about'|@translate} {$ADVICE_ABOUT}</h3>
+  <h4>{$ADVICE_TEXT}</h4>
+  <table summary="Admin advices summary">
+  {if isset($More)}
+  <tr>
+    <td style="text-align: left; width: 50%;">
+    {foreach from=$More item=advice}
+      {$advice}<BR />
+    {/foreach}
+    <br />
+    </td>
+    <td style="text-align: right; width: 20%;">
+    {if isset($thumbnail.IMAGE)}
+      <a href="{$thumbnail.U_MODIFY}" title="{'link_info_image'|@translate}">
+      <img class="thumbnail" src="{$thumbnail.IMAGE}"
+           alt="{$thumbnail.IMAGE_ALT}" title="{$thumbnail.IMAGE_TITLE}"></a>
+      </td><td style="text-align: left;">
+      <img src="{$themeconf.admin_icon_dir}/{$thumbnail.NAME}check.png"
+           alt="{$thumbnail.IMAGE_ALT}" title="{$thumbnail.IMAGE_TITLE}"> {'Name'|@translate}<br />
+      <img src="{$themeconf.admin_icon_dir}/{$thumbnail.COMMENT}check.png"
+           alt="{$thumbnail.IMAGE_ALT}" title="{$thumbnail.IMAGE_TITLE}"> {'Description'|@translate}<br />
+      <img src="{$themeconf.admin_icon_dir}/{$thumbnail.AUTHOR}check.png"
+           alt="{$thumbnail.IMAGE_ALT}" title="{$thumbnail.IMAGE_TITLE}"> {'Author'|@translate}<br />
+      <img src="{$themeconf.admin_icon_dir}/{$thumbnail.CREATE_DATE}check.png"
+           alt="{$thumbnail.IMAGE_ALT}" title="{$thumbnail.IMAGE_TITLE}"> {'Creation date'|@translate}<br />
+      <img src="{$themeconf.admin_icon_dir}/{$thumbnail.METADATA}check.png"
+           alt="{$thumbnail.IMAGE_ALT}" title="{$thumbnail.IMAGE_TITLE}"> {'Metadata'|@translate}<br />
+      <img src="{$themeconf.admin_icon_dir}/{$thumbnail.TAGS}check.png"
+           alt="{$thumbnail.IMAGE_ALT}" title="{$thumbnail.IMAGE_TITLE}"> {'Tags'|@translate} ({$thumbnail.NUM_TAGS})
+    {/if}
+    </td>
+  </tr>
+  {/if}
+  </table>
+  <div class="summary">
+    <h4>External summary</h4>
+    <ul>Database Analysis<br />
+      {if ($pwgsize != $size)}
+      - Space used by {$prefixTable} tables: {$pwgsize}<br />
+      {/if}
+      - Space used by all tables: {$size}<br />
+      - {$checked_tables}<br />
+      - Unused allocated space by {$prefixTable} tables: {$pwgspacef}<br />
+      {if ($spacef > 0 and $pwgspacef != $spacef)} 
+        - Unused allocated space: {$spacef}<br />
+      {/if}
+      {if ($spacef > 0)}
+      Useful links: 
+        <a class="internal" href="{$U_maintenance}">{'repair and optimize database'|@translate}</a> - 
+        {else}
+      MySQL documentation: 
+      {/if}
+        <a class="external" href="http://dev.mysql.com/doc/" onclick="window.open(this.href, ''); return false;">MySQL</a>
+      <br /><br />
+    Templates generated on {$smarty.now|date_format:"%A, %B %e, %Y - %r"} by 
+    <a class="external" href="http://www.smarty.net/" onclick="window.open(this.href, ''); return false;">Smarty</a>
+    {$smarty.version}
+    </ul>
+  </div>
+</div>
+<script type="text/javascript">// <![CDATA[
+{literal}$(document).ready(function() {
+	$("img.thumbnail").fadeTo("slow", 0.6); // Opacity on page load
+	$("img.thumbnail").hover(function(){
+		$(this).fadeTo("slow", 1.0); // Opacity on hover
+	},function(){
+   		$(this).fadeTo("slow", 0.6); // Opacity on mouseout
+	});
+});{/literal}
+// ]]>
+</script>
Index: /tags/2.0.2/plugins/admin_advices/adv_set.php
===================================================================
--- /tags/2.0.2/plugins/admin_advices/adv_set.php	(revision 3278)
+++ /tags/2.0.2/plugins/admin_advices/adv_set.php	(revision 3278)
@@ -0,0 +1,181 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+
+//
+// A new advices needs:
+//    $lang['Adv_case'][xx] = 'Text' ==> in all plugin.lang
+//    $adv['c'][xx] = Condition (default true)
+//    $adv['v'][xx] = Value (if there is one (facultative))
+//    $adv['n'][xx] = Name of $conf (A new advice about blah-blah)
+//
+//    prefix '**' . => Not a $conf['xxxxx']
+
+load_language('plugin.lang', dirname(__FILE__).'/');
+
+// No needed translation here below 
+
+// Use l10n if your need a localization and update all plugin.lang
+
+$adv['n'][0] = '**' . $lang['contribute'];
+
+$adv['n'][1] = 'newcat_default_status';
+$adv['c'][1] = ($conf['newcat_default_status'] !== 'public');
+$adv['v'][1] = sprintf($lang['current'], 'public');
+
+$adv['n'][2] = 'slideshow_period';
+$adv['c'][2] = ( $conf['slideshow_period'] < 4 );
+$adv['v'][2] = sprintf($lang['current'], $conf['slideshow_period']);
+
+$adv['n'][3] = 'file_ext';
+$adv['c'][3] = ( in_array('php',$conf['file_ext']) );
+$adv['v'][3] = sprintf($lang['current'], implode(', ', $conf['file_ext']));
+
+$adv['n'][4] = 'show_iptc_mapping';
+
+$adv['n'][5] = 'top_number';
+$adv['c'][5] = ( $conf['top_number'] > 50 );
+$adv['v'][5] = sprintf($lang['current'], $conf['top_number']);
+
+$adv['n'][6] = 'top_number';
+$adv['c'][6] = ( $conf['top_number'] < 2 ) ? true : false;
+$adv['v'][6] = sprintf($lang['current'], $conf['top_number']);
+
+$adv['n'][7] = 'anti-flood_time';
+$adv['c'][7] = ( $conf['anti-flood_time'] > 100 ) ? true : false;
+$adv['v'][7] = sprintf($lang['current'], $conf['anti-flood_time']);
+
+$adv['n'][8] = 'calendar_datefield';
+$adv['c'][8] = ( !in_array($conf['calendar_datefield'],
+        array('date_creation','date_available')) );
+$adv['v'][8] = sprintf($lang['current'], $conf['calendar_datefield']);
+
+/* Unavailable creation date and default calendar is creation date */
+$adv['n'][9] = 'calendar_datefield';
+$adv['c'][9] = ( (( $conf['use_exif'] and
+                isset($conf['use_exif_mapping']['date_creation']) ) 
+                or ( $conf['use_iptc'] and
+                isset($conf['use_iptc_mapping']['date_creation']) )) 
+                and ( $conf['calendar_datefield'] == 'date_creation' ) ) 
+                ? false : true;
+$adv['v'][9] = sprintf($lang['current'], $conf['calendar_datefield']);
+
+$adv['n'][10] = 'newcat_default_visible';
+$adv['c'][10] = !$conf['newcat_default_visible'];
+$adv['v'][10] = sprintf($lang['current'], 'false');
+
+$adv['n'][11] = 'level_separator';
+$adv['c'][11] = ( $conf['level_separator'] == ' / ' );
+$adv['v'][11] = sprintf($lang['current'], $conf['level_separator']);
+
+$adv['n'][12] = 'paginate_pages_around';
+$adv['c'][12] = (($conf['paginate_pages_around'] < 2)
+            or ($conf['paginate_pages_around'] > 12));
+$adv['v'][12] = sprintf($lang['current'], $conf['paginate_pages_around']);
+
+$adv['n'][13] = 'tn_width';
+$adv['c'][13] = (($conf['tn_width'] < 66)
+            or ($conf['tn_width'] > 180));
+$adv['v'][13] = sprintf($lang['current'], $conf['tn_width']);
+
+$adv['n'][14] = 'tn_height';
+$adv['c'][14] = (($conf['tn_height'] < 66)
+            or ($conf['tn_height'] > 180));
+$adv['v'][14] = sprintf($lang['current'], $conf['tn_height']);
+
+$adv['n'][15] = 'tn_height';
+
+$adv['c'][15] = ( $conf['tn_height'] !== $conf['tn_width'] );
+$adv['v'][15] = l10n('TN-height&width');
+
+$adv['n'][16] = 'show_version';
+$adv['c'][16] = $conf['show_version'];
+$adv['v'][16] = sprintf($lang['current'], 'true');
+
+$adv['n'][17] = 'show_thumbnail_caption';
+$adv['c'][17] = $conf['show_thumbnail_caption'];
+$adv['v'][17] = sprintf($lang['current'], 'true');
+
+$adv['n'][18] = 'show_picture_name_on_title';
+$adv['c'][18] = $conf['show_picture_name_on_title'];
+$adv['v'][18] = sprintf($lang['current'], 'true');
+
+$adv['n'][19] = 'tags_default_display_mode';
+$adv['c'][15] = ( $conf['tags_default_display_mode'] == 'cloud' );
+$adv['v'][19] = sprintf($lang['current'], "'".$conf['tags_default_display_mode']."'");
+
+$adv['n'][20] = 'allow_random_representative';
+$adv['c'][20] = $conf['allow_random_representative'];
+$adv['v'][20] = sprintf($lang['current'], 'true');
+
+$adv['n'][21] = 'prefix_thumbnail';
+$adv['c'][21] = ( $conf['prefix_thumbnail'] !== 'TN-' );
+$adv['v'][21] = sprintf($lang['current'], $conf['prefix_thumbnail']);
+
+$adv['n'][22] = 'users_page';
+$adv['c'][22] = ( $conf['users_page'] < 21 );
+$adv['v'][22] = sprintf($lang['current'], $conf['users_page']);
+
+$adv['n'][23] = 'mail_options';
+$adv['c'][23] = $conf['mail_options'];
+$adv['v'][23] = sprintf($lang['current'], 'true');
+
+$adv['n'][24] = 'check_upgrade_feed';
+$adv['c'][24] = $conf['check_upgrade_feed'];
+$adv['v'][24] = sprintf($lang['current'], 'true');
+
+$adv['n'][25] = 'rate_items';
+$adv['c'][25] = ( count($conf['rate_items']) < 4 );
+$adv['v'][25] = sprintf($lang['current'], $conf['rate_items']);
+
+$adv['n'][26] = 'rate_items';
+$adv['c'][26] = ( count($conf['rate_items']) > 6 );
+$adv['v'][26] = sprintf($lang['current'], $conf['rate_items']);
+
+$adv['n'][27] = 'show_iptc';
+$adv['c'][27] = $conf['show_iptc'];
+$adv['v'][27] = sprintf($lang['current'], 'true');
+
+$adv['n'][28] = 'use_iptc';
+$adv['c'][28] = $conf['use_iptc'];
+$adv['v'][28] = sprintf($lang['current'], 'true');
+
+$adv['n'][29] = 'use_iptc';
+
+$adv['n'][30] = 'use_iptc_mapping';
+
+$adv['n'][31] = 'show_exif';
+$adv['v'][31] = sprintf($lang['current'], (($conf['show_exif'])? 'true':'false' ));
+
+$adv['n'][32] = 'use_exif';
+$adv['v'][32] = sprintf($lang['current'], (($conf['use_exif'])? 'true':'false' ));
+
+$adv['n'][33] = '**' . $lang['navigation'];
+
+$adv['n'][34] = 'compiled_template_cache_language';
+$adv['v'][34] = sprintf($lang['current'], (($conf['compiled_template_cache_language'])? 'true':'false' ));
+
+$adv['n'][35] = 'template_compile_check';
+$adv['v'][35] = sprintf($lang['current'], (($conf['template_compile_check'])? 'true':'false' ));
+
+?>
Index: /tags/2.0.2/plugins/admin_advices/default-layout.css
===================================================================
--- /tags/2.0.2/plugins/admin_advices/default-layout.css	(revision 3278)
+++ /tags/2.0.2/plugins/admin_advices/default-layout.css	(revision 3278)
@@ -0,0 +1,19 @@
+/*.content {
+  list-style-type:none; 
+  margin: 0 1em 0 14.5em; 
+  padding: 0 0 15px 0;
+} */
+.content h2 {
+  font-weight: bold; 
+  padding-left: 2em;
+}
+/*.content h3 {
+  text-align: left; 
+  padding-left: 3em;
+  font-size: 120%;
+}*/
+.content table tr td {
+  text-align: left; 
+  padding-left: 2em; 
+}
+
Index: /tags/2.0.2/plugins/admin_advices/index.php
===================================================================
--- /tags/2.0.2/plugins/admin_advices/index.php	(revision 3278)
+++ /tags/2.0.2/plugins/admin_advices/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/plugins/admin_advices/language/de_DE/index.php
===================================================================
--- /tags/2.0.2/plugins/admin_advices/language/de_DE/index.php	(revision 3278)
+++ /tags/2.0.2/plugins/admin_advices/language/de_DE/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/plugins/admin_advices/language/de_DE/plugin.lang.php
===================================================================
--- /tags/2.0.2/plugins/admin_advices/language/de_DE/plugin.lang.php	(revision 3278)
+++ /tags/2.0.2/plugins/admin_advices/language/de_DE/plugin.lang.php	(revision 3278)
@@ -0,0 +1,169 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software, you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY, without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program, if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// --------- Starting below: New or revised $lang ---- from Butterfly (1.8)
+$lang['An_advice_about'] = 'Ein neues Gutachten über';
+$lang['contribute'] = 'wie Sie beitragen können'; 
+$lang['navigation'] = 'Navigation';
+$lang['Metadata'] = 'Metadaten';
+$lang['current'] =  'Aktueller Wert: %s.';
+$lang['TN-height&width'] = 'Thumbnail Höhe und Breite müssen gleich sein.';
+$lang['Adv_case'][0] = array( /* **contribute */
+ 'Wenn Sie mit Ihrem eigenen Beitrag "Trick", danke für die Veröffentlichung',
+ 'auf den Forum von Piwigo (oder durch private Nachricht an einen der Entwickler),', 
+ 'und wir würden gerne um es innerhalb nächste Veröffentlichung.', );
+$lang['Adv_case'][1] = array( /* newcat_default_status */
+ 'Versuchen $conf[\'newcat_default_status\'] = \'private\',',
+ 'Sie werden mehr Zeit haben zu beschreiben und überprüfen Sie Ihre Bilder.',
+ 'Zeit zu entscheiden zwischen privaten und öffentlichen Status.',
+ 'Wenn Sie privat wählen, Zeit zu vertreiben Genehmigung.',
+ 'Ihre neue Kategorie wird gut vorbereitet.', );
+$lang['Adv_case'][2] = array( /* slideshow_period */
+ 'Dieser Wert könnte zu klein für niedrige Band-Verbindungen.',
+ 'Denken Sie an höheren Wert wie 4.', );
+$lang['Adv_case'][3] = array( /* file_ext */
+ 'Sollte nie enthält Erweiterungen die ausgeführt werden können',
+ 'auf der Server-Seite wie *.php, *.php, *.asp,...', );
+$lang['Adv_case'][4] = array( /* show_iptc_mapping */
+ 'Zeige die IPTC-Daten von Ihrem Bild:',
+ ' 1 - Kopieren Sie eines Ihrer jpg Bilder (eine öffentliches) in ./tools/',
+ ' 2 - Benennen Sie es als sample.jpg.',
+ ' 3 - Führen Sie ./tools/metadata.php',
+ ' 4 - Ergebnisse analysieren um festzustellen welche IPTC-Felder nützlich sein könnte für Ihre Besucher.',
+ 'Anfänger würde es vorziehen $conf[\'show_iptc\'] = false,',
+ 'Fortgeschrittene Benutzer würde kümmern $lang Werte und Auswirkungen auf die Vorlagen.', );
+$lang['Adv_case'][5] = array( /* top_number */
+ 'Dieser Wert ist vielleicht zu hoch für niedrige Verbindungen hat, kann man 25-50 abhängig von Ihrem Thumbnail-Größen.', );
+$lang['Adv_case'][6] = array( /* top_number */
+ 'Ein? Es könnte sein zu niedrig für Zufalls-Bilder hat kann man 5-10 abhängig von Ihrem Thumbnail-Größen.',  );
+$lang['Adv_case'][7] = array( /* anti-flood_time */
+ 'Für normale Flow-Verarbeitung, Ihr Wert ist wahrscheinlich zu hoch. Angemessenen Wert ist 60 (Standard).' , );
+$lang['Adv_case'][8] = array( /* calendar_datefield */
+ 'Autorisierten Werte sind ' ."'date_creation' oder 'date_available'" . ', Sonst können Sie unvorhersehbare Ergebnisse.' , );
+$lang['Adv_case'][9] = array( /* calendar_datefield */
+ "'date_creation'" . ' ist NICHT gefüllt von jedem aktiviert Verwendung von Metadaten-Mapping Felder aus.',
+ 'So aktivieren Metadaten Nutzung <strong>oder</strong> ändern bis zu $conf[\'calendar_datefield\']=\'date_available\'',
+ 'Aktivieren Sie Metadaten-Nutzung wie Sie wollen: ',
+ '1 - $conf[\'use_iptc\'] = true, or $conf[\'use_exif\'] = true, jeder Weg wird korrekt.',
+ '2 - Jeweils zu den einzelnen Änderungen:',
+ '$conf[\'use_iptc_mapping\'] = array( ..., \'date_creation\'  => \'2#055\', ...',
+ 'oder/und:',
+ '$conf[\'use_exif_mapping\'] = array(\'date_creation\' => \'DateTimeOriginal\', ...',
+ '3 - Schließlich, eine neue Aufgabe liegt an Ihnen: Metadata-Synchronisierung.', );
+$lang['Adv_case'][10] = array( /* newcat_default_visible */
+ 'Nicht sinnvoll, privaten Status ist besser, so dass Code $conf[\'newcat_default_visible\'] = true,', );
+$lang['Adv_case'][11] = array( /* level_separator */
+ 'Probieren Sie etwas anderes wie $conf[\'level_separator\'] = \'+ \',',  );
+$lang['Adv_case'][12] = array( /* paginate_pages_around */
+ 'Üblichen Bereich liegt zwischen 2 und 5. Mehr leichter, wählen Sie $conf[\'paginate_pages_around\'] = 2, ',
+ 'So bieten große Sprung, wählen Sie $conf[\'paginate_pages_around\'] = 7,', );
+$lang['Adv_case'][13] = array( /* tn_width */
+ 'Sollte eine enge Wert auf Ihre Thumbnail-Breite. Üblichen Bereich liegt zwischen 96 und 150, über $conf[\'tn_width\'] = 128,', );
+$lang['Adv_case'][14] = array( /* tn_height */
+ 'Sollte eine enge Wert auf Ihre Thumbnail-Höhe. Üblichen Bereich liegt zwischen 96 und 150, über $conf[\'tn_height\'] = 128,', );
+$lang['Adv_case'][15] = array( /* tn_height */
+ 'Thumbnail Höhe und Breite müssen gleich sein.',
+ 'Wählen $conf[\'tn_height\'] = $conf[\'tn_width\'],',
+ 'oder $conf[\'tn_width\'] = $conf[\'tn_height\'],', );
+$lang['Adv_case'][16] = array( /* show_version */
+ 'Aus Sicherheitsgründen, setzen Sie bitte $conf[\'show_version\'] = false,', );
+$lang['Adv_case'][17] = array( /* show_thumbnail_caption */
+ 'Für eine leichtere Galerie müssen nur einen Blick bis zu $conf[\'show_thumbnail_caption\'] = false,', );
+$lang['Adv_case'][18] = array( /* show_picture_name_on_title */
+ 'Für eine leichtere Galerie müssen nur einen Blick bis zu $conf[\'show_picture_name_on_title\'] = false,', );
+
+$lang['Adv_case'][20] = array( /* allow_random_representative */
+ 'Verlassen $conf[\'allow_random_representative\'] = true, ',
+ 'aber analysieren, wenn Sie können verhindern, dass für Performance-Gründen.' , );
+$lang['Adv_case'][21] = array( /* prefix_thumbnail */
+ 'Seien Sie vorsichtig, Ihre $conf[\'prefix_thumbnail\'] ist NICHT Standard.',
+ 'Ändern sich NICHT, es sei denn, Ihr Thumbnails sind NICHT sichtbar.',
+ 'Entfernten Standort übertragen verwenden Sie ein anderes Präfix aber create_listing_file.php muss geändert werden.',
+ 'Sie erhalten eine Warnmeldung während der Synchronisierung in diesem Fall.',
+ 'Versuchen Sie den gleichen Präfix durch alle Ihre Websites entweder lokal oder distants.',
+ 'Halten Sie diesen Parameter in Ihrer ./include/config_ <strong>local.inc.php</strong>',
+ 'Auf unserer Wiki Konfiguration Seite finden Sie weitere Informationen zum ./include/config_<strong>local.inc.php</strong>.', );
+$lang['Adv_case'][22] = array( /* users_page */
+ 'Es sei denn, Sie haben ein niedriges Band-Anschluss besitzen, können erstellt $conf[\'users_page\'] auf einen höheren Wert, wenn Sie mehr als 20 Mitglieder.', );
+$lang['Adv_case'][23] = array( /* mail_options */
+ 'Sollte falsch, nur wenige Webmaster haben um $conf[\'mail_options\'] = true, ',
+ 'Eine spezifische Beratung können Sie von einem fortgeschrittenen Benutzer auf unserem Forum in einigen Mailing-Fragen.', );
+$lang['Adv_case'][24] = array( /* check_upgrade_feed */
+ 'Sollte falsch, nur PWG dev Team haben um $conf[\'check_upgrade_feed\'] = true, für Test-Zwecke.' , );
+$lang['Adv_case'][25] = array( /* rate_items */
+ 'Ihr $conf[\'rate_items\'] hätte es 4 oder 5 Posten, nicht weniger', );
+$lang['Adv_case'][26] = array( /* rate_items */
+ 'Ihr $conf[\'rate_items\'] hätte 5 oder 6 Posten, nicht mehr.',
+ 'Überprüfen Sie Ihre besten bewertet Bilder vor um einige Werte.',
+ 'Reduzieren Sie übermäßige Einschätzung des Hotels und ändern Sie Ihre $conf[\'rate_items\'].', );
+$lang['Adv_case'][27] = array( /* show_iptc */
+ 'Könnte wahr sein, denken Sie etwa $conf[\'show_iptc\'] = false,',
+ 'Einige professionelle Fotografen wählen Sie falsche ihre Gründe dafür sind nicht wirklich professionell.' ,
+ 'NICHT zu verwechseln zwischen <strong>show</strong>_iptc und <strong>use</strong>_iptc (werfen Sie einen Blick auf Metadaten-Seite auf unserem Wiki).', );
+$lang['Adv_case'][28] = array( /* use_iptc */
+ 'Dokumentare und professionellen Fotografen würde es stimmt, aber Anfänger sollten es als $conf[\'use_iptc\'] = false,',
+ 'Achten Sie darauf, der Hinweise auf Bereiche, in Metadaten-Synchronisierung.',
+ 'Genannten Bereichen wäre rewrited mit IPTC-Werte selbst in denjenigen sind NICHT leer.',
+ 'NICHT zu verwechseln zwischen <strong>show</strong>_iptc und <strong>use</strong>_iptc (werfen Sie einen Blick auf Metadaten-Seite auf unserem Wiki).', );
+$lang['Adv_case'][29] = array( /* use_iptc */
+ 'Der Umgang mit IPTC:',
+ '1 - Kopieren Sie eines Ihrer jpg Bilder (eine öffentliche eins) in ./tools/',
+ '2 - Benennen Sie es als sample.jpg.',
+ '3 - Start ./tools/metadata.php', 
+ '4 - Ergebnisse analysieren, um festzustellen welche IPTC-Felder genutzt werden könnte um Datenbank-Felder.',
+ 'Anfänger würde es vorziehen $conf[\'use_iptc\'] = false,',
+ 'Fortgeschrittene Benutzer machen Dokumentation Anstrengungen vor dem Upload ihrer Bilder.',
+ 'IPTC-Felder müssen ausgefüllt werden beschrieben in $conf[\'use_iptc_mapping\']',
+ 'Auf jedem Fall, <strong>show</strong>_iptc_mapping und <strong>use</strong>_iptc_mapping muss völlig anders aus.', );
+$lang['Adv_case'][30] = array( /* use_iptc_mapping */
+ 'Der Umgang mit IPTC:',
+ 'Achten Sie darauf, der Hinweise auf Bereiche, in Metadaten-Synchronisierung.',
+ 'Genannten Bereichen wäre rewrited mit IPTC-Werte selbst in denjenigen sind NICHT leer.',
+ 'Auf jedem Fall, <strong>show</strong>_iptc_mapping und <strong>use</strong>_iptc_mapping muss völlig anders aus.', );
+$lang['Adv_case'][31] = array( /* show_exif */
+ 'Sollte wahr sein, einige Informationen von Ihrer Kamera angezeigt werden kann.',
+ 'Denken Sie über EXIF-Informationen könnten werden verschiedene nach Kamera-Modelle.',
+ 'Wenn Sie ändern Ihre Kamera diesen Bereichen könnte zum Teil anders.',
+ 'Viele professionelle Fotografen wählen Sie falsch, ihre Gründe dafür sind zum Schutz ihres Wissens.' ,
+ 'NICHT zu verwechseln zwischen <strong>show</strong>_exif und <strong>use</strong>_exif (werfen Sie einen Blick auf Metadaten-Seite auf unserem Wiki).', );
+$lang['Adv_case'][32] = array( /* use_exif */
+ 'Dokumentare und professionellen Fotografen würde es stimmt, aber Anfänger sollten den Standardwert.',
+ 'Achten Sie darauf der Hinweise auf Bereiche in Metadaten-Synchronisierung.',
+ 'Genannten Bereichen wäre rewrited mit EXIF-Werte selbst in denjenigen sind NICHT leer.',
+ 'NICHT zu verwechseln zwischen <strong>show</strong>_exif und <strong>use</strong>_exif (werfen Sie einen Blick auf Metadaten-Seite auf unserem Wiki).', );
+$lang['Adv_case'][33] = array( /* **navigation */
+ 'Sie können mit der Tastatur Pfeile zum Navigieren zwischen den Bildern.', );
+$lang['Adv_case'][34] = array( /* compiled_template_cache_language */
+ 'Should be true, translation will be done at compilation time.',
+ 'If you are modifying a language (translators), you should consider to set it false.',
+ 'Setting it false, template @translate function are called at usage time.' );
+$lang['Adv_case'][35] = array( /* template_compile_check */
+ 'Default is true, template changes are detected and the template is compiled.',
+ 'If you are not updating template any more for several days, ',
+ 'you should consider to set it false.',
+ 'Choosing false, template changes are not detected, this improves response time.',
+ 'Anyway Specials > Maintenance > Purge compiled templates, is recommended after this $conf change.' );
+$lang['Adv_case'][19] = array( /* tags_default_display_mode */
+ '\'cloud\' by default, importance of tags is shown with font size.',
+ 'You can change the tags page, $conf[\'tags_default_display_mode\'] = \'letters\'', );
+?>
Index: /tags/2.0.2/plugins/admin_advices/language/en_UK/index.php
===================================================================
--- /tags/2.0.2/plugins/admin_advices/language/en_UK/index.php	(revision 3278)
+++ /tags/2.0.2/plugins/admin_advices/language/en_UK/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/plugins/admin_advices/language/en_UK/plugin.lang.php
===================================================================
--- /tags/2.0.2/plugins/admin_advices/language/en_UK/plugin.lang.php	(revision 3278)
+++ /tags/2.0.2/plugins/admin_advices/language/en_UK/plugin.lang.php	(revision 3278)
@@ -0,0 +1,168 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software, you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY, without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program, if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// --------- Starting below: New or revised $lang ---- from Butterfly (1.8)
+$lang['An_advice_about'] = 'A new advice about';
+$lang['contribute'] = 'how you can contribute'; 
+$lang['navigation'] = 'navigation';
+$lang['Metadata'] = 'Metadata';
+$lang['current'] =  'Current value: %s.';
+$lang['TN-height&width'] = 'Thumbnail height and width have to be equal.';
+$lang['Adv_case'][0] = array( /* **contribute */
+ 'If you want to contribute with your own "tip", please publish it',
+ 'on Piwigo Forums (or mail it to the one of the developers),', 
+ 'and we would be happy to add it within next release.', );
+$lang['Adv_case'][1] = array( /* newcat_default_status */
+ 'Try $conf[\'newcat_default_status\'] = \'private\',',
+ 'You will have more time to describe and check your pictures.',
+ 'Time to decide between private and public status.',
+ 'If you choose private, time to distribute authorization.',
+ 'Your new category will be well prepared.', );
+$lang['Adv_case'][2] = array( /* slideshow_period */
+ 'This value could be too small for low band connections.',
+ 'Think about higher value like 4.', );
+$lang['Adv_case'][3] = array( /* file_ext */
+ 'Should never contains extensions which can be executed',
+ 'on the server side like *.php, *.PHP, *.asp, ...', );
+$lang['Adv_case'][4] = array( /* show_iptc_mapping */
+ 'Show IPTC Data from your picture:',
+ ' 1 - Copy one of your jpg pictures (a public one) in ./tools/',
+ ' 2 - Rename it as sample.jpg.',
+ ' 3 - Run ./tools/metadata.php',
+ ' 4 - Analyse results to determine which IPTC fields could be useful for your visitors.',
+ 'Beginners would prefer to keep $conf[\'show_iptc\'] = false,',
+ 'Advanced users would take care of $lang values and impacts on templates.', );
+$lang['Adv_case'][5] = array( /* top_number */
+ 'This value is maybe too high for low connections, think about 25-50 depending on your thumbnail sizes.', );
+$lang['Adv_case'][6] = array( /* top_number */
+ 'One? It could be too low for random pictures, think about 5-10 depending on your thumbnail sizes.',  );
+$lang['Adv_case'][7] = array( /* anti-flood_time */
+ 'For normal flow processing, your value is probably too high. Reasonable value is 60 (default).' , );
+$lang['Adv_case'][8] = array( /* calendar_datefield */
+ 'Authorized values are ' . "'date_creation' or 'date_available'" . ', otherwise you can get unpredictable results.' , );
+$lang['Adv_case'][9] = array( /* calendar_datefield */
+ "'date_creation'" . ' is NOT filled by any activated use metadata mapping fields.',
+ 'So activate metadata usage <strong>or</strong> change to $conf[\'calendar_datefield\'] = \'date_available\'',
+ 'Activate metadata usage as you want: ',
+ '1 - $conf[\'use_iptc\'] = true, or $conf[\'use_exif\'] = true, each way will be correct.',
+ '2 - And respectively map:',
+ '$conf[\'use_iptc_mapping\'] = array( ..., \'date_creation\'  => \'2#055\', ...',
+ 'or/and:',
+ '$conf[\'use_exif_mapping\'] = array(\'date_creation\' => \'DateTimeOriginal\', ...',
+ '3 - Finally, a new task is up to you: Metadata synchronization.', );
+$lang['Adv_case'][10] = array( /* newcat_default_visible */
+ 'Not useful, private status is better, so code $conf[\'newcat_default_visible\'] = true,', );
+$lang['Adv_case'][11] = array( /* level_separator */
+ 'Try something else like $conf[\'level_separator\'] = \'+ \',',  );
+$lang['Adv_case'][12] = array( /* paginate_pages_around */
+ 'Usual range is between 2 and 5. To be light, choose $conf[\'paginate_pages_around\'] = 2, ',
+ 'To offer large jump, choose $conf[\'paginate_pages_around\'] = 7,', );
+$lang['Adv_case'][13] = array( /* tn_width */
+ 'Should be a close value to your thumbnail width. Usual range is between 96 and 150, about $conf[\'tn_width\'] = 128,', );
+$lang['Adv_case'][14] = array( /* tn_height */
+ 'Should be a close value to your thumbnail height. Usual range is between 96 and 150, about $conf[\'tn_height\'] = 128,', );
+$lang['Adv_case'][15] = array( /* tn_height */
+ 'Thumbnail height and width have to be equal.',
+ 'Choose $conf[\'tn_height\'] = $conf[\'tn_width\'],',
+ 'or $conf[\'tn_width\'] = $conf[\'tn_height\'],', );
+$lang['Adv_case'][16] = array( /* show_version */
+ 'For security reason, please set $conf[\'show_version\'] = false,', );
+$lang['Adv_case'][17] = array( /* show_thumbnail_caption */
+ 'For a lighter gallery just have a look to $conf[\'show_thumbnail_caption\'] = false,', );
+$lang['Adv_case'][18] = array( /* show_picture_name_on_title */
+ 'For a lighter gallery just have a look to $conf[\'show_picture_name_on_title\'] = false,', );
+$lang['Adv_case'][19] = array( /* tags_default_display_mode */
+ '\'cloud\' by default, importance of tags is shown with font size.',
+ 'You can change the tags page, $conf[\'tags_default_display_mode\'] = \'letters\'', );
+$lang['Adv_case'][20] = array( /* allow_random_representative */
+ 'Leave $conf[\'allow_random_representative\'] = true, ',
+ 'but analyze if you can avoid for performance reasons.' , );
+$lang['Adv_case'][21] = array( /* prefix_thumbnail */
+ 'Be careful your $conf[\'prefix_thumbnail\'] is NOT standard.',
+ 'Do NOT change it except if your thumbnails are NOT visible.',
+ 'Distant site may use a different prefix but create_listing_file.php must be modified.',
+ 'You will get a warning message during synchronization in that case.',
+ 'Try to keep the same prefix thru all your sites either local or distants.',
+ 'Keep this parameter in your ./include/config_ <strong>local.inc.php</strong>',
+ 'See our wiki configuration page for more information about ./include/config_<strong>local.inc.php</strong>.', );
+$lang['Adv_case'][22] = array( /* users_page */
+ 'Unless you have a low band connection, you can draw up $conf[\'users_page\'] to a higher value if you have more than 20 members.', );
+$lang['Adv_case'][23] = array( /* mail_options */
+ 'Should be false, only few webmasters have to set $conf[\'mail_options\'] = true, ',
+ 'A specific advice you can get from an advanced user on our forum in some mailing issues.', );
+$lang['Adv_case'][24] = array( /* check_upgrade_feed */
+ 'Should be false, only PWG dev Team have to set $conf[\'check_upgrade_feed\'] = true, for test purpose.' , );
+$lang['Adv_case'][25] = array( /* rate_items */
+ 'Your $conf[\'rate_items\'] would have 4 or 5 items not less.', );
+$lang['Adv_case'][26] = array( /* rate_items */
+ 'Your $conf[\'rate_items\'] would have 5 or 6 items not more.',
+ 'Check your best rated pictures prior to remove some values.',
+ 'Reduce excessive rating and change your $conf[\'rate_items\'].', );
+$lang['Adv_case'][27] = array( /* show_iptc */
+ 'Could be true, think about $conf[\'show_iptc\'] = false,',
+ 'Some Professional photographers choose false their reasons are not really professional.' ,
+ 'Do NOT confuse between <strong>show</strong>_iptc and <strong>use</strong>_iptc (have a look on metadata page on our wiki).', );
+$lang['Adv_case'][28] = array( /* use_iptc */
+ 'Documentalists and professionnal photographers would set it true, but beginners should leave it as $conf[\'use_iptc\'] = false,',
+ 'Take care of mentionned fields in metadata synchronization.',
+ 'Mentionned fields would be rewrited with IPTC values even those ones are NOT empty.',
+ 'Do NOT confuse between <strong>show</strong>_iptc and <strong>use</strong>_iptc (have a look on metadata page on our wiki).', );
+$lang['Adv_case'][29] = array( /* use_iptc */
+ 'How to deal with IPTC:',
+ '1 - Copy one of your jpg pictures (a public one) in ./tools/',
+ '2 - Rename it as sample.jpg.',
+ '3 - Run ./tools/metadata.php', 
+ '4 - Analyse results to determine which IPTC fields could be used to override database fields.',
+ 'Beginners would prefer to keep $conf[\'use_iptc\'] = false,',
+ 'Advanced users make documentation efforts prior to upload their pictures.',
+ 'IPTC fields have to be described in $conf[\'use_iptc_mapping\']',
+ 'In any case, <strong>show</strong>_iptc_mapping and <strong>use</strong>_iptc_mapping must be totally different.', );
+$lang['Adv_case'][30] = array( /* use_iptc_mapping */
+ 'How to deal with IPTC:',
+ 'Take care of mentionned fields in metadata synchronization.',
+ 'Mentionned fields would be rewrited with IPTC values even those ones are NOT empty.',
+ 'In any case, <strong>show</strong>_iptc_mapping and <strong>use</strong>_iptc_mapping must be totally different.', );
+$lang['Adv_case'][31] = array( /* show_exif */
+ 'Should be true, some information from your camera can be displayed.',
+ 'Think about EXIF information could be different depending on camera models.',
+ 'If you change your camera these fields could be partly different.',
+ 'Many professional photographers choose false, their reasons are to protect their knowledge.' ,
+ 'Do NOT confuse between <strong>show</strong>_exif and <strong>use</strong>_exif (have a look on metadata page on our wiki).', );
+$lang['Adv_case'][32] = array( /* use_exif */
+ 'Documentalists and professionnal photographers would set it true, but beginners should leave the default value.',
+ 'Take care of mentionned fields in metadata synchronization.',
+ 'Mentionned fields would be rewrited with EXIF values even those ones are NOT empty.',
+ 'Do NOT confuse between <strong>show</strong>_exif and <strong>use</strong>_exif (have a look on metadata page on our wiki).', );
+$lang['Adv_case'][33] = array( /* **navigation */
+ 'You can use keyboard arrows to navigate between pictures.', );
+$lang['Adv_case'][34] = array( /* compiled_template_cache_language */
+ 'Should be true, translation will be done at compilation time.',
+ 'If you are modifying a language (translators), you should consider to set it false.',
+ 'Setting it false, template @translate function are called at usage time.' );
+$lang['Adv_case'][35] = array( /* template_compile_check */
+ 'Default is true, template changes are detected and the template is compiled.',
+ 'If you are not updating template any more for several days, ',
+ 'you should consider to set it false.',
+ 'Choosing false, template changes are not detected, this improves response time.',
+ 'Anyway Specials > Maintenance > Purge compiled templates, is recommended after this $conf change.' );
+?>
Index: /tags/2.0.2/plugins/admin_advices/language/es_ES/index.php
===================================================================
--- /tags/2.0.2/plugins/admin_advices/language/es_ES/index.php	(revision 3278)
+++ /tags/2.0.2/plugins/admin_advices/language/es_ES/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/plugins/admin_advices/language/es_ES/plugin.lang.php
===================================================================
--- /tags/2.0.2/plugins/admin_advices/language/es_ES/plugin.lang.php	(revision 3278)
+++ /tags/2.0.2/plugins/admin_advices/language/es_ES/plugin.lang.php	(revision 3278)
@@ -0,0 +1,170 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software, you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY, without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program, if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// --------- Starting below: New or revised $lang ---- from Butterfly (1.8)
+$lang['An_advice_about'] = 'Un nuevo consejo a propósito de';
+$lang['contribute'] = 'Cómo contribuir'; 
+$lang['navigation'] = 'Navegación';
+$lang['Metadata'] = 'Méta-données';
+$lang['current'] =  'Valor actual : %s.';
+$lang['TN-height&width'] = 'Altura y anchura de miniatura debería ser plana.';
+$lang['Adv_case'][0] = array( /* **contribute */
+ 'Si usted desea contribuir con su propia "astucia", gracias por publicarla',
+ 'Sobre los Foros de Piwigo (o por mensaje privado a uno de los desarrolladores),', 
+ 'Y seremos felices de añadirlo desde la publicación siguiente.', );
+$lang['Adv_case'][1] = array( /* newcat_default_status */
+ 'Pruebe $conf[\'newcat_default_status\'] = \'private\';',
+ 'Usted tendrá más tiempo para describir y controlar su imágenes. ',
+ 'Del tiempo para decidirse entre un estatuto privado o público.',
+ 'Si usted escoge quedar privado, usted directamente pasa a la atribución de las autorizaciones. ',
+ 'Sus nuevas categorías serán preparadas más fácilmente.', );
+$lang['Adv_case'][2] = array( /* slideshow_period */
+ 'Este plazo podría ser demasiado corto para las conexiones abajo gasto. ',
+ 'Piense en un valor superior como 4.', );
+$lang['Adv_case'][3] = array( /* file_ext */
+ 'Jamás debería contener extensiones que podrían ser ejecutadas', 
+ 'sobre el servidor como *.php, *.PHP, *.asp, ...', );
+$lang['Adv_case'][4] = array( /* show_iptc_mapping */
+ 'Cómo administrar el IPTC:',
+ ' 1 - Copie una imagen jpg (pública) en ./tools/',
+ ' 2 - Renombre éste sample.jpg.',
+ ' 3 - Lance ./tools/metadata.php',
+ ' 4 - Analice los resultados para determinar cuales campos ',
+ 'Los principiantes dejarán $conf[\'show_iptc\'] = false;',
+ 'Los usuarios avanzados pensarán en los valores del tablero $lang; Incluso al impacto posible sobre los templates.', );
+$lang['Adv_case'][5] = array( /* top_number */
+ 'Este valor podría ser demasiado grande para conexiones baja velocidad.', 
+ 'Piense en un valor situado entre 25-50 con arreglo a lo talla de sus miniaturas.', );
+$lang['Adv_case'][6] = array( /* top_number */
+ '¿ Una única? Por lo menos para las imágenes aleatorias, piense alrededor de 5-10 según en tallas de sus miniaturas.', );
+$lang['Adv_case'][7] = array( /* anti-flood_time */
+ 'Para un tratamiento fluido, su valor es sin duda demasiado grande. Un valor razonable sería 60 (valor por defecto).', );
+$lang['Adv_case'][8] = array( /* calendar_datefield */
+ 'Los valores admitidos son ' . "'date_creation' ou 'date_available'" . ', muy diferente valor puede acabar en los resultados imprevisibles.', );
+$lang['Adv_case'][9] = array( /* calendar_datefield */
+ "' Date_creation ' ". ' no es informado. Ningún campo de los méta-datos (use_) actualiza la base.',
+ 'Seas acelera el uso de los méta-datos <strong>o</strong> cambie para $conf[\'calendar_datefield\'] = \'date_available\'',
+ 'Activate the usage of the méta-data simply by: ',
+ '1 - $conf[\'use_iptc\'] = true; ou $conf[\'use_exif\'] = true; A la elección, los 2 son válidos.',
+ '2 - Respectivamente a cada una hacer el modif:',
+ '$conf[\'use_iptc_mapping\'] = array( ..., \'date_creation\' => \'2#055\', ...',
+ 'y/o:',
+ '$conf[\'use_exif_mapping\'] = array(\'date_creation\' => \'DateTimeOriginal\', ...',
+ '3 - Por fin una nueva mancha le está destinada: la sincronización de los méta-datos.', );
+$lang['Adv_case'][10] = array( /* newcat_default_visible */
+ 'Es un error, un estatuto " private " es más simple, entonces escoja $conf[\'newcat_default_visible\'] = true;', );
+$lang['Adv_case'][11] = array( /* level_separator */
+ 'Usted puede siempre probar otro separador como : $conf[\'level_separator\'] = \'+ \';', );
+$lang['Adv_case'][12] = array( /* paginate_pages_around */
+ 'Los valores acostumbrados se sitúan entre 2 y 5. Para un sitio con una interfaz ligera, escogeramos : ',
+ '$conf[\'paginate_pages_around\'] = 2;',
+ 'Con el fin de proponer más accesos directos, escogeramos: $conf[\'paginate_pages_around\'] = 7;', );
+$lang['Adv_case'][13] = array( /* tn_width */
+ 'Debe ser un valor próximo de la anchura de sus miniaturas. Los valores acostumbrados se sitúan entre 96 y 150, como $conf[\'tn_width\'] = 128;', );
+$lang['Adv_case'][14] = array( /* tn_height */
+ 'Debe ser un valor próximo de la altura de sus miniaturas. Los valores acostumbrados se sitúan entre 96 y 150, como $conf[\'tn_height\'] = 128;', );
+$lang['Adv_case'][15] = array( /* tn_height */
+ 'Anchura y altura de miniatura deberían ser planas.',
+ 'Pruebe $conf[\'tn_height\'] = $conf[\'tn_width\'],',
+ 'o $conf[\'tn_width\'] = $conf[\'tn_height\'],', );
+$lang['Adv_case'][16] = array( /* show_version */
+ 'Por razones de seguridad de su galería, prefiera $conf[\'show_version\'] = false;', );
+$lang['Adv_case'][17] = array( /* show_thumbnail_caption */
+ 'Para una galería menos cargada, haga la prueba de $conf[\'show_thumbnail_caption\'] = false,', );
+$lang['Adv_case'][18] = array( /* show_picture_name_on_title */
+ 'Para una galería menos cargada, haga la prueba de $conf[\'show_picture_name_on_title\'] = false,', );
+$lang['Adv_case'][19] = array( /* tags_default_display_mode */
+ 'Por defecto a \'cloud\' (nube), más un "Tag" es utilizada más será escrito de allí grande.',
+ 'Usted puede cambiar la fijación de "tags", $conf[\'tags_default_display_mode\'] = \'letters\'', );
+$lang['Adv_case'][20] = array( /* allow_random_representative */
+ 'Deje $conf[\'allow_random_representative\'] = true, ',
+ 'Pero estudie cómo usted podría evitarlo por razones de realización.' , );
+$lang['Adv_case'][21] = array( /* prefix_thumbnail */
+ 'Atención, su $conf[\'prefix_thumbnail\']  no es estándar.',
+ 'No cambiar su prefijo excepto si sus miniaturas tienen un problema de fijación.',
+ 'Un sitio distante puede tener un prefijo diferente, le create_listing_file.php deberá ser modificado.',
+ 'Usted debería tener un mensaje de advertencia durante la sincronización en este caso.',
+ 'Trate de guardar el mismo prefijo de miniaturas para los sitios locales o distantes.',
+ 'Conserve este parámetro en vuestro  ./include/config_<strong>local.inc.php</strong>.',
+ 'Ver la página sobre la configuración en Wiki para más informaciones a propósito de ./include/config_<strong>local.inc.php</strong>.', );
+$lang['Adv_case'][22] = array( /* users_page */
+ 'A menos que tener una conexión baja velocidad, usted ampliamente puede aumentar $conf[\'users_page\'] sobre todo si usted tiene más de 20 miembros.', );
+$lang['Adv_case'][23] = array( /* mail_options */
+ 'Debería estar a false, solamente algún webmasters deberán indicar $conf[\'mail_options\'] = true;',
+ 'Un usuario avanzado de nuestro foro les habrá aconsejado en un solo caso de problema de e-mail.', );
+$lang['Adv_case'][24] = array( /* check_upgrade_feed */
+ 'Debería estar a false, sólo los miembros del equipo Piwigo codifican $conf[\'check_upgrade_feed\'] = true; para sus pruebas.', );
+$lang['Adv_case'][25] = array( /* rate_items */
+ 'Su $conf[\'rate_items\'] debería tener 4 o 5 elementos pero no menos.', );
+$lang['Adv_case'][26] = array( /* rate_items */
+ 'Su $conf[\'rate_items\'] debería tener 4 o 5 elementos pero no más.',
+ 'Controle sus imágenes las mejor anotadas antes de retirar ciertos valores.',
+ 'Reducir los valores excesivos y modifique vuestro $conf[\'rate_items\'].', );
+$lang['Adv_case'][27] = array( /* show_iptc */
+ 'Efectivamente puede a ser true, eventualmente escoja $conf[\'show_iptc\'] = false,',
+ 'Así como algunos fotógrafos profesionales escoja false aunque sus razones sean apenas profesionales.',
+ 'No confunda <strong>show</strong>_iptc y <strong>use</strong>_iptc (consulte las páginas con metadatos de nuestro wiki).', );
+$lang['Adv_case'][28] = array( /* use_iptc */
+ 'Los documentalistas y los fotógrafos profesionales preferirán el valor true, pero los principiantes deberían dejar $conf[\'use_iptc\'] = false,',
+ 'Hacer atención en los campos mencionados en la sincronización del metadatos.',
+ 'Los campos indicados podrán ser aplastados por valores de campo IPTC aun cuando estos campos no estarían vacíos.',
+ 'No confunda <strong>show</strong>_iptc et <strong>use</strong>_iptc (consulte las páginas con metadatos de nuestro wiki).', );
+$lang['Adv_case'][29] = array( /* use_iptc */
+ 'Cómo administrar IPTC:',
+ '1 - Copie una imagen jpg (pública) en ./tools/',
+ '2 - Renombre éste sample.jpg.',
+ '3 - Lance ./tools/metadata.php',
+ '4 - Analice los resultados para determinar cual campo IPTC podría completar su base de datos.',
+ 'Los principiantes dejarán $conf[\'use_iptc\'] = false,',
+ 'Los usuarios avanzados harán esfuerzos de documentación antes de trasladar sus imágenes.',
+ 'El campo IPTC debe ser descrito por $conf[\'use_iptc_mapping\']',
+ 'En todos los casos, <strong>show</strong>_iptc_mapping y <strong>use</strong>_iptc_mapping serán totalmente diferentes.', );
+$lang['Adv_case'][30] = array( /* use_iptc_mapping */
+ 'Cómo administrar IPTC:',
+ 'Haga atención en los campos mencionados en la sincronización del metadatos.',
+ 'Los campos indicados podrán ser aplastados por valores de campo IPTC aun cuando estos campos no estarían vacíos.',
+ 'En todos los casos, <strong>show</strong>_iptc_mapping y <strong>use</strong>_iptc_mapping serán totalmente diferentes.', );
+$lang['Adv_case'][31] = array( /* show_exif */
+ 'Debería estar a true, ciertas informaciones limpias de su aparato podrán ser fijadas.',
+ 'Piense en el hecho que las informaciones EXIF pueden ser diferentes según los modelos de aparato.',
+ 'Si usted cambia su aparato estos campos podrían en parte diferentes.',
+ 'Muchos fotógrafos profesionales escogen false, esto con el fin de proteger su destreza.' ,
+ 'No confunda <strong>show</strong>_exif y <strong>use</strong>_exif (Consulte las páginas con metadatos de nuestro wiki).', );
+$lang['Adv_case'][32] = array( /* use_exif */
+ 'Los documentalistas y los fotógrafos profesionales preferirán el valor true, pero los principiantes dejarán el valor por defecto.',
+ 'Ocúpese de campos mencionados en la sincronización del metadatos.',
+ 'Los campos indicados podrán ser aplastados por valores de campos EXIF aun cuando estos campos no estarían vacíos.',
+ 'No confunda <strong>show</strong>_exif y <strong>use</strong>_exif (Consulte las páginas con metadatos de nuestro wiki).', );
+$lang['Adv_case'][33] = array( /* **navigation */
+ 'Usted puede utilizar las flechas del teclado para navegar entre las imágenes.', );
+$lang['Adv_case'][34] = array( /* compiled_template_cache_language */
+ 'Debería estar a true, la traducción será efectuada en el momento de la compilación.',
+ 'Si usted modifica los ficheros lenguas (traductores), usted debería contemplar el valor false.',
+ 'Situado en false, @translate templates serán tratados a cada utilización.' );
+$lang['Adv_case'][35] = array( /* template_compile_check */
+ 'Por defecto en true, toda modificación de template es detectada y el template modificado es recompilado.',
+ 'Si usted no modifica más su templates durante varios días, ',
+ 'Usted debería contemplar el valor false.',
+ 'Escogiendo false, las modificaciones de template no son detectadas más, esto mejora tiempo de respuesta.',
+ 'En todos los casos Especiales > Mantenimiento > Purgar el templates compilado, es recomendado después de una modificación de este $conf.' );
+?>
Index: /tags/2.0.2/plugins/admin_advices/language/fr_FR/index.php
===================================================================
--- /tags/2.0.2/plugins/admin_advices/language/fr_FR/index.php	(revision 3278)
+++ /tags/2.0.2/plugins/admin_advices/language/fr_FR/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/plugins/admin_advices/language/fr_FR/plugin.lang.php
===================================================================
--- /tags/2.0.2/plugins/admin_advices/language/fr_FR/plugin.lang.php	(revision 3278)
+++ /tags/2.0.2/plugins/admin_advices/language/fr_FR/plugin.lang.php	(revision 3278)
@@ -0,0 +1,170 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software, you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY, without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program, if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// --------- Starting below: New or revised $lang ---- from Butterfly (1.8)
+$lang['An_advice_about'] = 'Un nouveau conseil à propos de ';
+$lang['contribute'] = 'comment contribuer'; 
+$lang['navigation'] = 'navigation';
+$lang['Metadata'] = 'Méta-données';
+$lang['current'] =  'Valeur actuelle : %s.';
+$lang['TN-height&width'] = 'Hauteur et largeur de miniature devrait être égales.';
+$lang['Adv_case'][0] = array( /* **contribute */
+ 'Si vous souhaitez contribuer avec votre propre «astuce», merci de la publier',
+ 'sur les Forums de Piwigo (ou par message privé à l\'un des développeurs),', 
+ 'et nous serons heureux de l\'ajouter dès la publication suivante.', );
+$lang['Adv_case'][1] = array( /* newcat_default_status */
+ 'Essayez $conf[\'newcat_default_status\'] = \'private\';',
+ 'Vous aurez plus de temps pour décrire et contrôler vos images. ',
+ 'Du temps pour vous décider entre un statut privé ou public.',
+ 'Si vous choisissez de rester privé, vous passerez directement à l\'attribution des autorisations. ',
+ 'Vos nouvelles catégories seront préparées plus facilement.', );
+$lang['Adv_case'][2] = array( /* slideshow_period */
+ 'Ce délai pourrait être trop court pour les connexions en bas débit. ',
+ 'Pensez à une valeur supérieure comme 4.', );
+$lang['Adv_case'][3] = array( /* file_ext */
+ 'Ne devrait jamais contenir des extensions pouvant être exécutées', 
+ 'sur le serveur comme *.php, *.PHP, *.asp, ...', );
+$lang['Adv_case'][4] = array( /* show_iptc_mapping */
+ 'Comment gérer les IPTC:',
+ ' 1 - Copiez une image jpg (publique) dans ./tools/',
+ ' 2 - Renommez celle-ci en sample.jpg.',
+ ' 3 - Lancez ./tools/metadata.php',
+ ' 4 - Analysez les résultats pour déterminer quels champs ',
+ 'Les débutants laisseront $conf[\'show_iptc\'] = false;',
+ 'Les utilisateurs avancés penseront aux valeurs du tableau $lang; voire même à l\'impact possible sur les templates.', );
+$lang['Adv_case'][5] = array( /* top_number */
+ 'Cette valeur pourrait être trop grande pour des connexions bas débit.', 
+ 'Pensez à une valeur située entre 25-50 en fonction de la taille de vos miniatures.', );
+$lang['Adv_case'][6] = array( /* top_number */
+ 'Une seule? Au moins pour les images aléatoires, pensez autour de 5-10 selon la tailles de vos miniatures.', );
+$lang['Adv_case'][7] = array( /* anti-flood_time */
+ 'Pour un traitement fluide, votre valeur est sans doute trop grande. Une valeur raisonnable serait 60 (valeur par défaut).', );
+$lang['Adv_case'][8] = array( /* calendar_datefield */
+ 'Les valeurs admises sont ' . "'date_creation' ou 'date_available'" . ', toute autre valeur peut aboutir à des résultats imprévisibles.', );
+ $lang['Adv_case'][9] = array( /* calendar_datefield */
+ "La 'date_creation'" . ' n\'est pas renseignée. Aucun champ des méta-données (use_) n\'actualise la base.',
+ 'Soit vous activez l\'usage des méta-données <strong>ou</strong> changez pour $conf[\'calendar_datefield\'] = \'date_available\'',
+ 'Activez l\'usage des méta-données simplement par: ',
+ '1 - $conf[\'use_iptc\'] = true; ou $conf[\'use_exif\'] = true; au choix, les 2 sont valables.',
+ '2 - Respectivement à chacune faire la modif:',
+ '$conf[\'use_iptc_mapping\'] = array( ..., \'date_creation\' => \'2#055\', ...',
+ 'et/ou:',
+ '$conf[\'use_exif_mapping\'] = array(\'date_creation\' => \'DateTimeOriginal\', ...',
+ '3 - Enfin une nouvelle tache vous est destinée: la synchronisation des méta-données.', );
+$lang['Adv_case'][10] = array( /* newcat_default_visible */
+ 'C\'est une erreur, un statut "private" est plus simple, alors choisissez $conf[\'newcat_default_visible\'] = true;', );
+$lang['Adv_case'][11] = array( /* level_separator */
+ 'Vous pouvez toujours essayer un autre séparateur comme : $conf[\'level_separator\'] = \'+ \';', );
+$lang['Adv_case'][12] = array( /* paginate_pages_around */
+ 'Les valeurs habituelles se situent entre 2 et 5. Pour un site avec une interface légère, on choisira : ',
+ '$conf[\'paginate_pages_around\'] = 2;',
+ 'Afin de proposer plus d\'accès directs, on choisira : $conf[\'paginate_pages_around\'] = 7;', );
+$lang['Adv_case'][13] = array( /* tn_width */
+ 'Doit être une valeur proche de la largeur de vos miniatures. Les valeurs habituelles se situent entre 96 et 150, comme $conf[\'tn_width\'] = 128;', );
+$lang['Adv_case'][14] = array( /* tn_height */
+ 'Doit être une valeur proche de la hauteur de vos miniatures. Les valeurs habituelles se situent entre 96 et 150, comme $conf[\'tn_height\'] = 128;', );
+$lang['Adv_case'][15] = array( /* tn_height */
+ 'Largeur et hauteur de miniature devraient être égales.',
+ 'Essayez $conf[\'tn_height\'] = $conf[\'tn_width\'],',
+ 'ou $conf[\'tn_width\'] = $conf[\'tn_height\'],', );
+$lang['Adv_case'][16] = array( /* show_version */
+ 'Pour des raisons de sécurité de votre galerie, préférez $conf[\'show_version\'] = false;', );
+$lang['Adv_case'][17] = array( /* show_thumbnail_caption */
+ 'Pour une galerie moins chargée, faites le test de $conf[\'show_thumbnail_caption\'] = false,', );
+$lang['Adv_case'][18] = array( /* show_picture_name_on_title */
+ 'Pour une galerie moins chargée, faites le test de $conf[\'show_picture_name_on_title\'] = false,', );
+$lang['Adv_case'][19] = array( /* tags_default_display_mode */
+ 'Par défaut à \'cloud\' (nuage), plus un "tag" est utilisé plus il sera écrit en grand.',
+ 'Vous pouvez changer l\'affichage des "tags", $conf[\'tags_default_display_mode\'] = \'letters\'', );
+$lang['Adv_case'][20] = array( /* allow_random_representative */
+ 'Laissez $conf[\'allow_random_representative\'] = true, ',
+ 'mais étudiez comment vous pourriez l\'éviter pour des raisons de performance.' , );
+$lang['Adv_case'][21] = array( /* prefix_thumbnail */
+ 'Attention, votre $conf[\'prefix_thumbnail\']  n\'est pas standard.',
+ 'Ne pas changer votre préfixe sauf si vos miniatures ont un problème d\'affichage.',
+ 'Un site distant peut avoir un préfixe différent, le create_listing_file.php devra être modifié.',
+ 'Vous devriez avoir un message d\'avertissement pendant la synchronisation dans ce cas.',
+ 'Essayez de garder le même préfixe de miniatures pour les sites locaux ou distants.',
+ 'Conservez ce paramètre dans votre ./include/config_<strong>local.inc.php</strong>.',
+ 'Voir la page sur la configuration dans le Wiki pour plus d\'informations à propos de ./include/config_<strong>local.inc.php</strong>.', );
+$lang['Adv_case'][22] = array( /* users_page */
+ 'A moins d\'avoir une connexion bas débit, vous pouvez augmenter largement $conf[\'users_page\'] surtout si vous avez plus de 20 membres.', );
+$lang['Adv_case'][23] = array( /* mail_options */
+ 'Devrait être à false, seulement quelques webmasters devront indiquer $conf[\'mail_options\'] = true;',
+ 'Un utilisateur avancé de notre forum les aura conseillé dans un seul cas de problème d\'email.', );
+$lang['Adv_case'][24] = array( /* check_upgrade_feed */
+ 'Devrait être à false, seuls les membres de l\'équipe Piwigo codent $conf[\'check_upgrade_feed\'] = true; pour leurs tests.', );
+$lang['Adv_case'][25] = array( /* rate_items */
+ 'Votre $conf[\'rate_items\'] devrait avoir 4 ou 5 éléments mais pas moins.', );
+$lang['Adv_case'][26] = array( /* rate_items */
+ 'Votre $conf[\'rate_items\'] devrait avoir 4 ou 5 éléments mais pas plus.',
+ 'Contrôlez vos images les mieux notées avant de retirer certaines valeurs.',
+ 'Réduire les valeurs excessives et modifiez votre $conf[\'rate_items\'].', );
+$lang['Adv_case'][27] = array( /* show_iptc */
+ 'Peut être effectivement à true, éventuellement choisissez $conf[\'show_iptc\'] = false,',
+ 'Comme quelques photographes professionnels choisissez false bien que leurs raisons ne soient guère professionnelles.',
+ 'Ne confondez pas <strong>show</strong>_iptc et <strong>use</strong>_iptc (consultez les pages sur les métadonnées de notre wiki).', );
+$lang['Adv_case'][28] = array( /* use_iptc */
+ 'Les documentalistes et photographes professionnels préfèreront la valeur true, mais les débutants devraient laisser $conf[\'use_iptc\'] = false,',
+ 'Faire attention aux champs mentionnés dans la synchronisation des métadonnées.',
+ 'Les champs indiqués pourront être écrasés par des valeurs de champs IPTC quand bien même ces champs ne seraient pas vides.',
+ 'Ne confondez pas <strong>show</strong>_iptc et <strong>use</strong>_iptc (consultez les pages sur les métadonnées de notre wiki).', );
+$lang['Adv_case'][29] = array( /* use_iptc */
+ 'Comment gérer les IPTC:',
+ '1 - Copiez une image jpg (publique) dans ./tools/',
+ '2 - Renommez celle-ci en sample.jpg.',
+ '3 - Lancez ./tools/metadata.php',
+ '4 - Analysez les résultats pour déterminer quels champs IPTC pourraient compléter votre base de données.',
+ 'Les débutants laisseront $conf[\'use_iptc\'] = false,',
+ 'Les utilisateurs avancés feront des efforts de documentation avant de transférer leurs images.',
+ 'Les champs IPTC doivent être décrits par $conf[\'use_iptc_mapping\']',
+ 'Dans tous les cas, <strong>show</strong>_iptc_mapping et <strong>use</strong>_iptc_mapping seront totalement différents.', );
+$lang['Adv_case'][30] = array( /* use_iptc_mapping */
+ 'Comment gérer les IPTC:',
+ 'Faites attention aux champs mentionnés dans la synchronisation des métadonnées.',
+ 'Les champs indiqués pourront être écrasés par des valeurs de champs IPTC quand bien même ces champs ne seraient pas vides.',
+ 'Dans tous les cas, <strong>show</strong>_iptc_mapping et <strong>use</strong>_iptc_mapping seront totalement différents.', );
+$lang['Adv_case'][31] = array( /* show_exif */
+ 'Devrait être à true, certaines informations propres à votre appareil pourront être affichées.',
+ 'Pensez au fait que les informations EXIF peuvent être différentes suivant les modèles d\'appareil.',
+ 'Si vous changez votre appareil ces champs pourraient en partie différents.',
+ 'Beaucoup de photographes professionnels choisissent false, ceci afin de protéger leur savoir-faire.' ,
+ 'Ne confondez pas <strong>show</strong>_exif et <strong>use</strong>_exif (consultez les pages sur les métadonnées de notre wiki).', );
+$lang['Adv_case'][32] = array( /* use_exif */
+ 'Les documentalistes et photographes professionnels préfèreront la valeur true, mais les débutants laisseront la valeur par défaut.',
+ 'Occupez-vous des champs mentionnés dans la synchronisation des métadonnées.',
+ 'Les champs indiqués pourront être écrasés par des valeurs de champs EXIF quand bien même ces champs ne seraient pas vides.',
+ 'Ne confondez pas <strong>show</strong>_exif et <strong>use</strong>_exif (consultez les pages sur les métadonnées de notre wiki).', );
+$lang['Adv_case'][33] = array( /* **navigation */
+ 'Vous pouvez utiliser les flèches du clavier pour naviguer entre les images.', );
+$lang['Adv_case'][34] = array( /* compiled_template_cache_language */
+ 'Devrait être à true, la traduction sera effectuée au moment de la compilation.',
+ 'Si vous modifiez les fichiers langues (traducteurs), vous devriez envisager la valeur false.',
+ 'Positionné à false, les @translate des templates seront traités à chaque utilisation.' );
+$lang['Adv_case'][35] = array( /* template_compile_check */
+ 'Par défaut à true, toute modification de template est détectée et le template modifié est recompilé.',
+ 'Si vous ne modifiez plus vos templates pendant plusieurs jours, ',
+ 'vous devriez envisager la valeur false.',
+ 'En choisissant false, les modifications de template ne sont plus détectées, ceci améliore les temps de réponse.',
+ 'Dans tous les cas Spéciales > Maintenance > Purger les templates compilés, est recommandé après une modification de cette $conf.' );
+?>
Index: /tags/2.0.2/plugins/admin_advices/language/index.php
===================================================================
--- /tags/2.0.2/plugins/admin_advices/language/index.php	(revision 3278)
+++ /tags/2.0.2/plugins/admin_advices/language/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/plugins/admin_advices/language/it_IT/index.php
===================================================================
--- /tags/2.0.2/plugins/admin_advices/language/it_IT/index.php	(revision 3278)
+++ /tags/2.0.2/plugins/admin_advices/language/it_IT/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/plugins/admin_advices/language/it_IT/plugin.lang.php
===================================================================
--- /tags/2.0.2/plugins/admin_advices/language/it_IT/plugin.lang.php	(revision 3278)
+++ /tags/2.0.2/plugins/admin_advices/language/it_IT/plugin.lang.php	(revision 3278)
@@ -0,0 +1,170 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software, you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY, without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program, if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// --------- Starting below: New or revised $lang ---- from Butterfly (1.8)
+$lang['An_advice_about'] = 'Un\'nuovo consiglio about';
+$lang['contribute'] = 'come contribuire'; 
+$lang['navigation'] = 'navigazione';
+$lang['Metadata'] = 'Meta-dati';
+$lang['current'] =  'Valore attuale : %s.';
+$lang['TN-height&width'] = 'Altezza e lunghezza delle miniature dovrebbero essere uguali.';
+$lang['Adv_case'][0] = array( /* **contribute */
+ 'Se volete contribuire con i vostri propri "trucchi", pubblicateli pure',
+ 'sul forum di Piwigo (o inviateli per posta agli sviluppatori),',
+ 'e saremmo felici d\'aggiungerli nella la prossima versione.',);
+$lang['Adv_case'][1] = array( /* newcat_default_status */
+ 'Trovate $conf[\'newcat_default_status\'] = \'private\',',
+ 'Avrete più tempo per descrivere e controllare le vostre immagini.',
+ 'Del tempo per decidere tra lo stato privato e pubblico. ',
+ 'Se scegliete di rimanere "privato", passerete direttamente all\'attribuzione delle autorizzazioni.',
+ 'Le vostre nuove categorie saranno pronte più facilmente.', );
+$lang['Adv_case'][2] = array( /* slideshow_period */
+ 'Questo valore potrebbe essere troppo piccolo per le connessioni a bassa velocità.',
+ 'Pesate ad un valore più alto come 4.', );
+$lang['Adv_case'][3] = array( /* file_ext */
+ 'Non dovrebbe mai contiene delle estensioni che possono essere eseguite',
+ 'sul server come *.php, *.PHP, *.asp, ...', );
+$lang['Adv_case'][4] = array( /* show_iptc_mapping */
+ 'Come gestire i IPTC :',
+ ' 1 - Copiate un\'immagine jpg (pubblica) in ./tools/',
+ ' 2 - Rinominatela in sample.jpg.',
+ ' 3 - Eseguite ./tools/metadata.php',
+ ' 4 - Analizzate il risultato per identificare quali campi ',
+ 'I principianti lasceranno $conf[\'show_iptc\'] = false,',
+ 'Gli utenti più sperimentati si occuperanno dei valori della tabella $lang e degli impatti sui templates.', );
+$lang['Adv_case'][5] = array( /* top_number */
+ 'Questo valore è forse troppo alto per i collegamenti a bassa velocità.',
+ 'Pensate ad un valore tra 25-50 in funzione della taglia delle miniature.', );
+$lang['Adv_case'][6] = array( /* top_number */
+ 'Una sola? Almeno per le "immagini a caso", pensate ad un valore tra 5-10 circa in funzione della taglia delle miniature.',  );
+$lang['Adv_case'][7] = array( /* anti-flood_time */
+ 'Per uno scorrimento normale, il vostro valore è probabilmente troppo alto. Un buon\' valore sarebbe 60 (valore predefinito).', );
+$lang['Adv_case'][8] = array( /* calendar_datefield */
+ 'I valori autorizzati sono ' . "'date_creation' o 'date_available'" . ', tutt\'altro valore può dare risultato inaspettato.' , );
+$lang['Adv_case'][9] = array( /* calendar_datefield */
+ "'date_creation'" . ' é vuoto. Nessun campo dei metadati (use_) n\'attualizza la base.',
+ 'O attivate l\'uso dei metatati activate <strong>o</strong> cambiate a $conf[\'calendar_datefield\'] = \'date_available\'',
+ 'Attivate l\'uso dei metadati semplicemente con :',
+ '1 - $conf[\'use_iptc\'] = true, o $conf[\'use_exif\'] = true; le due sonuzioni possono essere usate.',
+ '2 - Respettivamente eseguire le modifiche:',
+ '$conf[\'use_iptc_mapping\'] = array( ..., \'date_creation\' => \'2#055\', ...',
+ 'o/e:',
+ '$conf[\'use_exif_mapping\'] = array(\'date_creation\' => \'DateTimeOriginal\', ...',
+ '3 - In fine una nuova operazione é da eseguire : la sincronizzazione dei metadati synchronization.', );
+$lang['Adv_case'][10] = array( /* newcat_default_visible */
+ 'E un errore, lo stato "private" é più semplice, allora scegliete $conf[\'newcat_default_visible\'] = true,', );
+$lang['Adv_case'][11] = array( /* level_separator */
+ 'Potete sempre provare un altro separatore come : $conf[\'level_separator\'] = \'+ \',',  );
+$lang['Adv_case'][12] = array( /* paginate_pages_around */
+ 'I valore di default si trovano tra 2 e 5. Per un sito con un interfacia "leggera" scegliere : ',
+ '$conf[\'paginate_pages_around\'] = 2;',
+ 'Al fine d\'offrire più accessi diretti, scegliere : $conf[\'paginate_pages_around\'] = 7,', );
+$lang['Adv_case'][13] = array( /* tn_width */
+ 'Deve essere un valore vicino alla larghezza delle vostre miniature. I valori di default sono tra 96 e 150, come $conf[\'tn_width\'] = 128,', );
+$lang['Adv_case'][14] = array( /* tn_height */
+ 'Deve essere un valore vicino al altezza delle vostre miniature. I valori di default sono tra 96 e 150, come $conf[\'tn_height\'] = 128,', );
+$lang['Adv_case'][15] = array( /* tn_height */
+ 'L\'altezza e la lunghezza delle miniature dovrebbero essere uguali.',
+ 'Provate $conf[\'tn_height\'] = $conf[\'tn_width\'],',
+ 'o $conf[\'tn_width\'] = $conf[\'tn_height\'],', );
+$lang['Adv_case'][16] = array( /* show_version */
+ 'Per raggioni di sicurezza scegliete piuttosto $conf[\'show_version\'] = false,', );
+$lang['Adv_case'][17] = array( /* show_thumbnail_caption */
+ 'Per una galleria meno "carica", provate con $conf[\'show_thumbnail_caption\'] = false,', );
+$lang['Adv_case'][18] = array( /* show_picture_name_on_title */
+ 'Per una galleria meno "carica", provate con $conf[\'show_picture_name_on_title\'] = false,', );
+$lang['Adv_case'][19] = array( /* tags_default_display_mode */
+ 'Di default impostato a \'cloud\' (nuvola), più un "tag" è utilizzato più sarà scritto in grande.',
+ 'Potete modificare la visualizzazione dei tags, $conf[\'tags_default_display_mode\'] = \'letters\'', );
+$lang['Adv_case'][20] = array( /* allow_random_representative */
+ 'Lasciate pure $conf[\'allow_random_representative\'] = true, ',
+ 'ma provate a vedere come evitarlo per raggioni di performance.' , );
+$lang['Adv_case'][21] = array( /* prefix_thumbnail */
+ 'Attenzione, il vostro $conf[\'prefix_thumbnail\'] non è di default.',
+ 'Non dovete cambiarlo eccetto se le vostre miniature non sono visibili',
+ 'Il sito distante potrebbe usare un prefisso diverso, il create_listing_file.php dovrà essere modificato',
+ 'In questo caso, dovreste avere un messaggio d\'avvertimento durante la sincronizzazione',
+ 'Provate a mantenere lo stesso prefisso per tutti i siti sia locali che distanti',
+ 'Tenere questo parametro nel vostro ./include/config_<strong>locale.inc.php</strong>',
+ 'Vedere la pagina di configurazione nel WIKI per maggiore informazioni su ./include/config_<strong>locale.inc.php</strong>. ',);
+$lang['Adv_case'][22] = array( /* users_page */
+ 'Se avete una conessione a banda larga potete aumentare $conf[\'users_page\'] sopra tutto se avete più di 20 utenti registrati.', );
+$lang['Adv_case'][23] = array( /* mail_options */
+ 'Dovrebbe essere a "false", solo qualche webmaster dovranno impostare $conf[\'mail_options\'] = true, ',
+ 'Un utente esperto del nostro forum ha consigliato questo valore per coloro che hanno avuto problemi con l\'Email.', );
+$lang['Adv_case'][24] = array( /* check_upgrade_feed */
+ 'Dovrebbe essere a "false". Solo i sviluppatori della Team di PWG impostono $conf[\'check_upgrade_feed\'] = true, per i loro test.' , );
+$lang['Adv_case'][25] = array( /* rate_items */
+ 'Il vostro $conf[\'rate_items\'] dovrebbe avere 4 o 5 elementi ma non meno.', );
+$lang['Adv_case'][26] = array( /* rate_items */
+ 'Il vostro $conf[\'rate_items\'] dovrebbe avere 4 o 5 elementi ma non di più.',
+ 'Verificate le foto le più votate prima di togliere certi valori.',
+ 'Ridurre certi valori eccessivi e modificate il vostro $conf[\'rate_items\'].', );
+$lang['Adv_case'][27] = array( /* show_iptc */
+ 'Puo essere a "true", scegliete piuttosto $conf[\'show_iptc\'] = false,',
+ 'Come certi fotografi professioali scegliete false anche se le loro raggioni non sono per forsa professionali.' ,
+ 'Non confondere <strong>show</strong>_iptc e <strong>use</strong>_iptc (consultate le pagine sui metadati nel WIKI).', );
+$lang['Adv_case'][28] = array( /* use_iptc */
+ 'I documentaristi e fotografi professionnali lo regolerebbero a "true", ma i principianti dovrebbero lasciarlo a $conf[\'use_iptc\'] = false,',
+ 'Attenti ai campi mensionati durante la sincronizzazione dei metadati.',
+ 'I campi menzionati potrebbero essere sovrascritti con i valori dei campi IPTC anche se non sono vuoti',
+ 'Non confondere <strong>show</strong>_iptc e <strong>use</strong>_iptc (consultate le pagine sui metadati nel WIKI).', );
+$lang['Adv_case'][29] = array( /* use_iptc */
+ 'Come gestire i IPTC:',
+ '1 - Copiate un\'immagine jpg (pubblica) in ./tools/',
+ '2 - Rinominatela in sample.jpg.',
+ '3 - Eseguite ./tools/metadata.php',
+ '4 - Analizzate il risultato per identificare quali campi IPTC potrebbero completale la vostra base dati',
+ 'I principianti lasceranno $conf[\'show_iptc\'] = false,',
+ 'Gli utenti più sperimentati documenteranno le loro foto prima di trasferirle sul sito.',
+ 'I campi IPTC devono essere elencati in $conf[\'use_iptc_mapping\']',
+ 'In tutti i casi, <strong>show</strong>_iptc_mapping e <strong>use</strong>_iptc_mapping saranno totalmente diversi.', );
+$lang['Adv_case'][30] = array( /* use_iptc_mapping */
+ 'Come gestire i IPTC:',
+ 'Attenti ai campi mensionati durante la sincronizzazione dei metadati.',
+ 'I campi menzionati potrebbero essere sovrascritti con i valori dei campi IPTC anche se non sono vuoti',
+ 'In tutti i casi, <strong>show</strong>_iptc_mapping e <strong>use</strong>_iptc_mapping saranno totalmente diversi.', );
+$lang['Adv_case'][31] = array( /* show_exif */
+ 'Dovrebbe essere a "true", certe informazioni della vostra macchina fotografica potrebbero essere visualizzate.',
+ 'Le informazioni EXIF possono essere diverse a seconda del modello della macchina fotografica.',
+ 'Se cambiate macchina fotografica, le informazioni visualizzate potrebbero cambiare.',
+ 'Parecchi fotografi professionali sceglieranno "false", per proteggere il loro lavoro.' ,
+ 'Non confondere <strong>show</strong>_iptc e <strong>use</strong>_iptc (consultate le pagine sui metadati nel WIKI).', );
+$lang['Adv_case'][32] = array( /* use_exif */
+ 'I documentaristi e fotografi professionnali lo regolerebbero a "true", ma i principianti dovrebbero lasciare il valore di default.',
+ 'Take care of mentionned fields in metadata synchronization.',
+ 'I campi menzionati potrebbero essere sovrascritti con i valori dei campi EXIF anche se non sono vuoti',
+ 'Non confondere <strong>show</strong>_exif e <strong>use</strong>_exif (consultate le pagine sui metadati nel WIKI).', );
+$lang['Adv_case'][33] = array( /* **navigation */
+ 'Potrete usare le frecce della tastiera per navigare tra le foto.', );
+$lang['Adv_case'][34] = array( /* compiled_template_cache_language */
+ 'Doverbbe essere a "true", la traduzione sarà eseguta al momento della compilazione.',
+ 'Se modificate i files lingua (traduzioni), dovreste impostare il parametro a "false".',
+ 'Impostato a "false", i "@translate" dei templates saranno trattati ad ogni uso.' );
+$lang['Adv_case'][35] = array( /* template_compile_check */
+ 'Di default a "true", ogni modifica sui templates è rilevata e il template modificato è compilato.',
+ 'Se non modificate i vostri templates per qualche giorno, ',
+ 'dovreste penasre ad impostarlo a "false".',
+ 'Scelgliendo "false", le modifiche dei templates non saranno più rilevate, ciò amegliora i tempi di risposta.',
+ 'Comunque Speciale > Manutezione > Spurgare i templates compilati, è consigliato dopo una modifica di $conf.' );
+?>
Index: /tags/2.0.2/plugins/admin_advices/main.inc.php
===================================================================
--- /tags/2.0.2/plugins/admin_advices/main.inc.php	(revision 3278)
+++ /tags/2.0.2/plugins/admin_advices/main.inc.php	(revision 3278)
@@ -0,0 +1,36 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 Piwigo team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+/*
+Plugin Name: Admin Advices
+Version: 2.0.2
+Description: Give you an advice on the administration page.
+Plugin URI: http://piwigo.org/ext/extension_view.php?eid=285
+Author: Piwigo team
+Author URI: http://piwigo.org
+*/
+if (!defined('PHPWG_ROOT_PATH')) die('Hacking attempt!');
+
+if (script_basename() == 'admin' and defined('IN_ADMIN') and IN_ADMIN)
+  include_once(dirname(__FILE__).'/admin_advices.php');
+?>
Index: /tags/2.0.2/plugins/admin_multi_view/controller.php
===================================================================
--- /tags/2.0.2/plugins/admin_multi_view/controller.php	(revision 3278)
+++ /tags/2.0.2/plugins/admin_multi_view/controller.php	(revision 3278)
@@ -0,0 +1,224 @@
+<?php
+define('MULTIVIEW_CONTROLLER', 1);
+define('PHPWG_ROOT_PATH','../../');
+include_once( PHPWG_ROOT_PATH.'include/common.inc.php' );
+
+if (!is_admin() or !function_exists('multiview_user_init') )
+{
+  pwg_unset_session_var( 'multiview_as' );
+  pwg_unset_session_var( 'multiview_theme' );
+  pwg_unset_session_var( 'multiview_lang' );
+  pwg_unset_session_var( 'multiview_show_queries' );
+  pwg_unset_session_var( 'multiview_debug_l10n' );
+  pwg_unset_session_var( 'multiview_debug_template' );
+?>
+
+<script type="text/javascript">
+  window.close();
+</script>
+<?php
+  exit();
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+"http://www.w3.org/TR/html4/strict.dtd">
+<?php
+
+$refresh_main = false;
+
+if ( isset($_GET['view_as']) )
+{
+  if ( is_adviser() and $user['id']!=$_GET['view_as'] and $conf['guest_id']!=$_GET['view_as'])
+    die('security error');
+  if ($user['id']===$_GET['view_as'])
+    pwg_unset_session_var( 'multiview_as' );
+  else
+    pwg_set_session_var( 'multiview_as', (int)$_GET['view_as'] );
+  // user change resets theme/lang
+  pwg_unset_session_var( 'multiview_theme' );
+  pwg_unset_session_var( 'multiview_lang' );
+  $refresh_main = true;
+}
+if (pwg_get_session_var( 'multiview_as', $user['id']) != $user['id'] )
+  $view_as_user = build_user( pwg_get_session_var( 'multiview_as',0), false);
+else
+  $view_as_user = $user;
+
+if ( isset($_GET['theme']) )
+{
+  pwg_set_session_var( 'multiview_theme', $_GET['theme'] );
+  $refresh_main = true;
+}
+
+if ( isset($_GET['lang']) )
+{
+  pwg_set_session_var( 'multiview_lang', $_GET['lang'] );
+  $refresh_main = true;
+}
+
+if ( isset($_GET['show_queries']) )
+{
+  if ( $_GET['show_queries']> 0 )
+    pwg_set_session_var( 'multiview_show_queries', 1 );
+  else
+    pwg_unset_session_var( 'multiview_show_queries' );
+  $refresh_main = true;
+}
+
+if ( isset($_GET['debug_l10n']) )
+{
+  if ( $_GET['debug_l10n']>0 )
+    pwg_set_session_var( 'multiview_debug_l10n', 1 );
+  else
+    pwg_unset_session_var( 'multiview_debug_l10n' );
+  $refresh_main = true;
+}
+
+
+if ( isset($_GET['debug_template']) )
+{
+  if ( $_GET['debug_template']>0 )
+    pwg_set_session_var( 'multiview_debug_template', 1 );
+  else
+    pwg_unset_session_var( 'multiview_debug_template' );
+  $refresh_main = true;
+}
+
+$my_url = get_root_url().'plugins/'.basename(dirname(__FILE__)).'/'.basename(__FILE__);
+
+// +-----------------------------------------------------------------------+
+// | users                                                                 |
+$query = '
+SELECT '.$conf['user_fields']['id'].' AS id,'.$conf['user_fields']['username'].' AS username
+FROM '.USERS_TABLE;
+if (is_adviser())
+{
+  $query .='
+  WHERE '.$conf['user_fields']['id']. ' IN ('.$user['id'].','.$conf['guest_id'].')
+';
+}
+$query .='
+  ORDER BY CONVERT('.$conf['user_fields']['username'].',CHAR)
+;';
+$user_map = simple_hash_from_query($query, 'id', 'username');
+
+$users_html = '<select onchange="document.location = this.options[this.selectedIndex].value;">';
+foreach( $user_map as $id=>$username)
+{
+  $selected = ($id==$view_as_user['id']) ? 'selected="selected"' : '';
+  $users_html .=
+    '<option value="'
+    .$my_url.'?view_as='.$id
+    .'" '.$selected.'>'
+    .$username
+    .'</option>';
+}
+$users_html.= '</select>';
+
+
+// +-----------------------------------------------------------------------+
+// | templates                                                             |
+$my_template = '';
+$themes_html='<select onchange="document.location = this.options[this.selectedIndex].value;">';
+foreach (get_pwg_themes() as $pwg_template)
+{
+  $selected = $pwg_template == pwg_get_session_var( 'multiview_theme', $view_as_user['template'].'/'.$view_as_user['theme'] ) ? 'selected="selected"' : '';
+  $my_template = $selected == '' ? $my_template : $view_as_user['template'].'/theme/'.$view_as_user['theme'];
+  $themes_html .=
+    '<option value="'
+    .$my_url.'?theme='.$pwg_template
+    .'" '.$selected.'>'
+    .$pwg_template
+    .'</option>';
+}
+$themes_html .= '</select>';
+
+// +-----------------------------------------------------------------------+
+// | language                                                              |
+$lang_html='<select onchange="document.location = this.options[this.selectedIndex].value;">';
+foreach (get_languages() as $language_code => $language_name)
+{
+  $selected = $language_code == pwg_get_session_var( 'multiview_lang', $view_as_user['language'] ) ? 'selected="selected"' : '';
+  $lang_html .=
+    '<option value="'
+    .$my_url.'?lang='.$language_code
+    .'" '.$selected.'>'
+    .$language_name
+    .'</option>';
+}
+$lang_html .= '</select>';
+
+// +-----------------------------------------------------------------------+
+// | show queries                                                          |
+$show_queries_html='';
+if (!$conf['show_queries'])
+{
+  if ( !pwg_get_session_var( 'multiview_show_queries', 0 ) )
+    $show_queries_html.='<a href="'.$my_url.'?show_queries=1">Show SQL queries</a>';
+  else
+    $show_queries_html.='<a href="'.$my_url.'?show_queries=0">Hide SQL queries</a>';
+}
+
+// +-----------------------------------------------------------------------+
+// | debug language                                                        |
+$debug_l10n_html='';
+if (!$conf['debug_l10n'])
+{
+  if ( !pwg_get_session_var( 'multiview_debug_l10n', 0 ) )
+    $debug_l10n_html.='<a href="'.$my_url.'?debug_l10n=1">Debug language</a>';
+  else
+    $debug_l10n_html.='<a href="'.$my_url.'?debug_l10n=0">Revert debug language</a>';
+}
+
+// +-----------------------------------------------------------------------+
+// | debug template                                                        |
+$debug_template_html='';
+if (!$conf['debug_template'])
+{
+  if ( !pwg_get_session_var( 'multiview_debug_template', 0 ) )
+    $debug_template_html.='<a href="'.$my_url.'?debug_template=1">Debug template</a>';
+  else
+    $debug_template_html.='<a href="'.$my_url.'?debug_template=0">Revert debug template</a>';
+}
+
+?>
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=<?php echo get_pwg_charset() ?>">
+<title>Controller</title>
+<?php
+// Controller will be displayed  with  the **real admin template** (without Any if it has been removed)
+if ( $my_template !== '') {
+  $my_template = get_root_url().'template/'.$my_template.'/theme.css';
+  echo '<link rel="stylesheet" type="text/css" href="' . $my_template .'">';
+}
+?>
+
+</head>
+<body>
+<div>
+<script type="text/javascript">
+if (window.opener==null) {
+  window.close();
+  document.write("<"+"h2>How did you get here ???<"+"/h2>");
+}
+</script>
+
+<table>
+<tr><td>User</td><td><?php echo $users_html; ?></td></tr>
+
+<tr><td>Theme</td><td><?php echo $themes_html; ?></td></tr>
+
+<tr><td>Lang</td><td><?php echo $lang_html; ?></td></tr>
+</table>
+<?php echo implode( "<br/>\n", array($show_queries_html, $debug_l10n_html, $debug_template_html) ); ?>
+
+<script type="text/javascript">
+<?php
+  if ($refresh_main) echo '
+window.opener.location = window.opener.location;';
+?>
+</script>
+</div>
+</body>
+</html>
Index: /tags/2.0.2/plugins/admin_multi_view/index.php
===================================================================
--- /tags/2.0.2/plugins/admin_multi_view/index.php	(revision 3278)
+++ /tags/2.0.2/plugins/admin_multi_view/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/plugins/admin_multi_view/is_admin.inc.php
===================================================================
--- /tags/2.0.2/plugins/admin_multi_view/is_admin.inc.php	(revision 3278)
+++ /tags/2.0.2/plugins/admin_multi_view/is_admin.inc.php	(revision 3278)
@@ -0,0 +1,47 @@
+<?php
+if (! defined('MULTIVIEW_CONTROLLER') )
+{
+  global $user;
+  $view_as = pwg_get_session_var( 'multiview_as', 0 );
+  if ($view_as)
+  {
+    $user = build_user( $view_as, true);
+  }
+  $theme = pwg_get_session_var( 'multiview_theme', '' );
+  if ( !empty($theme) )
+  {
+    list($user['template'], $user['theme']) = explode('/', $theme);
+    unset( $user['admin_template'], $user['admin_theme']);
+  }
+  $lang = pwg_get_session_var( 'multiview_lang', '' );
+  if ( !empty($lang) )
+  {
+    $user['language'] = $lang;
+  }
+  global $conf;
+  if (pwg_get_session_var( 'multiview_show_queries', 0 ))
+    $conf['show_queries'] = true;
+  if (pwg_get_session_var( 'multiview_debug_l10n', 0 ))
+    $conf['debug_l10n'] = true;
+  if (pwg_get_session_var( 'multiview_debug_template', 0 ))
+    $conf['debug_template'] = true;
+}
+
+add_event_handler('loc_end_page_header', 'multiview_loc_end_page_header');
+
+function multiview_loc_end_page_header()
+{
+  global $template;
+  $my_root_url = get_root_url().'plugins/'. basename(dirname(__FILE__)).'/';
+  $js =
+'<script type="text/javascript">
+var theController = window.open("", "mview_controller", "alwaysRaised=yes,dependent=yes,toolbar=no,height=200,width=220,menubar=no,resizable=yes,scrollbars=yes,status=no");
+if ( theController.location.toString()=="about:blank" || !theController.location.toString().match(/^(https?.*\/)controller\.php(\?.+)?$/))
+{
+  theController.location = "'.$my_root_url.'controller.php";
+}
+</script>';
+
+  $template->append( 'head_elements', $js );
+}
+?>
Index: /tags/2.0.2/plugins/admin_multi_view/main.inc.php
===================================================================
--- /tags/2.0.2/plugins/admin_multi_view/main.inc.php	(revision 3278)
+++ /tags/2.0.2/plugins/admin_multi_view/main.inc.php	(revision 3278)
@@ -0,0 +1,42 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 Piwigo team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+/*
+Plugin Name: Multi view
+Version: 2.0.2
+Description: Allows administrators to view gallery as guests and/or change the language and/or theme on the fly. Practical to debug changes ...
+Plugin URI: http://piwigo.org/ext/extension_view.php?eid=286
+Author: Piwigo team
+Author URI: http://piwigo.org
+*/
+
+add_event_handler('user_init', 'multiview_user_init' );
+
+function multiview_user_init()
+{
+  if (!is_admin())
+    return;
+  include_once( dirname(__FILE__).'/is_admin.inc.php' );
+}
+
+?>
Index: /tags/2.0.2/plugins/c13y_upgrade/index.php
===================================================================
--- /tags/2.0.2/plugins/c13y_upgrade/index.php	(revision 3278)
+++ /tags/2.0.2/plugins/c13y_upgrade/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/plugins/c13y_upgrade/initialize.inc.php
===================================================================
--- /tags/2.0.2/plugins/c13y_upgrade/initialize.inc.php	(revision 3278)
+++ /tags/2.0.2/plugins/c13y_upgrade/initialize.inc.php	(revision 3278)
@@ -0,0 +1,116 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+add_event_handler('list_check_integrity', 'c13y_upgrade');
+
+function c13y_upgrade($c13y)
+{
+  global $conf;
+
+  load_language('plugin.lang', dirname(__FILE__).'/');
+
+  $to_deactivate = true;
+
+  /* Check user with same e-mail */
+  $query = '
+select
+  count(*)
+from
+  '.USERS_TABLE.'
+where
+  '.$conf['user_fields']['email'].' is not null
+group by
+  upper('.$conf['user_fields']['email'].')
+having count(*) > 1
+limit 0,1
+;';
+
+  if (mysql_fetch_array(pwg_query($query)))
+  {
+    $to_deactivate = false;
+    $c13y->add_anomaly(
+      l10n('c13y_dbl_email_user'),
+      null,
+      null,
+      l10n('c13y_correction_dbl_email_user'));
+  }
+
+  /* Check plugin included in Piwigo sources */
+  $included_plugins = array('dew', 'UpToDate', 'PluginsManager');
+  $query = '
+select
+  id
+from
+  '.PLUGINS_TABLE.'
+where
+  id in ('.
+    implode(
+      ',',
+      array_map(
+        create_function('$s', 'return "\'".$s."\'";'),
+        $included_plugins
+        )
+      )
+      .')
+;';
+
+  $result = pwg_query($query);
+  while ($row = mysql_fetch_assoc($result))
+  {
+    $to_deactivate = false;
+
+    $uninstall_msg_link =
+      '<a href="'.
+      PHPWG_ROOT_PATH.
+      'admin.php?page=plugins_list&amp;plugin='.$row['id'].'&amp;action=uninstall'.
+      '" onclick="window.open(this.href, \'\'); return false;">'.
+      sprintf(l10n('c13y_correction_obsolete_plugin'), $row['id']).'</a>';
+
+    $c13y->add_anomaly(
+      l10n('c13y_obsolete_plugin'),
+      null,
+      null,
+      $uninstall_msg_link);
+  }
+
+  /* Check if this plugin must be deactivate */
+  if ($to_deactivate)
+  {
+    $query = '
+REPLACE INTO '.PLUGINS_TABLE.'
+(id, state)
+VALUES (\'c13y_upgrade\', \'inactive\')
+;';
+    pwg_query($query);
+
+  global $page;
+  $page['infos'][] = l10n('c13y_upgrade_no_anomaly');
+  }
+}
+
+?>
Index: /tags/2.0.2/plugins/c13y_upgrade/language/de_DE/index.php
===================================================================
--- /tags/2.0.2/plugins/c13y_upgrade/language/de_DE/index.php	(revision 3278)
+++ /tags/2.0.2/plugins/c13y_upgrade/language/de_DE/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/plugins/c13y_upgrade/language/de_DE/plugin.lang.php
===================================================================
--- /tags/2.0.2/plugins/c13y_upgrade/language/de_DE/plugin.lang.php	(revision 3278)
+++ /tags/2.0.2/plugins/c13y_upgrade/language/de_DE/plugin.lang.php	(revision 3278)
@@ -0,0 +1,31 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// --------- Starting below: New or revised $lang ---- from Butterfly (1.8)
+$lang['c13y_upgrade_no_anomaly'] = 'Keine Unregelmäßigkeiten festgestellt nach der Aktualisierung der Anwendung'; /* TODO , "Check upgrades" plugin was deactivated.'*/
+$lang['c13y_dbl_email_user'] = 'Benutzer mit gleichen E-Mail-Adresse';
+$lang['c13y_correction_dbl_email_user'] = 'Löschen doppeltes Benutzer';
+$lang['c13y_obsolete_plugin'] = 'Veraltete Plugin';
+$lang['c13y_correction_obsolete_plugin'] = 'Das Plugin "%s" wurde enthaltet in dieser Programms Version und es müss deinstalliert werden.';
+
+?>
Index: /tags/2.0.2/plugins/c13y_upgrade/language/en_UK/index.php
===================================================================
--- /tags/2.0.2/plugins/c13y_upgrade/language/en_UK/index.php	(revision 3278)
+++ /tags/2.0.2/plugins/c13y_upgrade/language/en_UK/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/plugins/c13y_upgrade/language/en_UK/plugin.lang.php
===================================================================
--- /tags/2.0.2/plugins/c13y_upgrade/language/en_UK/plugin.lang.php	(revision 3278)
+++ /tags/2.0.2/plugins/c13y_upgrade/language/en_UK/plugin.lang.php	(revision 3278)
@@ -0,0 +1,31 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// --------- Starting below: New or revised $lang ---- from Butterfly (1.8)
+$lang['c13y_upgrade_no_anomaly'] = 'No anomaly detected after application upgrade, "Check upgrades" plugin was deactivated.';
+$lang['c13y_dbl_email_user'] = 'Users with same email address';
+$lang['c13y_correction_dbl_email_user'] = 'Delete duplicate users';
+$lang['c13y_obsolete_plugin'] = 'Obsolete plugin';
+$lang['c13y_correction_obsolete_plugin'] = '"%s" plugin has been included in this application version and you must uninstall it.';
+
+?>
Index: /tags/2.0.2/plugins/c13y_upgrade/language/es_ES/index.php
===================================================================
--- /tags/2.0.2/plugins/c13y_upgrade/language/es_ES/index.php	(revision 3278)
+++ /tags/2.0.2/plugins/c13y_upgrade/language/es_ES/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/plugins/c13y_upgrade/language/es_ES/plugin.lang.php
===================================================================
--- /tags/2.0.2/plugins/c13y_upgrade/language/es_ES/plugin.lang.php	(revision 3278)
+++ /tags/2.0.2/plugins/c13y_upgrade/language/es_ES/plugin.lang.php	(revision 3278)
@@ -0,0 +1,31 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// --------- Starting below: New or revised $lang ---- from Butterfly (1.8)
+$lang['c13y_upgrade_no_anomaly'] = 'Detectada ninguna anomalía después de la puesta al día de la aplicación, el plugin Check upgrades ha sido desactivado.';
+$lang['c13y_dbl_email_user'] = 'Usuarios con mismo correo electrónico';
+$lang['c13y_correction_dbl_email_user'] = 'Suprima a los utilizadores en duplicado';
+$lang['c13y_obsolete_plugin'] = 'Plugin obsoleto';
+$lang['c13y_correction_obsolete_plugin'] = 'El plugin "%s" ha sido incluido en esta versión de la aplicación y usted debe desinstalarlo.';
+
+?>
Index: /tags/2.0.2/plugins/c13y_upgrade/language/fr_FR/index.php
===================================================================
--- /tags/2.0.2/plugins/c13y_upgrade/language/fr_FR/index.php	(revision 3278)
+++ /tags/2.0.2/plugins/c13y_upgrade/language/fr_FR/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/plugins/c13y_upgrade/language/fr_FR/plugin.lang.php
===================================================================
--- /tags/2.0.2/plugins/c13y_upgrade/language/fr_FR/plugin.lang.php	(revision 3278)
+++ /tags/2.0.2/plugins/c13y_upgrade/language/fr_FR/plugin.lang.php	(revision 3278)
@@ -0,0 +1,31 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// --------- Starting below: New or revised $lang ---- from Butterfly (1.8)
+$lang['c13y_upgrade_no_anomaly'] = 'Pas d\'anomalie détectée après la mise à jour de l\'application, le plugin "Check upgrades" a été désactivé.';
+$lang['c13y_dbl_email_user'] = 'Utilisateurs avec la même adresse email';
+$lang['c13y_correction_dbl_email_user'] = 'Supprimez les utilisateurs en double';
+$lang['c13y_obsolete_plugin'] = 'Plugin obsolète';
+$lang['c13y_correction_obsolete_plugin'] = 'Le plugin "%s" a été inclus dans cette version de l\'application et vous devez le désinstaller.';
+
+?>
Index: /tags/2.0.2/plugins/c13y_upgrade/language/index.php
===================================================================
--- /tags/2.0.2/plugins/c13y_upgrade/language/index.php	(revision 3278)
+++ /tags/2.0.2/plugins/c13y_upgrade/language/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/plugins/c13y_upgrade/language/it_IT/index.php
===================================================================
--- /tags/2.0.2/plugins/c13y_upgrade/language/it_IT/index.php	(revision 3278)
+++ /tags/2.0.2/plugins/c13y_upgrade/language/it_IT/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/plugins/c13y_upgrade/language/it_IT/plugin.lang.php
===================================================================
--- /tags/2.0.2/plugins/c13y_upgrade/language/it_IT/plugin.lang.php	(revision 3278)
+++ /tags/2.0.2/plugins/c13y_upgrade/language/it_IT/plugin.lang.php	(revision 3278)
@@ -0,0 +1,31 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// --------- Starting below: New or revised $lang ---- from Butterfly (1.8)
+$lang['c13y_upgrade_no_anomaly'] = 'Nessun anomalia individuata dopo l\'aggiornamento dell\'applicatione, il plugin "Check upgrades" è stato disattivato .';
+$lang['c13y_dbl_email_user'] = 'Utenti con lo stesso indirizzo email';
+$lang['c13y_correction_dbl_email_user'] = 'Cancellare i doppioni';
+$lang['c13y_obsolete_plugin'] = 'Plugin obsoleto';
+$lang['c13y_correction_obsolete_plugin'] = 'Il plugin "%s" è stato incluso in questa versione dell\'applicazione e dovete disinstallarlo.';
+
+?>
Index: /tags/2.0.2/plugins/c13y_upgrade/main.inc.php
===================================================================
--- /tags/2.0.2/plugins/c13y_upgrade/main.inc.php	(revision 3278)
+++ /tags/2.0.2/plugins/c13y_upgrade/main.inc.php	(revision 3278)
@@ -0,0 +1,46 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+/*
+Plugin Name: Check upgrades
+Version: 2.0.2
+Description: Check integrity of upgrades / Contrôle d'intégrité des mises à jour
+Plugin URI: http://piwigo.org/ext/extension_view.php?eid=287
+Author: Piwigo team
+Author URI: http://piwigo.org
+*/
+
+if (!defined('PHPWG_ROOT_PATH'))
+{
+  die('Hacking attempt!');
+}
+
+if (in_array(script_basename(), array('popuphelp', 'admin')))
+{
+  if (defined('IN_ADMIN') and IN_ADMIN)
+  {
+   include_once(dirname(__FILE__).'/initialize.inc.php');
+  }
+}
+
+?>
Index: /tags/2.0.2/plugins/event_tracer/event_list.php
===================================================================
--- /tags/2.0.2/plugins/event_tracer/event_list.php	(revision 3278)
+++ /tags/2.0.2/plugins/event_tracer/event_list.php	(revision 3278)
@@ -0,0 +1,90 @@
+<?php
+if (!defined('PHPWG_ROOT_PATH')) die('Hacking attempt!');
+
+function get_php_files($path, $to_ignore=array(), $recursive=true )
+{
+  $files = array();
+  if (is_dir($path))
+  {
+    if ($contents = opendir($path))
+    {
+      while (($node = readdir($contents)) !== false)
+      {
+        if ($node != '.' and $node != '..' and $node != '.svn'
+            and !in_array($node, $to_ignore) )
+        {
+          if ( $recursive and is_dir($path.'/'.$node) )
+          {
+            $files = array_merge($files, get_php_files($path.'/'.$node, $to_ignore));
+
+          }
+          if ( is_file($path.'/'.$node) )
+          {
+            $files[] = $path.'/'.$node;
+          }
+        }
+      }
+      closedir($contents);
+    }
+  }
+  return $files;
+}
+
+$files = array();
+$files = array_merge( $files, get_php_files('.', array(), false) );
+$files = array_merge( $files, get_php_files('./include') );
+$files = array_merge( $files, get_php_files('./admin') );
+$files = array_unique($files);
+
+$events = array();
+foreach ($files as $file)
+{
+  $code = file_get_contents($file);
+  $code = preg_replace( '#\?'.'>.*<\?php#m', '', $code);
+  $code = preg_replace( '#\/\*.*\*\/#m', '', $code);
+  $code = preg_replace( '#\/\/.*#', '', $code);
+
+  $count = preg_match_all(
+    '#[^a-zA-Z_$-]trigger_(action|event)\s*\(\s*([^,)]+)#m',
+    $code, $matches
+    );
+
+  for ($i=0; $i<$count; $i++)
+  {
+    $type = $matches[1][$i];
+    $name = preg_replace( '#^[\'"]?([^\'"]*)[\'"]?$#', '$1', $matches[2][$i]);
+    array_push($events, array($type,$name,$file) );
+  }
+}
+
+$sort= isset($_GET['sort']) ? (int)$_GET['sort'] : 1;
+usort(
+  $events,
+  create_function( '$a,$b', 'return $a['.$sort.']>$b['.$sort.'];' )
+  );
+
+global $template;
+
+$url = get_admin_plugin_menu_link(__FILE__);
+
+$template->assign( array(
+  'NB_EVENTS' => count($events),
+  'U_SORT0' => add_url_params($url, array('sort'=>0) ),
+  'U_SORT1' => add_url_params($url, array('sort'=>1) ),
+  'U_SORT2' => add_url_params($url, array('sort'=>2) ),
+  ) );
+
+$template->assign('events', array());
+foreach ($events as $e)
+{
+  $template->append( 'events', array(
+    'TYPE' => $e[0],
+    'NAME' => $e[1],
+    'FILE' => $e[2],
+    )
+  );
+}
+
+$template->set_filenames( array('event_list' => dirname(__FILE__).'/event_list.tpl' ) );
+$template->assign_var_from_handle( 'ADMIN_CONTENT', 'event_list');
+?>
Index: /tags/2.0.2/plugins/event_tracer/event_list.tpl
===================================================================
--- /tags/2.0.2/plugins/event_tracer/event_list.tpl	(revision 3278)
+++ /tags/2.0.2/plugins/event_tracer/event_list.tpl	(revision 3278)
@@ -0,0 +1,17 @@
+{* $Id$ *}
+There are {$NB_EVENTS} calls to triger_event or triger_action.
+
+<table width="99%" class="table2">
+<tr class="throw">
+  <th><a href="{$U_SORT0}">Type</a></th>
+  <th><a href="{$U_SORT1}">Name</a></th>
+  <th><a href="{$U_SORT2}">File</a></th>
+</tr>
+{foreach from=$events item=event}
+<tr>
+  <td>{$event.TYPE}</td>
+  <td>{$event.NAME}</td>
+  <td>{$event.FILE}</td>
+</tr>
+{/foreach}
+</table>
Index: /tags/2.0.2/plugins/event_tracer/index.php
===================================================================
--- /tags/2.0.2/plugins/event_tracer/index.php	(revision 3278)
+++ /tags/2.0.2/plugins/event_tracer/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/plugins/event_tracer/main.inc.php
===================================================================
--- /tags/2.0.2/plugins/event_tracer/main.inc.php	(revision 3278)
+++ /tags/2.0.2/plugins/event_tracer/main.inc.php	(revision 3278)
@@ -0,0 +1,158 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 Piwigo team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+/*
+Plugin Name: Event tracer
+Version: 2.0.2
+Description: For developers. Shows all calls to trigger_event.
+Plugin URI: http://piwigo.org/ext/extension_view.php?eid=288
+Author: Piwigo team
+Author URI: http://piwigo.org
+*/
+
+if (!defined('PHPWG_ROOT_PATH')) die('Hacking attempt!');
+
+class EventTracer
+{
+  var $my_config;
+  var $trigger_counts = array();
+
+  function EventTracer()
+  {
+  }
+
+  function get_config_file_dir()
+  {
+    global $conf;
+    return $conf['local_data_dir'].'/plugins/';
+  }
+
+  function get_config_file_name()
+  {
+    return basename(dirname(__FILE__)).'.dat';
+  }
+
+  function load_config()
+  {
+    $x = @file_get_contents( $this->get_config_file_dir().$this->get_config_file_name() );
+    if ($x!==false)
+    {
+      $c = unserialize($x);
+      // do some more tests here
+      $this->my_config = $c;
+    }
+    if ( !isset($this->my_config)
+        or empty($this->my_config['filters']) )
+    {
+      $this->my_config['filters'] = array( '.*' );
+      $this->my_config['show_args'] = false;
+      $this->my_config['show_registered'] = true;
+      $this->save_config();
+    }
+  }
+
+  function save_config()
+  {
+    $dir = $this->get_config_file_dir();
+    @mkgetdir($dir);
+    $file = fopen( $dir.$this->get_config_file_name(), 'w' );
+    fwrite($file, serialize($this->my_config) );
+    fclose( $file );
+  }
+
+  function on_page_tail()
+  {
+    if (1 || @$this->my_config['show_registered'])
+    {
+      global $debug, $pwg_event_handlers;
+      $out = '';
+      foreach ($pwg_event_handlers as $event => $prio_array)
+      {
+        $out .= $event.' '.intval(@$this->trigger_counts[$event])." calls\n";
+        foreach ($prio_array as $prio => $handlers)
+        {
+          foreach ($handlers as $handler)
+          {
+            $out .= "\t$prio ";
+            if ( is_array($handler['function']) )
+            {
+              if ( is_string($handler['function'][0]) )
+                $out .= $handler['function'][0].'::';
+              else
+                $out .= @get_class($handler['function'][0]).'->';
+              $out .= $handler['function'][1];
+            }
+            else
+             $out .= $handler['function'];
+            $out .= "\n";
+          }
+        }
+        $out .= "\n";
+      }
+      $debug .= '<pre>'.$out.'</pre>';
+    }
+  }
+
+  function on_trigger($event_info)
+  {
+    if ($event_info['type']!='post_event')
+      @$this->trigger_counts[$event_info['event']]++;
+
+    foreach( $this->my_config['filters'] as $filter)
+    {
+      if ( preg_match( '/'.$filter.'/', $event_info['event'] ) )
+      {
+        if ($this->my_config['show_args'])
+        {
+          $s = '<pre>';
+          $s .= htmlspecialchars( var_export( $event_info['data'], true ) );
+          $s .= '</pre>';
+        }
+        else
+          $s = '';
+        pwg_debug($event_info['type'].' "'.$event_info['event'].'" '.($this->trigger_counts[$event_info['event']]).' calls '.($s) );
+        break;
+      }
+    }
+  }
+
+  function plugin_admin_menu($menu)
+  {
+    array_push($menu,
+        array(
+          'NAME' => 'Event Tracer',
+          'URL' => get_admin_plugin_menu_link(dirname(__FILE__).'/tracer_admin.php')
+        )
+      );
+    return $menu;
+  }
+}
+
+$obj = new EventTracer();
+$obj->load_config();
+
+add_event_handler('get_admin_plugin_menu_links', array(&$obj, 'plugin_admin_menu') );
+add_event_handler('loc_begin_page_tail', array(&$obj, 'on_page_tail') );
+add_event_handler('trigger', array(&$obj, 'on_trigger') );
+set_plugin_data($plugin['id'], $obj);
+?>
Index: /tags/2.0.2/plugins/event_tracer/maintain.inc.php
===================================================================
--- /tags/2.0.2/plugins/event_tracer/maintain.inc.php	(revision 3278)
+++ /tags/2.0.2/plugins/event_tracer/maintain.inc.php	(revision 3278)
@@ -0,0 +1,9 @@
+<?php
+if (!defined('PHPWG_ROOT_PATH')) die('Hacking attempt!');
+
+function plugin_uninstall($plugin_id)
+{
+  global $conf;
+  @unlink( $conf['local_data_dir'].'/plugins/'.$plugin_id.'.dat' );
+}
+?>
Index: /tags/2.0.2/plugins/event_tracer/tracer_admin.php
===================================================================
--- /tags/2.0.2/plugins/event_tracer/tracer_admin.php	(revision 3278)
+++ /tags/2.0.2/plugins/event_tracer/tracer_admin.php	(revision 3278)
@@ -0,0 +1,33 @@
+<?php
+if (!defined('PHPWG_ROOT_PATH')) die('Hacking attempt!');
+
+$me = get_plugin_data($plugin_id);
+
+global $template;
+$template->set_filenames( array('plugin_admin_content' => dirname(__FILE__).'/tracer_admin.tpl') );
+
+if ( isset($_POST['eventTracer_filters']) )
+{
+  $v = $_POST['eventTracer_filters'];
+  $v = str_replace( "\r\n", "\n", $v );
+  $v = str_replace( "\n\n", "\n", $v );
+  $v = stripslashes($v);
+  if (!empty($v))
+    $me->my_config['filters'] = explode("\n", $v);
+  else
+    $me->my_config['filters'] = array();
+  $me->my_config['show_args'] = isset($_POST['eventTracer_show_args']);
+  $me->my_config['show_registered'] = isset($_POST['eventTracer_show_registered']);
+  $me->save_config();
+  global $page;
+  array_push($page['infos'], 'event tracer options saved');
+}
+$template->assign('EVENT_TRACER_FILTERS', implode("\n", $me->my_config['filters'] ) );
+$template->assign('EVENT_TRACER_SHOW_ARGS', $me->my_config['show_args'] ? 'checked="checked"' : '' );
+$template->assign('U_LIST_EVENTS', get_admin_plugin_menu_link(dirname(__FILE__).'/event_list.php'));
+$template->assign('EVENT_TRACER_SHOW_REGISTERED', $me->my_config['show_registered'] ? 'checked="checked"' : '' );
+
+//$template->assign_var('EVENT_TRACER_F_ACTION', $my_url);
+
+$template->assign_var_from_handle( 'ADMIN_CONTENT', 'plugin_admin_content');
+?>
Index: /tags/2.0.2/plugins/event_tracer/tracer_admin.tpl
===================================================================
--- /tags/2.0.2/plugins/event_tracer/tracer_admin.tpl	(revision 3278)
+++ /tags/2.0.2/plugins/event_tracer/tracer_admin.tpl	(revision 3278)
@@ -0,0 +1,37 @@
+{* $Id$ *}
+<div class="titrePage">
+  <h2>Event Tracer</h2>
+</div>
+
+<p>
+The event tracer is a developer tool that logs in the footer of the window all calls to trigger_event method.
+You can use this plugin to see what events is Piwigo calling.
+<b>Note that $conf['show_queries'] must be true.</b>
+</p>
+<form method="post" action="" class="general">
+<fieldset>
+	<legend>Event Tracer</legend>
+
+<label>Show event arguments
+	<input type="checkbox" name="eventTracer_show_args" {$EVENT_TRACER_SHOW_ARGS} />
+</label>
+
+<br/>
+
+<label>Fill below a list of regular expressions (one per line).
+An event will be logged if its name matches at least one expression in the list.
+	<textarea name="eventTracer_filters" id="eventTracer_filters"rows="10" cols="80">{$EVENT_TRACER_FILTERS}</textarea>
+</label>
+
+<br/>
+
+<label>Show all registered handlers
+	<input type="checkbox" name="eventTracer_show_registered" {$EVENT_TRACER_SHOW_REGISTERED} />
+</label>
+
+</fieldset>
+
+<p><input class="submit" type="submit" value="Submit" /></p>
+
+<p><a href="{$U_LIST_EVENTS}">Click here to see a complete list of actions and events trigered by this PWG version</a>.</p>
+</form>
Index: /tags/2.0.2/plugins/index.php
===================================================================
--- /tags/2.0.2/plugins/index.php	(revision 3278)
+++ /tags/2.0.2/plugins/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/plugins/language_switch/icons/index.php
===================================================================
--- /tags/2.0.2/plugins/language_switch/icons/index.php	(revision 3278)
+++ /tags/2.0.2/plugins/language_switch/icons/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/plugins/language_switch/index.php
===================================================================
--- /tags/2.0.2/plugins/language_switch/index.php	(revision 3278)
+++ /tags/2.0.2/plugins/language_switch/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/plugins/language_switch/language_switch.inc.php
===================================================================
--- /tags/2.0.2/plugins/language_switch/language_switch.inc.php	(revision 3278)
+++ /tags/2.0.2/plugins/language_switch/language_switch.inc.php	(revision 3278)
@@ -0,0 +1,92 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+function language_switch()
+{
+  global $user, $template, $conf, $lang;
+  if (!defined('PHPWG_ROOT_PATH')) { die('Hacking attempt!'); }
+  $same = $user['language'];
+  if ( isset( $_GET['lang']) )
+  {
+    if ( !empty($_GET['lang'] ) and
+      file_exists( PHPWG_ROOT_PATH.'language/'
+      . $_GET['lang'].'/common.lang.php') )
+    {
+      if (is_a_guest() or is_generic())
+      {
+        setcookie( 'pwg_lang_switch', $_GET['lang'],
+          time()+60*60*24*30, cookie_path() );
+      }
+      else
+      {
+        $query = 'UPDATE '.USER_INFOS_TABLE.'
+        SET language = \''.$_GET['lang'].'\'
+        WHERE user_id = '.$user['id'].'
+        ;';
+        pwg_query($query);
+      }
+      $user['language'] = $_GET['lang'];
+    }
+  }
+// Users have $user['language']
+// Guest or generic members will use their cookied language !
+  if ((is_a_guest() or is_generic())
+    and isset( $_COOKIE['pwg_lang_switch'] ) )
+  {
+    $user['language'] = $_COOKIE['pwg_lang_switch'];
+  }
+// Reload language only if it isn't the same one
+  if ( $same !== $user['language'])
+  {
+    load_language('common.lang', '', array('language'=>$user['language']) );
+    load_language('local.lang', '', array('language'=>$user['language'], 'no_fallback'=>true) );
+    if (defined('IN_ADMIN') and IN_ADMIN)
+    {
+      load_language('admin.lang', '', array('language'=>$user['language']) );
+    }
+  }
+}
+//if ( isset( $_GET['lang']) ) { redirect( make_index_url() ); }
+
+function Lang_flags()
+{
+  global $user, $template;
+  $available_lang = get_languages();
+  foreach ( $available_lang as $code => $displayname )
+  {
+    $qlc_url = add_url_params( make_index_url(), array( 'lang' => $code ) );
+    $qlc_alt = ucwords( $displayname );
+    $qlc_title =  $qlc_alt;
+    $qlc_img =  'plugins/language_switch/icons/'
+       . $code . '.gif';
+
+    if ( $code !== $user['language'] and file_exists(PHPWG_ROOT_PATH.$qlc_img) )
+    {
+      $template->concat( 'PLUGIN_INDEX_ACTIONS',
+        '<li><a href="' . $qlc_url . '" ><img src="' . get_root_url().$qlc_img . '" alt="'
+        . $qlc_alt . '" title="'
+        . $qlc_title . '" style="border: 1px solid #000000; '
+        . ' margin: 0px 2px;" /></a></li>');
+    }
+  }
+}
+?>
Index: /tags/2.0.2/plugins/language_switch/main.inc.php
===================================================================
--- /tags/2.0.2/plugins/language_switch/main.inc.php	(revision 3278)
+++ /tags/2.0.2/plugins/language_switch/main.inc.php	(revision 3278)
@@ -0,0 +1,36 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+/*
+Plugin Name: Language Switch
+Version: 2.0.2
+Description: Switch to another language from flags on your gallery home page.
+Plugin URI: http://piwigo.org/ext/extension_view.php?eid=123
+Author: Piwigo team
+Author URI: http://piwigo.org
+*/
+
+include_once(PHPWG_PLUGINS_PATH.'language_switch/language_switch.inc.php');
+add_event_handler('loading_lang', 'language_switch' );
+add_event_handler('loc_end_index', 'Lang_flags' );
+?>
Index: /tags/2.0.2/popuphelp.php
===================================================================
--- /tags/2.0.2/popuphelp.php	(revision 3278)
+++ /tags/2.0.2/popuphelp.php	(revision 3278)
@@ -0,0 +1,80 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// +-----------------------------------------------------------------------+
+// |                           initialization                              |
+// +-----------------------------------------------------------------------+
+
+define('PHPWG_ROOT_PATH','./');
+include_once( PHPWG_ROOT_PATH.'include/common.inc.php' );
+
+// +-----------------------------------------------------------------------+
+// | Check Access and exit when user status is not ok                      |
+// +-----------------------------------------------------------------------+
+check_status(ACCESS_GUEST);
+
+$page['body_id'] = 'thePopuphelpPage';
+$title = l10n('Piwigo Help');
+$page['page_banner'] = '<h1>'.$title.'</h1>';
+$page['meta_robots']=array('noindex'=>1, 'nofollow'=>1);
+include(PHPWG_ROOT_PATH.'include/page_header.php');
+
+if
+  (
+    isset($_GET['page'])
+    and preg_match('/^[a-z_]*$/', $_GET['page'])
+  )
+{
+  $help_content =
+    load_language('help/'.$_GET['page'].'.html', '', array('return'=>true) );
+
+  if ($help_content == false)
+  {
+    $help_content = '';
+  }
+
+  $help_content = trigger_event(
+    'get_popup_help_content', $help_content, $_GET['page']);
+}
+else
+{
+  die('Hacking attempt!');
+}
+
+$template->set_filename('popuphelp','popuphelp.tpl');
+
+$template->assign(
+  array
+  (
+    'HELP_CONTENT' => $help_content
+  ));
+
+// +-----------------------------------------------------------------------+
+// |                           html code display                           |
+// +-----------------------------------------------------------------------+
+
+$template->pparse('popuphelp');
+
+include(PHPWG_ROOT_PATH.'include/page_tail.php');
+
+?>
Index: /tags/2.0.2/profile.php
===================================================================
--- /tags/2.0.2/profile.php	(revision 3278)
+++ /tags/2.0.2/profile.php	(revision 3278)
@@ -0,0 +1,271 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// customize appearance of the site for a user
+// +-----------------------------------------------------------------------+
+// |                           initialization                              |
+// +-----------------------------------------------------------------------+
+
+if (!defined('PHPWG_ROOT_PATH'))
+{//direct script access
+  define('PHPWG_ROOT_PATH','./');
+  include_once(PHPWG_ROOT_PATH.'include/common.inc.php');
+
+  // +-----------------------------------------------------------------------+
+  // | Check Access and exit when user status is not ok                      |
+  // +-----------------------------------------------------------------------+
+  check_status(ACCESS_CLASSIC);
+
+  $userdata = $user;
+
+  trigger_action('loc_begin_profile');
+
+  save_profile_from_post($userdata, $errors);
+
+  $title= l10n('customize_page_title');
+  $page['body_id'] = 'theProfilePage';
+  include(PHPWG_ROOT_PATH.'include/page_header.php');
+
+  load_profile_in_template(
+    get_root_url().'profile.php', // action
+    make_index_url(), // for redirect
+    $userdata );
+
+  // +-----------------------------------------------------------------------+
+  // |                             errors display                            |
+  // +-----------------------------------------------------------------------+
+  if (count($errors) != 0)
+  {
+    $template->assign('errors', $errors);
+  }
+  $template->set_filename('profile', 'profile.tpl');
+  trigger_action('loc_end_profile');
+  $template->parse('profile');
+  include(PHPWG_ROOT_PATH.'include/page_tail.php');
+}
+
+//------------------------------------------------------ update & customization
+function save_profile_from_post($userdata, &$errors)
+{
+  global $conf;
+  $errors = array();
+
+  if (!isset($_POST['validate']))
+  {
+    return false;
+  }
+
+  $special_user = in_array($userdata['id'], array($conf['guest_id'], $conf['default_user_id']));
+  if ($special_user)
+  {
+    unset($_POST['mail_address'],
+          $_POST['password'],
+          $_POST['use_new_pwd'],
+          $_POST['passwordConf']
+          );
+  }
+
+  $int_pattern = '/^\d+$/';
+  if (empty($_POST['nb_image_line'])
+      or (!preg_match($int_pattern, $_POST['nb_image_line'])))
+  {
+    $errors[] = l10n('nb_image_line_error');
+  }
+
+  if (empty($_POST['nb_line_page'])
+      or (!preg_match($int_pattern, $_POST['nb_line_page'])))
+  {
+    $errors[] = l10n('nb_line_page_error');
+  }
+
+  if ($_POST['maxwidth'] != ''
+      and (!preg_match($int_pattern, $_POST['maxwidth'])
+           or $_POST['maxwidth'] < 50))
+  {
+    $errors[] = l10n('maxwidth_error');
+  }
+  if ($_POST['maxheight']
+       and (!preg_match($int_pattern, $_POST['maxheight'])
+             or $_POST['maxheight'] < 50))
+  {
+    $errors[] = l10n('maxheight_error');
+  }
+  // periods must be integer values, they represents number of days
+  if (!preg_match($int_pattern, $_POST['recent_period'])
+      or $_POST['recent_period'] <= 0)
+  {
+    $errors[] = l10n('periods_error') ;
+  }
+
+  if (isset($_POST['mail_address']))
+  {
+    // if $_POST and $userdata have are same email
+    // validate_mail_address allows, however, to check email
+    $mail_error = validate_mail_address($userdata['id'], $_POST['mail_address']);
+    if (!empty($mail_error))
+    {
+      $errors[] = $mail_error;
+    }
+  }
+
+  if (!empty($_POST['use_new_pwd']))
+  {
+    // password must be the same as its confirmation
+    if ($_POST['use_new_pwd'] != $_POST['passwordConf'])
+    {
+      $errors[] = l10n('New password confirmation does not correspond');
+    }
+
+    if ( !defined('IN_ADMIN') )
+    {// changing password requires old password
+      $query = '
+  SELECT '.$conf['user_fields']['password'].' AS password
+    FROM '.USERS_TABLE.'
+    WHERE '.$conf['user_fields']['id'].' = \''.$userdata['id'].'\'
+  ;';
+      list($current_password) = mysql_fetch_row(pwg_query($query));
+  
+      if ($conf['pass_convert']($_POST['password']) != $current_password)
+      {
+        $errors[] = l10n('Current password is wrong');
+      }
+    }
+  }
+
+  if (count($errors) == 0)
+  {
+    // mass_updates function
+    include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+
+    if (isset($_POST['mail_address']))
+    {
+      // update common user informations
+      $fields = array($conf['user_fields']['email']);
+
+      $data = array();
+      $data{$conf['user_fields']['id']} = $userdata['id'];
+      $data{$conf['user_fields']['email']} = $_POST['mail_address'];
+
+      // password is updated only if filled
+      if (!empty($_POST['use_new_pwd']))
+      {
+        array_push($fields, $conf['user_fields']['password']);
+        // password is encrpyted with function $conf['pass_convert']
+        $data{$conf['user_fields']['password']} =
+          $conf['pass_convert']($_POST['use_new_pwd']);
+      }
+      mass_updates(USERS_TABLE,
+                   array('primary' => array($conf['user_fields']['id']),
+                         'update' => $fields),
+                   array($data));
+    }
+
+    // update user "additional" informations (specific to Piwigo)
+    $fields = array(
+      'nb_image_line', 'nb_line_page', 'language', 'maxwidth', 'maxheight',
+      'expand', 'show_nb_comments', 'show_nb_hits', 'recent_period', 'template'
+      );
+
+    $data = array();
+    $data['user_id'] = $userdata['id'];
+
+    foreach ($fields as $field)
+    {
+      if (isset($_POST[$field]))
+      {
+        $data[$field] = $_POST[$field];
+      }
+    }
+    mass_updates(USER_INFOS_TABLE,
+                 array('primary' => array('user_id'), 'update' => $fields),
+                 array($data));
+
+    trigger_action( 'save_profile_from_post', $userdata['id'] );
+    
+    if (!empty($_POST['redirect']))
+    {
+      redirect($_POST['redirect']);
+    }
+  }
+  return true;
+}
+
+
+function load_profile_in_template($url_action, $url_redirect, $userdata)
+{
+  global $template, $conf;
+
+  $template->set_filename('profile_content', 'profile_content.tpl');
+
+  $template->assign('radio_options',
+    array(
+      'true' => l10n('Yes'),
+      'false' => l10n('No')));
+
+  $template->assign(
+    array(
+      'USERNAME'=>$userdata['username'],
+      'EMAIL'=>get_email_address_as_display_text(@$userdata['email']),
+      'NB_IMAGE_LINE'=>$userdata['nb_image_line'],
+      'NB_ROW_PAGE'=>$userdata['nb_line_page'],
+      'RECENT_PERIOD'=>$userdata['recent_period'],
+      'MAXWIDTH'=>@$userdata['maxwidth'],
+      'MAXHEIGHT'=>@$userdata['maxheight'],
+      'EXPAND' =>$userdata['expand'] ? 'true' : 'false',
+      'NB_COMMENTS'=>$userdata['show_nb_comments'] ? 'true' : 'false',
+      'NB_HITS'=>$userdata['show_nb_hits'] ? 'true' : 'false',
+      'REDIRECT' => $url_redirect,
+      'F_ACTION'=>$url_action,
+      ));
+
+  foreach (get_pwg_themes() as $pwg_template)
+  {
+    if (isset($_POST['submit'])
+      or $userdata['template'].'/'.$userdata['theme'] == $pwg_template)
+    {
+      $template->assign('template_selection', $pwg_template);
+    }
+    $template_options[$pwg_template] = $pwg_template;
+  }
+  $template->assign('template_options', $template_options);
+
+  foreach (get_languages() as $language_code => $language_name)
+  {
+    if (isset($_POST['submit']) or $userdata['language'] == $language_code)
+    {
+      $template->assign('language_selection', $language_code);
+    }
+    $language_options[$language_code] = $language_name;
+  }
+  $template->assign('language_options', $language_options);
+
+  $special_user = in_array($userdata['id'], array($conf['guest_id'], $conf['default_user_id']));
+  $template->assign('SPECIAL_USER', $special_user);
+  $template->assign('IN_ADMIN', defined('IN_ADMIN'));
+
+  // allow plugins to add their own form data to content
+  trigger_action( 'load_profile_in_template', $userdata );
+  
+  $template->assign_var_from_handle('PROFILE_CONTENT', 'profile_content');
+}
+?>
Index: /tags/2.0.2/qsearch.php
===================================================================
--- /tags/2.0.2/qsearch.php	(revision 3278)
+++ /tags/2.0.2/qsearch.php	(revision 3278)
@@ -0,0 +1,74 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+define('PHPWG_ROOT_PATH','./');
+include_once( PHPWG_ROOT_PATH.'include/common.inc.php' );
+
+// +-----------------------------------------------------------------------+
+// | Check Access and exit when user status is not ok                      |
+// +-----------------------------------------------------------------------+
+check_status(ACCESS_GUEST);
+
+if (empty($_GET['q']))
+{
+  redirect( make_index_url() );
+}
+
+$search = array();
+$search['q']=$_GET['q'];
+
+$query = '
+SElECT id FROM '.SEARCH_TABLE.'
+  WHERE rules = \''.addslashes(serialize($search)).'\'
+;';
+$search_id = array_from_query( $query, 'id');
+if ( !empty($search_id) )
+{
+  $search_id = $search_id[0];
+  $query = '
+UPDATE '.SEARCH_TABLE.'
+  SET last_seen=NOW()
+  WHERE id='.$search_id;
+  pwg_query($query);
+}
+else
+{
+  $query ='
+INSERT INTO '.SEARCH_TABLE.'
+  (rules, last_seen)
+  VALUES
+  (\''.addslashes(serialize($search)).'\', NOW() )
+;';
+  pwg_query($query);
+  $search_id = mysql_insert_id();
+}
+
+redirect(
+  make_index_url(
+    array(
+      'section' => 'search',
+      'search'  => $search_id,
+      )
+    )
+  );
+?>
Index: /tags/2.0.2/random.php
===================================================================
--- /tags/2.0.2/random.php	(revision 3278)
+++ /tags/2.0.2/random.php	(revision 3278)
@@ -0,0 +1,63 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// +-----------------------------------------------------------------------+
+// |                          define and include                           |
+// +-----------------------------------------------------------------------+
+
+define('PHPWG_ROOT_PATH','./');
+include_once( PHPWG_ROOT_PATH.'include/common.inc.php' );
+
+// +-----------------------------------------------------------------------+
+// | Check Access and exit when user status is not ok                      |
+// +-----------------------------------------------------------------------+
+check_status(ACCESS_GUEST);
+
+// +-----------------------------------------------------------------------+
+// |                     generate random element list                      |
+// +-----------------------------------------------------------------------+
+
+$query = '
+SELECT DISTINCT(id)
+  FROM '.IMAGES_TABLE.'
+    INNER JOIN '.IMAGE_CATEGORY_TABLE.' AS ic ON id = ic.image_id
+'.get_sql_condition_FandF
+  (
+    array
+      (
+        'forbidden_categories' => 'category_id',
+        'visible_categories' => 'category_id',
+        'visible_images' => 'id'
+      ),
+    'WHERE'
+  ).'
+  ORDER BY RAND(NOW())
+  LIMIT 0, '.min(50, $conf['top_number'],$user['nb_image_page']).'
+;';
+
+// +-----------------------------------------------------------------------+
+// |                                redirect                               |
+// +-----------------------------------------------------------------------+
+
+redirect(make_index_url(array('list' => array_from_query($query, 'id'))));
+?>
Index: /tags/2.0.2/register.php
===================================================================
--- /tags/2.0.2/register.php	(revision 3278)
+++ /tags/2.0.2/register.php	(revision 3278)
@@ -0,0 +1,91 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+//----------------------------------------------------------- include
+define('PHPWG_ROOT_PATH','./');
+include_once( PHPWG_ROOT_PATH.'include/common.inc.php' );
+
+// +-----------------------------------------------------------------------+
+// | Check Access and exit when user status is not ok                      |
+// +-----------------------------------------------------------------------+
+check_status(ACCESS_FREE);
+
+//----------------------------------------------------------- user registration
+
+if (!$conf['allow_user_registration'])
+{
+  page_forbidden('User registration closed');
+}
+
+$errors = array();
+if (isset($_POST['submit']))
+{
+  if ($_POST['password'] != $_POST['password_conf'])
+  {
+    array_push($errors, l10n('reg_err_pass'));
+  }
+
+  $errors =
+      register_user(htmlspecialchars($_POST['login'],ENT_COMPAT,'utf-8'),
+                    $_POST['password'],
+                    $_POST['mail_address'],
+                    true,
+                    $errors);
+
+  if (count($errors) == 0)
+  {
+    $user_id = get_userid($_POST['login']);
+    log_user($user_id, false);
+    redirect(make_index_url());
+  }
+}
+
+$login = !empty($_POST['login'])?$_POST['login']:'';
+$email = !empty($_POST['mail_address'])?$_POST['mail_address']:'';
+
+//----------------------------------------------------- template initialization
+//
+// Start output of page
+//
+$title= l10n('Registration');
+$page['body_id'] = 'theRegisterPage';
+include(PHPWG_ROOT_PATH.'include/page_header.php');
+
+$template->set_filenames( array('register'=>'register.tpl') );
+$template->assign(array(
+  'U_HOME' => make_index_url(),
+
+  'F_ACTION' => 'register.php',
+  'F_LOGIN' => $login,
+  'F_EMAIL' => $email
+  ));
+
+//-------------------------------------------------------------- errors display
+if (count($errors) != 0)
+{
+  $template->assign('errors', $errors);
+}
+
+$template->parse('register');
+include(PHPWG_ROOT_PATH.'include/page_tail.php');
+?>
Index: /tags/2.0.2/search.php
===================================================================
--- /tags/2.0.2/search.php	(revision 3278)
+++ /tags/2.0.2/search.php	(revision 3278)
@@ -0,0 +1,226 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+//--------------------------------------------------------------------- include
+define('PHPWG_ROOT_PATH','./');
+include_once( PHPWG_ROOT_PATH.'include/common.inc.php' );
+
+// +-----------------------------------------------------------------------+
+// | Check Access and exit when user status is not ok                      |
+// +-----------------------------------------------------------------------+
+check_status(ACCESS_GUEST);
+
+//------------------------------------------------------------------ form check
+$errors = array();
+$search = array();
+if (isset($_POST['submit']))
+{
+  if (isset($_POST['search_allwords'])
+      and !preg_match('/^\s*$/', $_POST['search_allwords']))
+  {
+    $drop_char_match = array(
+      '-','^','$',';','#','&','(',')','<','>','`','\'','"','|',',','@','_',
+      '?','%','~','.','[',']','{','}',':','\\','/','=','\'','!','*');
+    $drop_char_replace = array(
+      ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','','',' ',' ',' ',' ','',' ',
+      ' ',' ',' ',' ',' ',' ',' ',' ','' ,' ',' ',' ',' ',' ');
+
+    // Split words
+    $search['fields']['allwords'] = array(
+      'words' => array_unique(
+        preg_split(
+          '/\s+/',
+          str_replace(
+            $drop_char_match,
+            $drop_char_replace,
+            $_POST['search_allwords']
+            )
+          )
+        ),
+      'mode' => $_POST['mode'],
+      );
+  }
+
+  if (isset($_POST['tags']))
+  {
+    $search['fields']['tags'] = array(
+      'words' => $_POST['tags'],
+      'mode'  => $_POST['tag_mode'],
+      );
+  }
+
+  if ($_POST['search_author'])
+  {
+    $search['fields']['author'] = array(
+      'words' => preg_split(
+        '/\s+/',
+        $_POST['search_author']
+        ),
+      'mode' => 'OR',
+      );
+  }
+
+  if (isset($_POST['cat']))
+  {
+    $search['fields']['cat'] = array(
+      'words'   => $_POST['cat'],
+      'sub_inc' => ($_POST['subcats-included'] == 1) ? true : false,
+      );
+  }
+
+  // dates
+  $type_date = $_POST['date_type'];
+
+  if (!empty($_POST['start_year']))
+  {
+    $search['fields'][$type_date.'-after'] = array(
+      'date' => join(
+        '-',
+        array(
+          $_POST['start_year'],
+          $_POST['start_month'] != 0 ? $_POST['start_month'] : '01',
+          $_POST['start_day']   != 0 ? $_POST['start_day']   : '01',
+          )
+        ),
+      'inc' => true,
+      );
+  }
+
+  if (!empty($_POST['end_year']))
+  {
+    $search['fields'][$type_date.'-before'] = array(
+      'date' => join(
+        '-',
+        array(
+          $_POST['end_year'],
+          $_POST['end_month'] != 0 ? $_POST['end_month'] : '12',
+          $_POST['end_day']   != 0 ? $_POST['end_day']   : '31',
+          )
+        ),
+      'inc' => true,
+      );
+  }
+
+  if (!empty($search))
+  {
+    // default search mode : each clause must be respected
+    $search['mode'] = 'AND';
+
+    // register search rules in database, then they will be available on
+    // thumbnails page and picture page.
+    $query ='
+INSERT INTO '.SEARCH_TABLE.'
+  (rules, last_seen)
+  VALUES
+  (\''.serialize($search).'\', NOW())
+;';
+    pwg_query($query);
+
+    $search_id = mysql_insert_id();
+  }
+  else
+  {
+    array_push($errors, l10n('search_one_clause_at_least'));
+  }
+}
+//----------------------------------------------------------------- redirection
+if (isset($_POST['submit']) and count($errors) == 0)
+{
+  redirect(
+    make_index_url(
+      array(
+        'section' => 'search',
+        'search'  => $search_id,
+        )
+      )
+    );
+}
+//----------------------------------------------------- template initialization
+
+//
+// Start output of page
+//
+$title= l10n('search_title');
+$page['body_id'] = 'theSearchPage';
+
+$template->set_filename('search' ,'search.tpl' );
+
+$month_list = $lang['month'];
+$month_list[0]='------------';
+ksort($month_list);
+
+$template->assign(
+  array(
+    'F_SEARCH_ACTION' => 'search.php',
+    'U_HELP' => PHPWG_ROOT_PATH.'popuphelp.php?page=search',
+
+    'month_list' => $month_list,
+    'START_DAY_SELECTED' => @$_POST['start_day'],
+    'START_MONTH_SELECTED' => @$_POST['start_month'],
+    'END_DAY_SELECTED' => @$_POST['end_day'],
+    'END_MONTH_SELECTED' => @$_POST['end_month'],
+    )
+  );
+
+$available_tags = get_available_tags();
+
+if (count($available_tags) > 0)
+{
+  usort( $available_tags, 'tag_alpha_compare');
+
+  $template->assign(
+    'TAG_SELECTION',
+    get_html_tag_selection(
+        $available_tags,
+        'tags',
+        isset($_POST['tags']) ? $_POST['tags'] : array()
+        )
+    );
+}
+
+//------------------------------------------------------------- categories form
+$query = '
+SELECT id,name,global_rank,uppercats
+  FROM '.CATEGORIES_TABLE.'
+'.get_sql_condition_FandF
+  (
+    array
+      (
+        'forbidden_categories' => 'id',
+        'visible_categories' => 'id'
+      ),
+    'WHERE'
+  ).'
+;';
+display_select_cat_wrapper($query, array(), 'category_options', false);
+
+//-------------------------------------------------------------- errors display
+if (sizeof($errors) != 0)
+{
+  $template->assign('errors', $errors);
+}
+//------------------------------------------------------------ log informations
+include(PHPWG_ROOT_PATH.'include/page_header.php');
+$template->pparse('search');
+include(PHPWG_ROOT_PATH.'include/page_tail.php');
+?>
Index: /tags/2.0.2/search_rules.php
===================================================================
--- /tags/2.0.2/search_rules.php	(revision 3278)
+++ /tags/2.0.2/search_rules.php	(revision 3278)
@@ -0,0 +1,243 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+/**
+ * returns language value 'included' or 'excluded' depending on boolean
+ * value. This function is useful only to make duplicate code shorter
+ *
+ * @param bool is_included
+ * @return string
+ */
+function inc_exc_str($is_included)
+{
+  return $is_included ? l10n('included') : l10n('excluded');
+}
+
+// +-----------------------------------------------------------------------+
+// |                           initialization                              |
+// +-----------------------------------------------------------------------+
+
+define('PHPWG_ROOT_PATH','./');
+include_once( PHPWG_ROOT_PATH.'include/common.inc.php' );
+check_status(ACCESS_FREE);
+include_once( PHPWG_ROOT_PATH.'include/functions_search.inc.php' );
+
+$page['body_id'] = 'thePopuphelpPage';
+$title = l10n('Piwigo Help');
+$page['page_banner'] = '<h1>'.$title.'</h1>';
+$page['meta_robots']=array('noindex'=>1, 'nofollow'=>1);
+include(PHPWG_ROOT_PATH.'include/page_header.php');
+
+$template->set_filenames(array('search_rules' => 'search_rules.tpl'));
+
+// +-----------------------------------------------------------------------+
+// |                        Textual rules creation                         |
+// +-----------------------------------------------------------------------+
+
+// Rules are stored in database, serialized in an array. This array must be
+// transformed into a list of textual rules.
+
+$search = get_search_array($_GET['search_id']);
+
+if (isset($search['q']))
+{
+  $template->append( 'search_words', $search['q'] );
+}
+else
+{
+  $template->assign(
+    array(
+      'INTRODUCTION'
+        => 'OR' == $search['mode']
+        ? l10n('At least one listed rule must be satisfied.')
+        : l10n('Each listed rule must be satisfied.'),
+      )
+    );
+}
+
+if (isset($search['fields']['allwords']))
+{
+  $template->append( 'search_words',
+      sprintf(
+        l10n('searched words : %s'),
+        join(', ', $search['fields']['allwords']['words'])
+        )
+      );
+}
+
+if (isset($search['fields']['tags']))
+{
+  $template->assign('SEARCH_TAGS_MODE', $search['fields']['tags']['mode']);
+  
+  $query = '
+SELECT name
+  FROM '.TAGS_TABLE.'
+  WHERE id IN ('.implode(',', $search['fields']['tags']['words']).')
+;';
+  $template->assign(
+      'search_tags',
+      array_from_query($query, 'name')
+    );
+}
+
+if (isset($search['fields']['author']))
+{
+  $template->append(
+    'search_words',
+     sprintf(
+          l10n('author(s) : %s'),
+          join(', ', $search['fields']['author']['words'])
+        )
+      );
+}
+
+if (isset($search['fields']['cat']))
+{
+  if ($search['fields']['cat']['sub_inc'])
+  {
+    // searching all the categories id of sub-categories
+    $cat_ids = get_subcat_ids($search['fields']['cat']['words']);
+  }
+  else
+  {
+    $cat_ids = $search['fields']['cat']['words'];
+  }
+
+  $query = '
+SELECT id, uppercats, global_rank
+  FROM '.CATEGORIES_TABLE.'
+  WHERE id IN ('.
+    implode(',', $cat_ids).
+    ')
+;';
+  $result = pwg_query($query);
+
+  $categories = array();
+  if (!empty($result))
+  {
+    while ($row = mysql_fetch_array($result))
+    {
+      array_push($categories, $row);
+    }
+  }
+  usort($categories, 'global_rank_compare');
+
+  foreach ($categories as $category)
+  {
+    $template->append(
+      'search_categories',
+      get_cat_display_name_cache(
+          $category['uppercats'],
+          null,                      // no url on category names
+          false                    // no blank replacement
+          )
+      );
+  }
+}
+
+foreach (array('date_available', 'date_creation') as $datefield)
+{
+  if ('date_available' == $datefield)
+  {
+    $lang_items = array(
+      'date'   => 'became available on %s',
+      'period' => 'became available between %s (%s) and %s (%s)',
+      'after'  => 'became available after %s (%s)',
+      'before' => 'became available before %s (%s)',
+      );
+  }
+  elseif ('date_creation' == $datefield)
+  {
+    $lang_items = array(
+      'date'   => 'created on %s',
+      'period' => 'created between %s (%s) and %s (%s)',
+      'after'  => 'created after %s (%s)',
+      'before' => 'created before %s (%s)',
+      );
+  }
+
+  $keys = array(
+    'date'   => $datefield,
+    'after'  => $datefield.'-after',
+    'before' => $datefield.'-before',
+    );
+
+  if (isset($search['fields'][ $keys['date'] ]))
+  {
+    $template->assign(
+      strtoupper($datefield),
+      sprintf(
+          l10n($lang_items['date']),
+          format_date($search['fields'][ $keys['date'] ])
+          )
+      );
+  }
+  elseif (isset($search['fields'][ $keys['before'] ])
+          and isset($search['fields'][ $keys['after'] ]))
+  {
+    $template->assign(
+      strtoupper($datefield),
+      sprintf(
+          l10n($lang_items['period']),
+
+          format_date($search['fields'][ $keys['after'] ]['date']),
+          inc_exc_str($search['fields'][ $keys['after'] ]['inc']),
+
+          format_date($search['fields'][ $keys['before'] ]['date']),
+          inc_exc_str($search['fields'][ $keys['before'] ]['inc'])
+          )
+      );
+  }
+  elseif (isset($search['fields'][ $keys['before'] ]))
+  {
+    $template->assign(
+      strtoupper($datefield),
+      sprintf(
+          l10n($lang_items['before']),
+
+          format_date($search['fields'][ $keys['before'] ]['date']),
+          inc_exc_str($search['fields'][ $keys['before'] ]['inc'])
+          )
+      );
+  }
+  elseif (isset($search['fields'][ $keys['after'] ]))
+  {
+    $template->assign(
+      strtoupper($datefield),
+      sprintf(
+          l10n($lang_items['after']),
+
+          format_date($search['fields'][ $keys['after'] ]['date']),
+          inc_exc_str($search['fields'][ $keys['after'] ]['inc'])
+          )
+      );
+  }
+}
+
+// +-----------------------------------------------------------------------+
+// |                           html code display                           |
+// +-----------------------------------------------------------------------+
+
+$template->pparse('search_rules');
+include(PHPWG_ROOT_PATH.'include/page_tail.php');
+?>
Index: /tags/2.0.2/tags.php
===================================================================
--- /tags/2.0.2/tags.php	(revision 3278)
+++ /tags/2.0.2/tags.php	(revision 3278)
@@ -0,0 +1,197 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// +-----------------------------------------------------------------------+
+// |                             functions                                 |
+// +-----------------------------------------------------------------------+
+
+function counter_compare($a, $b)
+{
+  if ($a['counter'] == $b['counter'])
+  {
+    return id_compare($a, $b);
+  }
+
+  return ($a['counter'] < $b['counter']) ? +1 : -1;
+}
+
+function id_compare($a, $b)
+{
+  return ($a['id'] < $b['id']) ? -1 : 1;
+}
+
+// +-----------------------------------------------------------------------+
+// |                           initialization                              |
+// +-----------------------------------------------------------------------+
+
+define('PHPWG_ROOT_PATH','./');
+include_once(PHPWG_ROOT_PATH.'include/common.inc.php');
+
+check_status(ACCESS_GUEST);
+
+// +-----------------------------------------------------------------------+
+// |                       page header and options                         |
+// +-----------------------------------------------------------------------+
+
+$title= l10n('Tags');
+$page['body_id'] = 'theTagsPage';
+
+$template->set_filenames(array('tags'=>'tags.tpl'));
+
+$page['display_mode'] = $conf['tags_default_display_mode'];
+if (isset($_GET['display_mode']))
+{
+  if (in_array($_GET['display_mode'], array('cloud', 'letters')))
+  {
+    $page['display_mode'] = $_GET['display_mode'];
+  }
+}
+
+foreach (array('cloud', 'letters') as $mode)
+{
+  $template->assign(
+    'U_'.strtoupper($mode),
+    get_root_url().'tags.php'. ($conf['tags_default_display_mode']==$mode ? '' : '?display_mode='.$mode)
+    );
+}
+
+$template->assign( 'display_mode', $page['display_mode'] );
+
+// find all tags available for the current user
+$tags = get_available_tags();
+
+// +-----------------------------------------------------------------------+
+// |                       letter groups construction                      |
+// +-----------------------------------------------------------------------+
+
+if ($page['display_mode'] == 'letters') {
+  // we want tags diplayed in alphabetic order
+  usort($tags, 'tag_alpha_compare');
+
+  $current_letter = null;
+  $nb_tags = count($tags);
+  $current_column = 1;
+  $current_tag_idx = 0;
+
+  $letter = array(
+    'tags' => array()
+    );
+
+  foreach ($tags as $tag)
+  {
+    $tag_letter = strtoupper(substr($tag['url_name'], 0, 1));
+
+    if ($current_tag_idx==0) {
+      $current_letter = $tag_letter;
+      $letter['TITLE'] = $tag_letter;
+    }
+
+    //lettre precedente differente de la lettre suivante
+    if ($tag_letter !== $current_letter)
+    {
+      if ($current_column<$conf['tag_letters_column_number']
+          and $current_tag_idx > $current_column*$nb_tags/$conf['tag_letters_column_number'] )
+      {
+        $letter['CHANGE_COLUMN'] = true;
+        $current_column++;
+      }
+
+      $letter['TITLE'] = $current_letter;
+
+      $template->append(
+        'letters',
+        $letter
+        );
+
+      $current_letter = $tag_letter;
+      $letter = array(
+        'tags' => array()
+        );
+    }
+
+    array_push(
+      $letter['tags'],
+      array_merge(
+        $tag,
+        array(
+          'URL' => make_index_url(
+            array(
+              'tags' => array($tag),
+              )
+            ),
+          )
+        )
+      );
+
+    $current_tag_idx++;
+  }
+
+  // flush last letter
+  if (count($letter['tags']) > 0)
+  {
+    unset($letter['CHANGE_COLUMN']);
+    $letter['TITLE'] = $current_letter;
+    $template->append(
+      'letters',
+      $letter
+      );
+  }
+}
+
+// +-----------------------------------------------------------------------+
+// |                        tag cloud construction                         |
+// +-----------------------------------------------------------------------+
+
+// we want only the first most represented tags, so we sort them by counter
+// and take the first tags
+usort($tags, 'counter_compare');
+$tags = array_slice($tags, 0, $conf['full_tag_cloud_items_number']);
+
+// depending on its counter and the other tags counter, each tag has a level
+$tags = add_level_to_tags($tags);
+
+// we want tags diplayed in alphabetic order
+usort($tags, 'tag_alpha_compare');
+
+// display sorted tags
+foreach ($tags as $tag)
+{
+  $template->append(
+    'tags',
+    array_merge(
+      $tag,
+      array(
+        'URL' => make_index_url(
+          array(
+            'tags' => array($tag),
+            )
+          ),
+        )
+      )
+    );
+}
+
+include(PHPWG_ROOT_PATH.'include/page_header.php');
+$template->pparse('tags');
+include(PHPWG_ROOT_PATH.'include/page_tail.php');
+?>
Index: /tags/2.0.2/template-common/csshover.htc
===================================================================
--- /tags/2.0.2/template-common/csshover.htc	(revision 3278)
+++ /tags/2.0.2/template-common/csshover.htc	(revision 3278)
@@ -0,0 +1,120 @@
+<attach event="ondocumentready" handler="parseStylesheets" />
+<script>
+/**
+ *	Whatever:hover - V1.42.060206 - hover & active
+ *	------------------------------------------------------------
+ *	(c) 2005 - Peter Nederlof
+ *	Peterned - http://www.xs4all.nl/~peterned/
+ *	License  - http://creativecommons.org/licenses/LGPL/2.1/
+ *
+ *	Whatever:hover is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU Lesser General Public
+ *	License as published by the Free Software Foundation; either
+ *	version 2.1 of the License, or (at your option) any later version.
+ *
+ *	Whatever:hover is distributed in the hope that it will be useful,
+ *	but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ *	Lesser General Public License for more details.
+ *
+ *	Credits and thanks to:
+ *	Arnoud Berendsen, Martin Reurings, Robert Hanson
+ *
+ *	howto: body { behavior:url("csshover.htc"); }
+ *	------------------------------------------------------------
+ */
+
+var csshoverReg = /(^|\s)(([^a]([^ ]+)?)|(a([^#.][^ ]+)+)):(hover|active)/i,
+currentSheet, doc = window.document, hoverEvents = [], activators = {
+	onhover:{on:'onmouseover', off:'onmouseout'},
+	onactive:{on:'onmousedown', off:'onmouseup'}
+}
+
+function parseStylesheets() {
+	if(!/MSIE (5|6)/.test(navigator.userAgent)) return;
+	window.attachEvent('onunload', unhookHoverEvents);
+	var sheets = doc.styleSheets, l = sheets.length;
+	for(var i=0; i<l; i++) 
+		parseStylesheet(sheets[i]);
+}
+	function parseStylesheet(sheet) {
+		if(sheet.imports) {
+			try {
+				var imports = sheet.imports, l = imports.length;
+				for(var i=0; i<l; i++) parseStylesheet(sheet.imports[i]);
+			} catch(securityException){}
+		}
+
+		try {
+			var rules = (currentSheet = sheet).rules, l = rules.length;
+			for(var j=0; j<l; j++) parseCSSRule(rules[j]);
+		} catch(securityException){}
+	}
+
+	function parseCSSRule(rule) {
+		var select = rule.selectorText, style = rule.style.cssText;
+		if(!csshoverReg.test(select) || !style) return;
+
+		var pseudo = select.replace(/[^:]+:([a-z-]+).*/i, 'on$1');
+		var newSelect = select.replace(/(\.([a-z0-9_-]+):[a-z]+)|(:[a-z]+)/gi, '.$2' + pseudo);
+		var className = (/\.([a-z0-9_-]*on(hover|active))/i).exec(newSelect)[1];
+		var affected = select.replace(/:(hover|active).*$/, '');
+		var elements = getElementsBySelect(affected);
+		if(elements.length == 0) return;
+
+		currentSheet.addRule(newSelect, style);
+		for(var i=0; i<elements.length; i++)
+			new HoverElement(elements[i], className, activators[pseudo]);
+	}
+
+function HoverElement(node, className, events) {
+	if(!node.hovers) node.hovers = {};
+	if(node.hovers[className]) return;
+	node.hovers[className] = true;
+	hookHoverEvent(node, events.on, function() { node.className += ' ' + className; });
+	hookHoverEvent(node, events.off, function() { node.className = node.className.replace(new RegExp('\\s+'+className, 'g'),''); });
+}
+	function hookHoverEvent(node, type, handler) {
+		node.attachEvent(type, handler);
+		hoverEvents[hoverEvents.length] = { 
+			node:node, type:type, handler:handler 
+		};
+	}
+
+	function unhookHoverEvents() {
+		for(var e,i=0; i<hoverEvents.length; i++) {
+			e = hoverEvents[i]; 
+			e.node.detachEvent(e.type, e.handler);
+		}
+	}
+
+function getElementsBySelect(rule) {
+	var parts, nodes = [doc];
+	parts = rule.split(' ');
+	for(var i=0; i<parts.length; i++) {
+		nodes = getSelectedNodes(parts[i], nodes);
+	}	return nodes;
+}
+	function getSelectedNodes(select, elements) {
+		var result, node, nodes = [];
+		var identify = (/\#([a-z0-9_-]+)/i).exec(select);
+		if(identify) {
+			var element = doc.getElementById(identify[1]);
+			return element? [element]:nodes;
+		}
+		
+		var classname = (/\.([a-z0-9_-]+)/i).exec(select);
+		var tagName = select.replace(/(\.|\#|\:)[a-z0-9_-]+/i, '');
+		var classReg = classname? new RegExp('\\b' + classname[1] + '\\b'):false;
+		for(var i=0; i<elements.length; i++) {
+			result = tagName? elements[i].all.tags(tagName):elements[i].all; 
+			for(var j=0; j<result.length; j++) {
+				node = result[j];
+				if(classReg && !classReg.test(node.className)) continue;
+				nodes[nodes.length] = node;
+			}
+		}	
+		
+		return nodes;
+	}
+</script>
Index: /tags/2.0.2/template-common/datepicker.js
===================================================================
--- /tags/2.0.2/template-common/datepicker.js	(revision 3278)
+++ /tags/2.0.2/template-common/datepicker.js	(revision 3278)
@@ -0,0 +1,191 @@
+// initialize controls
+// buttonImageName: Directory and name of calendar picture
+// day, month, year: selectors of visible date controls
+// linked_date: selector of hidden linked dates control
+// checked_on_change: selector of control to change "checked" attribut
+// min_linked_date: selector of hidden linked date control witch give min value
+// max_linked_date: selector of hidden linked date control witch give max value
+function pwg_common_initialization_datepicker(buttonImageName, day, month, year, linked_date, checked_on_change, min_linked_date, max_linked_date)
+{
+  // return formated date with control values
+  function pwg_get_fmt_from_ctrls()
+  {
+    return $(year).val() + "-" + $(month).val() + "-" + $(day).val();
+  }
+
+  // return if linked_date is valid date
+  function is_valid_linked_value(linked_date_name)
+  {
+    array_date = $(linked_date_name).val().split('-');
+    return (
+      (array_date.length == 3) &&
+      (array_date[0] != "") &&
+      (array_date[1] != "") && (array_date[1] != "0") &&
+      (array_date[2] != "") && (array_date[2] != "0")
+      )
+  }
+  
+  // Action on change date value
+  function pwg_on_date_change()
+  {
+    pwg_check_date();
+    if (checked_on_change != null)
+    {
+      $(checked_on_change).attr("checked", "true");
+    }
+  }
+
+  // In order to desable element of list
+  function pwg_disabled_selection()
+  {
+    array_date = $(linked_date).val().split('-');
+    y = array_date[0];
+    m = array_date[1];
+
+    // Init list
+    $(day + " option").attr("disabled", "");
+    $(month + " option").attr("disabled", "");
+
+    var daysInMonth = 32 - new Date(y, m - 1, 32).getDate();
+    $(day + " option:gt(" + (daysInMonth) +")").attr("disabled", "disabled");
+
+    if ((min_linked_date != null) && (is_valid_linked_value(min_linked_date) == true))
+    {
+      date_cmp = min_linked_date;
+      op_cmp = "lt";
+    }
+    else if ((max_linked_date != null) && (is_valid_linked_value(max_linked_date) == true))
+    {
+      date_cmp = max_linked_date;
+      op_cmp = "gt";
+    }
+    else
+    {
+      date_cmp = null;
+      op_cmp = null;
+    }
+
+    if (op_cmp != null)
+    {
+      array_date = $(date_cmp).val().split('-');
+      y_cmp = array_date[0];
+      m_cmp = array_date[1];
+      d_cmp = array_date[2];
+      
+      if (y == y_cmp)
+      {
+        $(month + " option:" + op_cmp + "(" + (m_cmp) +")").attr("disabled", "disabled");
+        if (op_cmp ==  "lt")
+        {
+            $(month + " option:eq(" + (0) +")").attr("disabled", "");
+        }
+
+        if (m == m_cmp)
+        {
+          $(day + " option:" + op_cmp + "(" + (d_cmp) +")").attr("disabled", "disabled");
+          if (op_cmp ==  "lt")
+          {
+            $(day + " option:eq(" + (0) +")").attr("disabled", "");
+          }
+        }
+      }
+    }
+  }
+
+  // Prevent selection of invalid dates through the select controls 
+  function pwg_check_date()
+  {
+    last_date = $(linked_date).val();
+
+    $(linked_date).val(pwg_get_fmt_from_ctrls());
+
+    if ((min_linked_date != null) && (is_valid_linked_value(min_linked_date)))
+    {
+      cancel = ($(min_linked_date).datepicker("getDate") > $(linked_date).datepicker("getDate"));
+    }
+    else if ((max_linked_date != null) && (is_valid_linked_value(max_linked_date)))
+    {
+      cancel = ($(max_linked_date).datepicker("getDate") < $(linked_date).datepicker("getDate"));
+    }
+    else
+    {
+      cancel = false;
+    }
+
+    if (cancel)
+    {
+      array_date = last_date.split('-');
+      $(year).val(array_date[0]);
+      $(month).val(array_date[1]);
+      $(day).val(array_date[2]);
+      // check again
+      pwg_check_date();
+    }
+  }
+
+  jQuery().ready(function(){
+    // Init hidden value
+    $(linked_date).val(pwg_get_fmt_from_ctrls());
+
+    // Init Datepicker
+    jQuery(linked_date).datepicker({
+      dateFormat:'yy-m-d',
+      beforeShow:
+        // Prepare to show a date picker linked to three select controls 
+        function readLinked(input) { 
+            if (min_linked_date != null)
+            {
+              return {minDate: $(min_linked_date).datepicker("getDate")};
+            }
+            else if (max_linked_date != null)
+            {
+              return {maxDate: $(max_linked_date).datepicker("getDate")};
+            }
+            else
+            {
+              return {};
+            }
+        },
+      onSelect:
+        // Update three select controls to match a date picker selection 
+        function updateLinked(date) {
+            if (date.length == 0)
+            {
+              $(year).val("");
+              $(month).val("0");
+              $(day).val("0");
+            }
+            else
+            {
+              array_date = date.split('-');
+              $(year).val(array_date[0]);
+              $(month).val(array_date[1]);
+              $(day).val(array_date[2]);
+            }
+            pwg_on_date_change();
+        },
+      showOn: "both",
+      buttonImage: buttonImageName,
+      buttonImageOnly: true,
+      buttonText: ""
+      });
+
+    // Check showed controls
+    jQuery(day + ", " + month + ", " + year).change(
+      function ()
+      {
+        pwg_on_date_change();
+      });
+
+    // Check showed controls
+    jQuery(day + ", " + month + ", " + year).focus(
+      function ()
+      {
+        pwg_disabled_selection();
+      });
+
+    // In order to init linked input
+    pwg_check_date();
+   });
+
+}
Index: /tags/2.0.2/template-common/default-layout.css
===================================================================
--- /tags/2.0.2/template-common/default-layout.css	(revision 3278)
+++ /tags/2.0.2/template-common/default-layout.css	(revision 3278)
@@ -0,0 +1,42 @@
+/* $Id$ */
+
+/* Set the width of the menubar for the galery */
+#menubar {
+  width: 18em;
+}
+.content {
+  margin-left: 20em;  /* = #menubar width + 2em */
+}
+/* Set minimum width of the page before getting a scrollbar */
+/* IE5 and IE6 don't get that */
+BODY {
+  min-width: 60em;  /* ~ 3* #menubar width */
+}
+BODY#thePopuphelpPage {
+  min-width: 0;
+}
+
+/* Set some sizes according to your maximum thumbnail width and height */
+.content UL.thumbnails SPAN,
+.content UL.thumbnails SPAN.wrap2 A,
+.content UL.thumbnails LABEL,
+.content DIV.thumbnailCategory DIV.illustration {
+  width: 140px;      /* max thumbnail width + 2px */
+}
+.content UL.thumbnails SPAN.wrap2,
+.content DIV.thumbnailCategory DIV.description {
+  height: 140px;    /* max thumbnail height + 2px */
+}
+
+
+/* Category thumbnails on main page */
+.content UL.thumbnailCategories LI {
+  width: 49.7%;    /* 49.7% for 2 per line, 33.2% for 3 per line*/
+}
+
+/* Set defaults for thumbnails legend */
+.content UL.thumbnails SPAN.thumbLegend {
+  display: block;  /* display: none; if you don't want legend */
+  height: 4em;    /* legend height (don't set auto to be Gecko friendly)*/
+}
+
Index: /tags/2.0.2/template-common/index.php
===================================================================
--- /tags/2.0.2/template-common/index.php	(revision 3278)
+++ /tags/2.0.2/template-common/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/template-common/inputfix.htc
===================================================================
--- /tags/2.0.2/template-common/inputfix.htc	(revision 3278)
+++ /tags/2.0.2/template-common/inputfix.htc	(revision 3278)
@@ -0,0 +1,42 @@
+<public:attach event="oncontentready"  onevent="fixElements()" />
+
+<script langage=javascript>
+
+function setFocusStyle()
+{
+  window.event.srcElement.className += ' focus';
+}
+
+function setBlurStyle()
+{
+  window.event.srcElement.className = window.event.srcElement.className.replace( ' focus', ' nofocus');
+}
+
+function setClassFromType()
+{
+  this.className += ' ' + this.type;
+}
+
+function fixElements()
+{
+  for ( var i=0; i<this.elements.length; i++ )
+  {
+    var elem=this.elements[i];
+    switch ( elem.tagName )
+    {
+      case "INPUT":
+        elem.className += ' ' + elem.type;
+        if ( (elem.type != "radio") && (elem.type != "checkbox") )
+        { /* setting focus/nofocus on those is a mess to handle in css */
+          elem.attachEvent( 'onfocus', setFocusStyle );
+          elem.attachEvent( 'onblur', setBlurStyle );
+        }
+      break;
+      case "SELECT":
+      case "TEXTAREA":
+        elem.attachEvent( 'onfocus', setFocusStyle );
+        elem.attachEvent( 'onblur', setBlurStyle );
+    }
+  }
+}
+</script>
Index: /tags/2.0.2/template-common/lib/jquery.js
===================================================================
--- /tags/2.0.2/template-common/lib/jquery.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/jquery.js	(revision 3278)
@@ -0,0 +1,3549 @@
+(function(){
+/*
+ * jQuery 1.2.6 - New Wave Javascript
+ *
+ * Copyright (c) 2008 John Resig (jquery.com)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * $Date$
+ * $Rev$
+ */
+
+// Map over jQuery in case of overwrite
+var _jQuery = window.jQuery,
+// Map over the $ in case of overwrite
+	_$ = window.$;
+
+var jQuery = window.jQuery = window.$ = function( selector, context ) {
+	// The jQuery object is actually just the init constructor 'enhanced'
+	return new jQuery.fn.init( selector, context );
+};
+
+// A simple way to check for HTML strings or ID strings
+// (both of which we optimize for)
+var quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/,
+
+// Is it a simple selector
+	isSimple = /^.[^:#\[\.]*$/,
+
+// Will speed up references to undefined, and allows munging its name.
+	undefined;
+
+jQuery.fn = jQuery.prototype = {
+	init: function( selector, context ) {
+		// Make sure that a selection was provided
+		selector = selector || document;
+
+		// Handle $(DOMElement)
+		if ( selector.nodeType ) {
+			this[0] = selector;
+			this.length = 1;
+			return this;
+		}
+		// Handle HTML strings
+		if ( typeof selector == "string" ) {
+			// Are we dealing with HTML string or an ID?
+			var match = quickExpr.exec( selector );
+
+			// Verify a match, and that no context was specified for #id
+			if ( match && (match[1] || !context) ) {
+
+				// HANDLE: $(html) -> $(array)
+				if ( match[1] )
+					selector = jQuery.clean( [ match[1] ], context );
+
+				// HANDLE: $("#id")
+				else {
+					var elem = document.getElementById( match[3] );
+
+					// Make sure an element was located
+					if ( elem ){
+						// Handle the case where IE and Opera return items
+						// by name instead of ID
+						if ( elem.id != match[3] )
+							return jQuery().find( selector );
+
+						// Otherwise, we inject the element directly into the jQuery object
+						return jQuery( elem );
+					}
+					selector = [];
+				}
+
+			// HANDLE: $(expr, [context])
+			// (which is just equivalent to: $(content).find(expr)
+			} else
+				return jQuery( context ).find( selector );
+
+		// HANDLE: $(function)
+		// Shortcut for document ready
+		} else if ( jQuery.isFunction( selector ) )
+			return jQuery( document )[ jQuery.fn.ready ? "ready" : "load" ]( selector );
+
+		return this.setArray(jQuery.makeArray(selector));
+	},
+
+	// The current version of jQuery being used
+	jquery: "1.2.6",
+
+	// The number of elements contained in the matched element set
+	size: function() {
+		return this.length;
+	},
+
+	// The number of elements contained in the matched element set
+	length: 0,
+
+	// Get the Nth element in the matched element set OR
+	// Get the whole matched element set as a clean array
+	get: function( num ) {
+		return num == undefined ?
+
+			// Return a 'clean' array
+			jQuery.makeArray( this ) :
+
+			// Return just the object
+			this[ num ];
+	},
+
+	// Take an array of elements and push it onto the stack
+	// (returning the new matched element set)
+	pushStack: function( elems ) {
+		// Build a new jQuery matched element set
+		var ret = jQuery( elems );
+
+		// Add the old object onto the stack (as a reference)
+		ret.prevObject = this;
+
+		// Return the newly-formed element set
+		return ret;
+	},
+
+	// Force the current matched set of elements to become
+	// the specified array of elements (destroying the stack in the process)
+	// You should use pushStack() in order to do this, but maintain the stack
+	setArray: function( elems ) {
+		// Resetting the length to 0, then using the native Array push
+		// is a super-fast way to populate an object with array-like properties
+		this.length = 0;
+		Array.prototype.push.apply( this, elems );
+
+		return this;
+	},
+
+	// Execute a callback for every element in the matched set.
+	// (You can seed the arguments with an array of args, but this is
+	// only used internally.)
+	each: function( callback, args ) {
+		return jQuery.each( this, callback, args );
+	},
+
+	// Determine the position of an element within
+	// the matched set of elements
+	index: function( elem ) {
+		var ret = -1;
+
+		// Locate the position of the desired element
+		return jQuery.inArray(
+			// If it receives a jQuery object, the first element is used
+			elem && elem.jquery ? elem[0] : elem
+		, this );
+	},
+
+	attr: function( name, value, type ) {
+		var options = name;
+
+		// Look for the case where we're accessing a style value
+		if ( name.constructor == String )
+			if ( value === undefined )
+				return this[0] && jQuery[ type || "attr" ]( this[0], name );
+
+			else {
+				options = {};
+				options[ name ] = value;
+			}
+
+		// Check to see if we're setting style values
+		return this.each(function(i){
+			// Set all the styles
+			for ( name in options )
+				jQuery.attr(
+					type ?
+						this.style :
+						this,
+					name, jQuery.prop( this, options[ name ], type, i, name )
+				);
+		});
+	},
+
+	css: function( key, value ) {
+		// ignore negative width and height values
+		if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 )
+			value = undefined;
+		return this.attr( key, value, "curCSS" );
+	},
+
+	text: function( text ) {
+		if ( typeof text != "object" && text != null )
+			return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
+
+		var ret = "";
+
+		jQuery.each( text || this, function(){
+			jQuery.each( this.childNodes, function(){
+				if ( this.nodeType != 8 )
+					ret += this.nodeType != 1 ?
+						this.nodeValue :
+						jQuery.fn.text( [ this ] );
+			});
+		});
+
+		return ret;
+	},
+
+	wrapAll: function( html ) {
+		if ( this[0] )
+			// The elements to wrap the target around
+			jQuery( html, this[0].ownerDocument )
+				.clone()
+				.insertBefore( this[0] )
+				.map(function(){
+					var elem = this;
+
+					while ( elem.firstChild )
+						elem = elem.firstChild;
+
+					return elem;
+				})
+				.append(this);
+
+		return this;
+	},
+
+	wrapInner: function( html ) {
+		return this.each(function(){
+			jQuery( this ).contents().wrapAll( html );
+		});
+	},
+
+	wrap: function( html ) {
+		return this.each(function(){
+			jQuery( this ).wrapAll( html );
+		});
+	},
+
+	append: function() {
+		return this.domManip(arguments, true, false, function(elem){
+			if (this.nodeType == 1)
+				this.appendChild( elem );
+		});
+	},
+
+	prepend: function() {
+		return this.domManip(arguments, true, true, function(elem){
+			if (this.nodeType == 1)
+				this.insertBefore( elem, this.firstChild );
+		});
+	},
+
+	before: function() {
+		return this.domManip(arguments, false, false, function(elem){
+			this.parentNode.insertBefore( elem, this );
+		});
+	},
+
+	after: function() {
+		return this.domManip(arguments, false, true, function(elem){
+			this.parentNode.insertBefore( elem, this.nextSibling );
+		});
+	},
+
+	end: function() {
+		return this.prevObject || jQuery( [] );
+	},
+
+	find: function( selector ) {
+		var elems = jQuery.map(this, function(elem){
+			return jQuery.find( selector, elem );
+		});
+
+		return this.pushStack( /[^+>] [^+>]/.test( selector ) || selector.indexOf("..") > -1 ?
+			jQuery.unique( elems ) :
+			elems );
+	},
+
+	clone: function( events ) {
+		// Do the clone
+		var ret = this.map(function(){
+			if ( jQuery.browser.msie && !jQuery.isXMLDoc(this) ) {
+				// IE copies events bound via attachEvent when
+				// using cloneNode. Calling detachEvent on the
+				// clone will also remove the events from the orignal
+				// In order to get around this, we use innerHTML.
+				// Unfortunately, this means some modifications to
+				// attributes in IE that are actually only stored
+				// as properties will not be copied (such as the
+				// the name attribute on an input).
+				var clone = this.cloneNode(true),
+					container = document.createElement("div");
+				container.appendChild(clone);
+				return jQuery.clean([container.innerHTML])[0];
+			} else
+				return this.cloneNode(true);
+		});
+
+		// Need to set the expando to null on the cloned set if it exists
+		// removeData doesn't work here, IE removes it from the original as well
+		// this is primarily for IE but the data expando shouldn't be copied over in any browser
+		var clone = ret.find("*").andSelf().each(function(){
+			if ( this[ expando ] != undefined )
+				this[ expando ] = null;
+		});
+
+		// Copy the events from the original to the clone
+		if ( events === true )
+			this.find("*").andSelf().each(function(i){
+				if (this.nodeType == 3)
+					return;
+				var events = jQuery.data( this, "events" );
+
+				for ( var type in events )
+					for ( var handler in events[ type ] )
+						jQuery.event.add( clone[ i ], type, events[ type ][ handler ], events[ type ][ handler ].data );
+			});
+
+		// Return the cloned set
+		return ret;
+	},
+
+	filter: function( selector ) {
+		return this.pushStack(
+			jQuery.isFunction( selector ) &&
+			jQuery.grep(this, function(elem, i){
+				return selector.call( elem, i );
+			}) ||
+
+			jQuery.multiFilter( selector, this ) );
+	},
+
+	not: function( selector ) {
+		if ( selector.constructor == String )
+			// test special case where just one selector is passed in
+			if ( isSimple.test( selector ) )
+				return this.pushStack( jQuery.multiFilter( selector, this, true ) );
+			else
+				selector = jQuery.multiFilter( selector, this );
+
+		var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType;
+		return this.filter(function() {
+			return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector;
+		});
+	},
+
+	add: function( selector ) {
+		return this.pushStack( jQuery.unique( jQuery.merge(
+			this.get(),
+			typeof selector == 'string' ?
+				jQuery( selector ) :
+				jQuery.makeArray( selector )
+		)));
+	},
+
+	is: function( selector ) {
+		return !!selector && jQuery.multiFilter( selector, this ).length > 0;
+	},
+
+	hasClass: function( selector ) {
+		return this.is( "." + selector );
+	},
+
+	val: function( value ) {
+		if ( value == undefined ) {
+
+			if ( this.length ) {
+				var elem = this[0];
+
+				// We need to handle select boxes special
+				if ( jQuery.nodeName( elem, "select" ) ) {
+					var index = elem.selectedIndex,
+						values = [],
+						options = elem.options,
+						one = elem.type == "select-one";
+
+					// Nothing was selected
+					if ( index < 0 )
+						return null;
+
+					// Loop through all the selected options
+					for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
+						var option = options[ i ];
+
+						if ( option.selected ) {
+							// Get the specifc value for the option
+							value = jQuery.browser.msie && !option.attributes.value.specified ? option.text : option.value;
+
+							// We don't need an array for one selects
+							if ( one )
+								return value;
+
+							// Multi-Selects return an array
+							values.push( value );
+						}
+					}
+
+					return values;
+
+				// Everything else, we just grab the value
+				} else
+					return (this[0].value || "").replace(/\r/g, "");
+
+			}
+
+			return undefined;
+		}
+
+		if( value.constructor == Number )
+			value += '';
+
+		return this.each(function(){
+			if ( this.nodeType != 1 )
+				return;
+
+			if ( value.constructor == Array && /radio|checkbox/.test( this.type ) )
+				this.checked = (jQuery.inArray(this.value, value) >= 0 ||
+					jQuery.inArray(this.name, value) >= 0);
+
+			else if ( jQuery.nodeName( this, "select" ) ) {
+				var values = jQuery.makeArray(value);
+
+				jQuery( "option", this ).each(function(){
+					this.selected = (jQuery.inArray( this.value, values ) >= 0 ||
+						jQuery.inArray( this.text, values ) >= 0);
+				});
+
+				if ( !values.length )
+					this.selectedIndex = -1;
+
+			} else
+				this.value = value;
+		});
+	},
+
+	html: function( value ) {
+		return value == undefined ?
+			(this[0] ?
+				this[0].innerHTML :
+				null) :
+			this.empty().append( value );
+	},
+
+	replaceWith: function( value ) {
+		return this.after( value ).remove();
+	},
+
+	eq: function( i ) {
+		return this.slice( i, i + 1 );
+	},
+
+	slice: function() {
+		return this.pushStack( Array.prototype.slice.apply( this, arguments ) );
+	},
+
+	map: function( callback ) {
+		return this.pushStack( jQuery.map(this, function(elem, i){
+			return callback.call( elem, i, elem );
+		}));
+	},
+
+	andSelf: function() {
+		return this.add( this.prevObject );
+	},
+
+	data: function( key, value ){
+		var parts = key.split(".");
+		parts[1] = parts[1] ? "." + parts[1] : "";
+
+		if ( value === undefined ) {
+			var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
+
+			if ( data === undefined && this.length )
+				data = jQuery.data( this[0], key );
+
+			return data === undefined && parts[1] ?
+				this.data( parts[0] ) :
+				data;
+		} else
+			return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){
+				jQuery.data( this, key, value );
+			});
+	},
+
+	removeData: function( key ){
+		return this.each(function(){
+			jQuery.removeData( this, key );
+		});
+	},
+
+	domManip: function( args, table, reverse, callback ) {
+		var clone = this.length > 1, elems;
+
+		return this.each(function(){
+			if ( !elems ) {
+				elems = jQuery.clean( args, this.ownerDocument );
+
+				if ( reverse )
+					elems.reverse();
+			}
+
+			var obj = this;
+
+			if ( table && jQuery.nodeName( this, "table" ) && jQuery.nodeName( elems[0], "tr" ) )
+				obj = this.getElementsByTagName("tbody")[0] || this.appendChild( this.ownerDocument.createElement("tbody") );
+
+			var scripts = jQuery( [] );
+
+			jQuery.each(elems, function(){
+				var elem = clone ?
+					jQuery( this ).clone( true )[0] :
+					this;
+
+				// execute all scripts after the elements have been injected
+				if ( jQuery.nodeName( elem, "script" ) )
+					scripts = scripts.add( elem );
+				else {
+					// Remove any inner scripts for later evaluation
+					if ( elem.nodeType == 1 )
+						scripts = scripts.add( jQuery( "script", elem ).remove() );
+
+					// Inject the elements into the document
+					callback.call( obj, elem );
+				}
+			});
+
+			scripts.each( evalScript );
+		});
+	}
+};
+
+// Give the init function the jQuery prototype for later instantiation
+jQuery.fn.init.prototype = jQuery.fn;
+
+function evalScript( i, elem ) {
+	if ( elem.src )
+		jQuery.ajax({
+			url: elem.src,
+			async: false,
+			dataType: "script"
+		});
+
+	else
+		jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
+
+	if ( elem.parentNode )
+		elem.parentNode.removeChild( elem );
+}
+
+function now(){
+	return +new Date;
+}
+
+jQuery.extend = jQuery.fn.extend = function() {
+	// copy reference to target object
+	var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;
+
+	// Handle a deep copy situation
+	if ( target.constructor == Boolean ) {
+		deep = target;
+		target = arguments[1] || {};
+		// skip the boolean and the target
+		i = 2;
+	}
+
+	// Handle case when target is a string or something (possible in deep copy)
+	if ( typeof target != "object" && typeof target != "function" )
+		target = {};
+
+	// extend jQuery itself if only one argument is passed
+	if ( length == i ) {
+		target = this;
+		--i;
+	}
+
+	for ( ; i < length; i++ )
+		// Only deal with non-null/undefined values
+		if ( (options = arguments[ i ]) != null )
+			// Extend the base object
+			for ( var name in options ) {
+				var src = target[ name ], copy = options[ name ];
+
+				// Prevent never-ending loop
+				if ( target === copy )
+					continue;
+
+				// Recurse if we're merging object values
+				if ( deep && copy && typeof copy == "object" && !copy.nodeType )
+					target[ name ] = jQuery.extend( deep, 
+						// Never move original objects, clone them
+						src || ( copy.length != null ? [ ] : { } )
+					, copy );
+
+				// Don't bring in undefined values
+				else if ( copy !== undefined )
+					target[ name ] = copy;
+
+			}
+
+	// Return the modified object
+	return target;
+};
+
+var expando = "jQuery" + now(), uuid = 0, windowData = {},
+	// exclude the following css properties to add px
+	exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i,
+	// cache defaultView
+	defaultView = document.defaultView || {};
+
+jQuery.extend({
+	noConflict: function( deep ) {
+		window.$ = _$;
+
+		if ( deep )
+			window.jQuery = _jQuery;
+
+		return jQuery;
+	},
+
+	// See test/unit/core.js for details concerning this function.
+	isFunction: function( fn ) {
+		return !!fn && typeof fn != "string" && !fn.nodeName &&
+			fn.constructor != Array && /^[\s[]?function/.test( fn + "" );
+	},
+
+	// check if an element is in a (or is an) XML document
+	isXMLDoc: function( elem ) {
+		return elem.documentElement && !elem.body ||
+			elem.tagName && elem.ownerDocument && !elem.ownerDocument.body;
+	},
+
+	// Evalulates a script in a global context
+	globalEval: function( data ) {
+		data = jQuery.trim( data );
+
+		if ( data ) {
+			// Inspired by code by Andrea Giammarchi
+			// http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
+			var head = document.getElementsByTagName("head")[0] || document.documentElement,
+				script = document.createElement("script");
+
+			script.type = "text/javascript";
+			if ( jQuery.browser.msie )
+				script.text = data;
+			else
+				script.appendChild( document.createTextNode( data ) );
+
+			// Use insertBefore instead of appendChild  to circumvent an IE6 bug.
+			// This arises when a base node is used (#2709).
+			head.insertBefore( script, head.firstChild );
+			head.removeChild( script );
+		}
+	},
+
+	nodeName: function( elem, name ) {
+		return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase();
+	},
+
+	cache: {},
+
+	data: function( elem, name, data ) {
+		elem = elem == window ?
+			windowData :
+			elem;
+
+		var id = elem[ expando ];
+
+		// Compute a unique ID for the element
+		if ( !id )
+			id = elem[ expando ] = ++uuid;
+
+		// Only generate the data cache if we're
+		// trying to access or manipulate it
+		if ( name && !jQuery.cache[ id ] )
+			jQuery.cache[ id ] = {};
+
+		// Prevent overriding the named cache with undefined values
+		if ( data !== undefined )
+			jQuery.cache[ id ][ name ] = data;
+
+		// Return the named cache data, or the ID for the element
+		return name ?
+			jQuery.cache[ id ][ name ] :
+			id;
+	},
+
+	removeData: function( elem, name ) {
+		elem = elem == window ?
+			windowData :
+			elem;
+
+		var id = elem[ expando ];
+
+		// If we want to remove a specific section of the element's data
+		if ( name ) {
+			if ( jQuery.cache[ id ] ) {
+				// Remove the section of cache data
+				delete jQuery.cache[ id ][ name ];
+
+				// If we've removed all the data, remove the element's cache
+				name = "";
+
+				for ( name in jQuery.cache[ id ] )
+					break;
+
+				if ( !name )
+					jQuery.removeData( elem );
+			}
+
+		// Otherwise, we want to remove all of the element's data
+		} else {
+			// Clean up the element expando
+			try {
+				delete elem[ expando ];
+			} catch(e){
+				// IE has trouble directly removing the expando
+				// but it's ok with using removeAttribute
+				if ( elem.removeAttribute )
+					elem.removeAttribute( expando );
+			}
+
+			// Completely remove the data cache
+			delete jQuery.cache[ id ];
+		}
+	},
+
+	// args is for internal usage only
+	each: function( object, callback, args ) {
+		var name, i = 0, length = object.length;
+
+		if ( args ) {
+			if ( length == undefined ) {
+				for ( name in object )
+					if ( callback.apply( object[ name ], args ) === false )
+						break;
+			} else
+				for ( ; i < length; )
+					if ( callback.apply( object[ i++ ], args ) === false )
+						break;
+
+		// A special, fast, case for the most common use of each
+		} else {
+			if ( length == undefined ) {
+				for ( name in object )
+					if ( callback.call( object[ name ], name, object[ name ] ) === false )
+						break;
+			} else
+				for ( var value = object[0];
+					i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}
+		}
+
+		return object;
+	},
+
+	prop: function( elem, value, type, i, name ) {
+		// Handle executable functions
+		if ( jQuery.isFunction( value ) )
+			value = value.call( elem, i );
+
+		// Handle passing in a number to a CSS property
+		return value && value.constructor == Number && type == "curCSS" && !exclude.test( name ) ?
+			value + "px" :
+			value;
+	},
+
+	className: {
+		// internal only, use addClass("class")
+		add: function( elem, classNames ) {
+			jQuery.each((classNames || "").split(/\s+/), function(i, className){
+				if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) )
+					elem.className += (elem.className ? " " : "") + className;
+			});
+		},
+
+		// internal only, use removeClass("class")
+		remove: function( elem, classNames ) {
+			if (elem.nodeType == 1)
+				elem.className = classNames != undefined ?
+					jQuery.grep(elem.className.split(/\s+/), function(className){
+						return !jQuery.className.has( classNames, className );
+					}).join(" ") :
+					"";
+		},
+
+		// internal only, use hasClass("class")
+		has: function( elem, className ) {
+			return jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1;
+		}
+	},
+
+	// A method for quickly swapping in/out CSS properties to get correct calculations
+	swap: function( elem, options, callback ) {
+		var old = {};
+		// Remember the old values, and insert the new ones
+		for ( var name in options ) {
+			old[ name ] = elem.style[ name ];
+			elem.style[ name ] = options[ name ];
+		}
+
+		callback.call( elem );
+
+		// Revert the old values
+		for ( var name in options )
+			elem.style[ name ] = old[ name ];
+	},
+
+	css: function( elem, name, force ) {
+		if ( name == "width" || name == "height" ) {
+			var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ];
+
+			function getWH() {
+				val = name == "width" ? elem.offsetWidth : elem.offsetHeight;
+				var padding = 0, border = 0;
+				jQuery.each( which, function() {
+					padding += parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
+					border += parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
+				});
+				val -= Math.round(padding + border);
+			}
+
+			if ( jQuery(elem).is(":visible") )
+				getWH();
+			else
+				jQuery.swap( elem, props, getWH );
+
+			return Math.max(0, val);
+		}
+
+		return jQuery.curCSS( elem, name, force );
+	},
+
+	curCSS: function( elem, name, force ) {
+		var ret, style = elem.style;
+
+		// A helper method for determining if an element's values are broken
+		function color( elem ) {
+			if ( !jQuery.browser.safari )
+				return false;
+
+			// defaultView is cached
+			var ret = defaultView.getComputedStyle( elem, null );
+			return !ret || ret.getPropertyValue("color") == "";
+		}
+
+		// We need to handle opacity special in IE
+		if ( name == "opacity" && jQuery.browser.msie ) {
+			ret = jQuery.attr( style, "opacity" );
+
+			return ret == "" ?
+				"1" :
+				ret;
+		}
+		// Opera sometimes will give the wrong display answer, this fixes it, see #2037
+		if ( jQuery.browser.opera && name == "display" ) {
+			var save = style.outline;
+			style.outline = "0 solid black";
+			style.outline = save;
+		}
+
+		// Make sure we're using the right name for getting the float value
+		if ( name.match( /float/i ) )
+			name = styleFloat;
+
+		if ( !force && style && style[ name ] )
+			ret = style[ name ];
+
+		else if ( defaultView.getComputedStyle ) {
+
+			// Only "float" is needed here
+			if ( name.match( /float/i ) )
+				name = "float";
+
+			name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase();
+
+			var computedStyle = defaultView.getComputedStyle( elem, null );
+
+			if ( computedStyle && !color( elem ) )
+				ret = computedStyle.getPropertyValue( name );
+
+			// If the element isn't reporting its values properly in Safari
+			// then some display: none elements are involved
+			else {
+				var swap = [], stack = [], a = elem, i = 0;
+
+				// Locate all of the parent display: none elements
+				for ( ; a && color(a); a = a.parentNode )
+					stack.unshift(a);
+
+				// Go through and make them visible, but in reverse
+				// (It would be better if we knew the exact display type that they had)
+				for ( ; i < stack.length; i++ )
+					if ( color( stack[ i ] ) ) {
+						swap[ i ] = stack[ i ].style.display;
+						stack[ i ].style.display = "block";
+					}
+
+				// Since we flip the display style, we have to handle that
+				// one special, otherwise get the value
+				ret = name == "display" && swap[ stack.length - 1 ] != null ?
+					"none" :
+					( computedStyle && computedStyle.getPropertyValue( name ) ) || "";
+
+				// Finally, revert the display styles back
+				for ( i = 0; i < swap.length; i++ )
+					if ( swap[ i ] != null )
+						stack[ i ].style.display = swap[ i ];
+			}
+
+			// We should always get a number back from opacity
+			if ( name == "opacity" && ret == "" )
+				ret = "1";
+
+		} else if ( elem.currentStyle ) {
+			var camelCase = name.replace(/\-(\w)/g, function(all, letter){
+				return letter.toUpperCase();
+			});
+
+			ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];
+
+			// From the awesome hack by Dean Edwards
+			// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
+
+			// If we're not dealing with a regular pixel number
+			// but a number that has a weird ending, we need to convert it to pixels
+			if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) {
+				// Remember the original values
+				var left = style.left, rsLeft = elem.runtimeStyle.left;
+
+				// Put in the new values to get a computed value out
+				elem.runtimeStyle.left = elem.currentStyle.left;
+				style.left = ret || 0;
+				ret = style.pixelLeft + "px";
+
+				// Revert the changed values
+				style.left = left;
+				elem.runtimeStyle.left = rsLeft;
+			}
+		}
+
+		return ret;
+	},
+
+	clean: function( elems, context ) {
+		var ret = [];
+		context = context || document;
+		// !context.createElement fails in IE with an error but returns typeof 'object'
+		if (typeof context.createElement == 'undefined')
+			context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
+
+		jQuery.each(elems, function(i, elem){
+			if ( !elem )
+				return;
+
+			if ( elem.constructor == Number )
+				elem += '';
+
+			// Convert html string into DOM nodes
+			if ( typeof elem == "string" ) {
+				// Fix "XHTML"-style tags in all browsers
+				elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){
+					return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ?
+						all :
+						front + "></" + tag + ">";
+				});
+
+				// Trim whitespace, otherwise indexOf won't work as expected
+				var tags = jQuery.trim( elem ).toLowerCase(), div = context.createElement("div");
+
+				var wrap =
+					// option or optgroup
+					!tags.indexOf("<opt") &&
+					[ 1, "<select multiple='multiple'>", "</select>" ] ||
+
+					!tags.indexOf("<leg") &&
+					[ 1, "<fieldset>", "</fieldset>" ] ||
+
+					tags.match(/^<(thead|tbody|tfoot|colg|cap)/) &&
+					[ 1, "<table>", "</table>" ] ||
+
+					!tags.indexOf("<tr") &&
+					[ 2, "<table><tbody>", "</tbody></table>" ] ||
+
+				 	// <thead> matched above
+					(!tags.indexOf("<td") || !tags.indexOf("<th")) &&
+					[ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] ||
+
+					!tags.indexOf("<col") &&
+					[ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] ||
+
+					// IE can't serialize <link> and <script> tags normally
+					jQuery.browser.msie &&
+					[ 1, "div<div>", "</div>" ] ||
+
+					[ 0, "", "" ];
+
+				// Go to html and back, then peel off extra wrappers
+				div.innerHTML = wrap[1] + elem + wrap[2];
+
+				// Move to the right depth
+				while ( wrap[0]-- )
+					div = div.lastChild;
+
+				// Remove IE's autoinserted <tbody> from table fragments
+				if ( jQuery.browser.msie ) {
+
+					// String was a <table>, *may* have spurious <tbody>
+					var tbody = !tags.indexOf("<table") && tags.indexOf("<tbody") < 0 ?
+						div.firstChild && div.firstChild.childNodes :
+
+						// String was a bare <thead> or <tfoot>
+						wrap[1] == "<table>" && tags.indexOf("<tbody") < 0 ?
+							div.childNodes :
+							[];
+
+					for ( var j = tbody.length - 1; j >= 0 ; --j )
+						if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length )
+							tbody[ j ].parentNode.removeChild( tbody[ j ] );
+
+					// IE completely kills leading whitespace when innerHTML is used
+					if ( /^\s/.test( elem ) )
+						div.insertBefore( context.createTextNode( elem.match(/^\s*/)[0] ), div.firstChild );
+
+				}
+
+				elem = jQuery.makeArray( div.childNodes );
+			}
+
+			if ( elem.length === 0 && (!jQuery.nodeName( elem, "form" ) && !jQuery.nodeName( elem, "select" )) )
+				return;
+
+			if ( elem[0] == undefined || jQuery.nodeName( elem, "form" ) || elem.options )
+				ret.push( elem );
+
+			else
+				ret = jQuery.merge( ret, elem );
+
+		});
+
+		return ret;
+	},
+
+	attr: function( elem, name, value ) {
+		// don't set attributes on text and comment nodes
+		if (!elem || elem.nodeType == 3 || elem.nodeType == 8)
+			return undefined;
+
+		var notxml = !jQuery.isXMLDoc( elem ),
+			// Whether we are setting (or getting)
+			set = value !== undefined,
+			msie = jQuery.browser.msie;
+
+		// Try to normalize/fix the name
+		name = notxml && jQuery.props[ name ] || name;
+
+		// Only do all the following if this is a node (faster for style)
+		// IE elem.getAttribute passes even for style
+		if ( elem.tagName ) {
+
+			// These attributes require special treatment
+			var special = /href|src|style/.test( name );
+
+			// Safari mis-reports the default selected property of a hidden option
+			// Accessing the parent's selectedIndex property fixes it
+			if ( name == "selected" && jQuery.browser.safari )
+				elem.parentNode.selectedIndex;
+
+			// If applicable, access the attribute via the DOM 0 way
+			if ( name in elem && notxml && !special ) {
+				if ( set ){
+					// We can't allow the type property to be changed (since it causes problems in IE)
+					if ( name == "type" && jQuery.nodeName( elem, "input" ) && elem.parentNode )
+						throw "type property can't be changed";
+
+					elem[ name ] = value;
+				}
+
+				// browsers index elements by id/name on forms, give priority to attributes.
+				if( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) )
+					return elem.getAttributeNode( name ).nodeValue;
+
+				return elem[ name ];
+			}
+
+			if ( msie && notxml &&  name == "style" )
+				return jQuery.attr( elem.style, "cssText", value );
+
+			if ( set )
+				// convert the value to a string (all browsers do this but IE) see #1070
+				elem.setAttribute( name, "" + value );
+
+			var attr = msie && notxml && special
+					// Some attributes require a special call on IE
+					? elem.getAttribute( name, 2 )
+					: elem.getAttribute( name );
+
+			// Non-existent attributes return null, we normalize to undefined
+			return attr === null ? undefined : attr;
+		}
+
+		// elem is actually elem.style ... set the style
+
+		// IE uses filters for opacity
+		if ( msie && name == "opacity" ) {
+			if ( set ) {
+				// IE has trouble with opacity if it does not have layout
+				// Force it by setting the zoom level
+				elem.zoom = 1;
+
+				// Set the alpha filter to set the opacity
+				elem.filter = (elem.filter || "").replace( /alpha\([^)]*\)/, "" ) +
+					(parseInt( value ) + '' == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")");
+			}
+
+			return elem.filter && elem.filter.indexOf("opacity=") >= 0 ?
+				(parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100) + '':
+				"";
+		}
+
+		name = name.replace(/-([a-z])/ig, function(all, letter){
+			return letter.toUpperCase();
+		});
+
+		if ( set )
+			elem[ name ] = value;
+
+		return elem[ name ];
+	},
+
+	trim: function( text ) {
+		return (text || "").replace( /^\s+|\s+$/g, "" );
+	},
+
+	makeArray: function( array ) {
+		var ret = [];
+
+		if( array != null ){
+			var i = array.length;
+			//the window, strings and functions also have 'length'
+			if( i == null || array.split || array.setInterval || array.call )
+				ret[0] = array;
+			else
+				while( i )
+					ret[--i] = array[i];
+		}
+
+		return ret;
+	},
+
+	inArray: function( elem, array ) {
+		for ( var i = 0, length = array.length; i < length; i++ )
+		// Use === because on IE, window == document
+			if ( array[ i ] === elem )
+				return i;
+
+		return -1;
+	},
+
+	merge: function( first, second ) {
+		// We have to loop this way because IE & Opera overwrite the length
+		// expando of getElementsByTagName
+		var i = 0, elem, pos = first.length;
+		// Also, we need to make sure that the correct elements are being returned
+		// (IE returns comment nodes in a '*' query)
+		if ( jQuery.browser.msie ) {
+			while ( elem = second[ i++ ] )
+				if ( elem.nodeType != 8 )
+					first[ pos++ ] = elem;
+
+		} else
+			while ( elem = second[ i++ ] )
+				first[ pos++ ] = elem;
+
+		return first;
+	},
+
+	unique: function( array ) {
+		var ret = [], done = {};
+
+		try {
+
+			for ( var i = 0, length = array.length; i < length; i++ ) {
+				var id = jQuery.data( array[ i ] );
+
+				if ( !done[ id ] ) {
+					done[ id ] = true;
+					ret.push( array[ i ] );
+				}
+			}
+
+		} catch( e ) {
+			ret = array;
+		}
+
+		return ret;
+	},
+
+	grep: function( elems, callback, inv ) {
+		var ret = [];
+
+		// Go through the array, only saving the items
+		// that pass the validator function
+		for ( var i = 0, length = elems.length; i < length; i++ )
+			if ( !inv != !callback( elems[ i ], i ) )
+				ret.push( elems[ i ] );
+
+		return ret;
+	},
+
+	map: function( elems, callback ) {
+		var ret = [];
+
+		// Go through the array, translating each of the items to their
+		// new value (or values).
+		for ( var i = 0, length = elems.length; i < length; i++ ) {
+			var value = callback( elems[ i ], i );
+
+			if ( value != null )
+				ret[ ret.length ] = value;
+		}
+
+		return ret.concat.apply( [], ret );
+	}
+});
+
+var userAgent = navigator.userAgent.toLowerCase();
+
+// Figure out what browser is being used
+jQuery.browser = {
+	version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [])[1],
+	safari: /webkit/.test( userAgent ),
+	opera: /opera/.test( userAgent ),
+	msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ),
+	mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )
+};
+
+var styleFloat = jQuery.browser.msie ?
+	"styleFloat" :
+	"cssFloat";
+
+jQuery.extend({
+	// Check to see if the W3C box model is being used
+	boxModel: !jQuery.browser.msie || document.compatMode == "CSS1Compat",
+
+	props: {
+		"for": "htmlFor",
+		"class": "className",
+		"float": styleFloat,
+		cssFloat: styleFloat,
+		styleFloat: styleFloat,
+		readonly: "readOnly",
+		maxlength: "maxLength",
+		cellspacing: "cellSpacing"
+	}
+});
+
+jQuery.each({
+	parent: function(elem){return elem.parentNode;},
+	parents: function(elem){return jQuery.dir(elem,"parentNode");},
+	next: function(elem){return jQuery.nth(elem,2,"nextSibling");},
+	prev: function(elem){return jQuery.nth(elem,2,"previousSibling");},
+	nextAll: function(elem){return jQuery.dir(elem,"nextSibling");},
+	prevAll: function(elem){return jQuery.dir(elem,"previousSibling");},
+	siblings: function(elem){return jQuery.sibling(elem.parentNode.firstChild,elem);},
+	children: function(elem){return jQuery.sibling(elem.firstChild);},
+	contents: function(elem){return jQuery.nodeName(elem,"iframe")?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes);}
+}, function(name, fn){
+	jQuery.fn[ name ] = function( selector ) {
+		var ret = jQuery.map( this, fn );
+
+		if ( selector && typeof selector == "string" )
+			ret = jQuery.multiFilter( selector, ret );
+
+		return this.pushStack( jQuery.unique( ret ) );
+	};
+});
+
+jQuery.each({
+	appendTo: "append",
+	prependTo: "prepend",
+	insertBefore: "before",
+	insertAfter: "after",
+	replaceAll: "replaceWith"
+}, function(name, original){
+	jQuery.fn[ name ] = function() {
+		var args = arguments;
+
+		return this.each(function(){
+			for ( var i = 0, length = args.length; i < length; i++ )
+				jQuery( args[ i ] )[ original ]( this );
+		});
+	};
+});
+
+jQuery.each({
+	removeAttr: function( name ) {
+		jQuery.attr( this, name, "" );
+		if (this.nodeType == 1)
+			this.removeAttribute( name );
+	},
+
+	addClass: function( classNames ) {
+		jQuery.className.add( this, classNames );
+	},
+
+	removeClass: function( classNames ) {
+		jQuery.className.remove( this, classNames );
+	},
+
+	toggleClass: function( classNames ) {
+		jQuery.className[ jQuery.className.has( this, classNames ) ? "remove" : "add" ]( this, classNames );
+	},
+
+	remove: function( selector ) {
+		if ( !selector || jQuery.filter( selector, [ this ] ).r.length ) {
+			// Prevent memory leaks
+			jQuery( "*", this ).add(this).each(function(){
+				jQuery.event.remove(this);
+				jQuery.removeData(this);
+			});
+			if (this.parentNode)
+				this.parentNode.removeChild( this );
+		}
+	},
+
+	empty: function() {
+		// Remove element nodes and prevent memory leaks
+		jQuery( ">*", this ).remove();
+
+		// Remove any remaining nodes
+		while ( this.firstChild )
+			this.removeChild( this.firstChild );
+	}
+}, function(name, fn){
+	jQuery.fn[ name ] = function(){
+		return this.each( fn, arguments );
+	};
+});
+
+jQuery.each([ "Height", "Width" ], function(i, name){
+	var type = name.toLowerCase();
+
+	jQuery.fn[ type ] = function( size ) {
+		// Get window width or height
+		return this[0] == window ?
+			// Opera reports document.body.client[Width/Height] properly in both quirks and standards
+			jQuery.browser.opera && document.body[ "client" + name ] ||
+
+			// Safari reports inner[Width/Height] just fine (Mozilla and Opera include scroll bar widths)
+			jQuery.browser.safari && window[ "inner" + name ] ||
+
+			// Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
+			document.compatMode == "CSS1Compat" && document.documentElement[ "client" + name ] || document.body[ "client" + name ] :
+
+			// Get document width or height
+			this[0] == document ?
+				// Either scroll[Width/Height] or offset[Width/Height], whichever is greater
+				Math.max(
+					Math.max(document.body["scroll" + name], document.documentElement["scroll" + name]),
+					Math.max(document.body["offset" + name], document.documentElement["offset" + name])
+				) :
+
+				// Get or set width or height on the element
+				size == undefined ?
+					// Get width or height on the element
+					(this.length ? jQuery.css( this[0], type ) : null) :
+
+					// Set the width or height on the element (default to pixels if value is unitless)
+					this.css( type, size.constructor == String ? size : size + "px" );
+	};
+});
+
+// Helper function used by the dimensions and offset modules
+function num(elem, prop) {
+	return elem[0] && parseInt( jQuery.curCSS(elem[0], prop, true), 10 ) || 0;
+}var chars = jQuery.browser.safari && parseInt(jQuery.browser.version) < 417 ?
+		"(?:[\\w*_-]|\\\\.)" :
+		"(?:[\\w\u0128-\uFFFF*_-]|\\\\.)",
+	quickChild = new RegExp("^>\\s*(" + chars + "+)"),
+	quickID = new RegExp("^(" + chars + "+)(#)(" + chars + "+)"),
+	quickClass = new RegExp("^([#.]?)(" + chars + "*)");
+
+jQuery.extend({
+	expr: {
+		"": function(a,i,m){return m[2]=="*"||jQuery.nodeName(a,m[2]);},
+		"#": function(a,i,m){return a.getAttribute("id")==m[2];},
+		":": {
+			// Position Checks
+			lt: function(a,i,m){return i<m[3]-0;},
+			gt: function(a,i,m){return i>m[3]-0;},
+			nth: function(a,i,m){return m[3]-0==i;},
+			eq: function(a,i,m){return m[3]-0==i;},
+			first: function(a,i){return i==0;},
+			last: function(a,i,m,r){return i==r.length-1;},
+			even: function(a,i){return i%2==0;},
+			odd: function(a,i){return i%2;},
+
+			// Child Checks
+			"first-child": function(a){return a.parentNode.getElementsByTagName("*")[0]==a;},
+			"last-child": function(a){return jQuery.nth(a.parentNode.lastChild,1,"previousSibling")==a;},
+			"only-child": function(a){return !jQuery.nth(a.parentNode.lastChild,2,"previousSibling");},
+
+			// Parent Checks
+			parent: function(a){return a.firstChild;},
+			empty: function(a){return !a.firstChild;},
+
+			// Text Check
+			contains: function(a,i,m){return (a.textContent||a.innerText||jQuery(a).text()||"").indexOf(m[3])>=0;},
+
+			// Visibility
+			visible: function(a){return "hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden";},
+			hidden: function(a){return "hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden";},
+
+			// Form attributes
+			enabled: function(a){return !a.disabled;},
+			disabled: function(a){return a.disabled;},
+			checked: function(a){return a.checked;},
+			selected: function(a){return a.selected||jQuery.attr(a,"selected");},
+
+			// Form elements
+			text: function(a){return "text"==a.type;},
+			radio: function(a){return "radio"==a.type;},
+			checkbox: function(a){return "checkbox"==a.type;},
+			file: function(a){return "file"==a.type;},
+			password: function(a){return "password"==a.type;},
+			submit: function(a){return "submit"==a.type;},
+			image: function(a){return "image"==a.type;},
+			reset: function(a){return "reset"==a.type;},
+			button: function(a){return "button"==a.type||jQuery.nodeName(a,"button");},
+			input: function(a){return /input|select|textarea|button/i.test(a.nodeName);},
+
+			// :has()
+			has: function(a,i,m){return jQuery.find(m[3],a).length;},
+
+			// :header
+			header: function(a){return /h\d/i.test(a.nodeName);},
+
+			// :animated
+			animated: function(a){return jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length;}
+		}
+	},
+
+	// The regular expressions that power the parsing engine
+	parse: [
+		// Match: [@value='test'], [@foo]
+		/^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/,
+
+		// Match: :contains('foo')
+		/^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/,
+
+		// Match: :even, :last-child, #id, .class
+		new RegExp("^([:.#]*)(" + chars + "+)")
+	],
+
+	multiFilter: function( expr, elems, not ) {
+		var old, cur = [];
+
+		while ( expr && expr != old ) {
+			old = expr;
+			var f = jQuery.filter( expr, elems, not );
+			expr = f.t.replace(/^\s*,\s*/, "" );
+			cur = not ? elems = f.r : jQuery.merge( cur, f.r );
+		}
+
+		return cur;
+	},
+
+	find: function( t, context ) {
+		// Quickly handle non-string expressions
+		if ( typeof t != "string" )
+			return [ t ];
+
+		// check to make sure context is a DOM element or a document
+		if ( context && context.nodeType != 1 && context.nodeType != 9)
+			return [ ];
+
+		// Set the correct context (if none is provided)
+		context = context || document;
+
+		// Initialize the search
+		var ret = [context], done = [], last, nodeName;
+
+		// Continue while a selector expression exists, and while
+		// we're no longer looping upon ourselves
+		while ( t && last != t ) {
+			var r = [];
+			last = t;
+
+			t = jQuery.trim(t);
+
+			var foundToken = false,
+
+			// An attempt at speeding up child selectors that
+			// point to a specific element tag
+				re = quickChild,
+
+				m = re.exec(t);
+
+			if ( m ) {
+				nodeName = m[1].toUpperCase();
+
+				// Perform our own iteration and filter
+				for ( var i = 0; ret[i]; i++ )
+					for ( var c = ret[i].firstChild; c; c = c.nextSibling )
+						if ( c.nodeType == 1 && (nodeName == "*" || c.nodeName.toUpperCase() == nodeName) )
+							r.push( c );
+
+				ret = r;
+				t = t.replace( re, "" );
+				if ( t.indexOf(" ") == 0 ) continue;
+				foundToken = true;
+			} else {
+				re = /^([>+~])\s*(\w*)/i;
+
+				if ( (m = re.exec(t)) != null ) {
+					r = [];
+
+					var merge = {};
+					nodeName = m[2].toUpperCase();
+					m = m[1];
+
+					for ( var j = 0, rl = ret.length; j < rl; j++ ) {
+						var n = m == "~" || m == "+" ? ret[j].nextSibling : ret[j].firstChild;
+						for ( ; n; n = n.nextSibling )
+							if ( n.nodeType == 1 ) {
+								var id = jQuery.data(n);
+
+								if ( m == "~" && merge[id] ) break;
+
+								if (!nodeName || n.nodeName.toUpperCase() == nodeName ) {
+									if ( m == "~" ) merge[id] = true;
+									r.push( n );
+								}
+
+								if ( m == "+" ) break;
+							}
+					}
+
+					ret = r;
+
+					// And remove the token
+					t = jQuery.trim( t.replace( re, "" ) );
+					foundToken = true;
+				}
+			}
+
+			// See if there's still an expression, and that we haven't already
+			// matched a token
+			if ( t && !foundToken ) {
+				// Handle multiple expressions
+				if ( !t.indexOf(",") ) {
+					// Clean the result set
+					if ( context == ret[0] ) ret.shift();
+
+					// Merge the result sets
+					done = jQuery.merge( done, ret );
+
+					// Reset the context
+					r = ret = [context];
+
+					// Touch up the selector string
+					t = " " + t.substr(1,t.length);
+
+				} else {
+					// Optimize for the case nodeName#idName
+					var re2 = quickID;
+					var m = re2.exec(t);
+
+					// Re-organize the results, so that they're consistent
+					if ( m ) {
+						m = [ 0, m[2], m[3], m[1] ];
+
+					} else {
+						// Otherwise, do a traditional filter check for
+						// ID, class, and element selectors
+						re2 = quickClass;
+						m = re2.exec(t);
+					}
+
+					m[2] = m[2].replace(/\\/g, "");
+
+					var elem = ret[ret.length-1];
+
+					// Try to do a global search by ID, where we can
+					if ( m[1] == "#" && elem && elem.getElementById && !jQuery.isXMLDoc(elem) ) {
+						// Optimization for HTML document case
+						var oid = elem.getElementById(m[2]);
+
+						// Do a quick check for the existence of the actual ID attribute
+						// to avoid selecting by the name attribute in IE
+						// also check to insure id is a string to avoid selecting an element with the name of 'id' inside a form
+						if ( (jQuery.browser.msie||jQuery.browser.opera) && oid && typeof oid.id == "string" && oid.id != m[2] )
+							oid = jQuery('[@id="'+m[2]+'"]', elem)[0];
+
+						// Do a quick check for node name (where applicable) so
+						// that div#foo searches will be really fast
+						ret = r = oid && (!m[3] || jQuery.nodeName(oid, m[3])) ? [oid] : [];
+					} else {
+						// We need to find all descendant elements
+						for ( var i = 0; ret[i]; i++ ) {
+							// Grab the tag name being searched for
+							var tag = m[1] == "#" && m[3] ? m[3] : m[1] != "" || m[0] == "" ? "*" : m[2];
+
+							// Handle IE7 being really dumb about <object>s
+							if ( tag == "*" && ret[i].nodeName.toLowerCase() == "object" )
+								tag = "param";
+
+							r = jQuery.merge( r, ret[i].getElementsByTagName( tag ));
+						}
+
+						// It's faster to filter by class and be done with it
+						if ( m[1] == "." )
+							r = jQuery.classFilter( r, m[2] );
+
+						// Same with ID filtering
+						if ( m[1] == "#" ) {
+							var tmp = [];
+
+							// Try to find the element with the ID
+							for ( var i = 0; r[i]; i++ )
+								if ( r[i].getAttribute("id") == m[2] ) {
+									tmp = [ r[i] ];
+									break;
+								}
+
+							r = tmp;
+						}
+
+						ret = r;
+					}
+
+					t = t.replace( re2, "" );
+				}
+
+			}
+
+			// If a selector string still exists
+			if ( t ) {
+				// Attempt to filter it
+				var val = jQuery.filter(t,r);
+				ret = r = val.r;
+				t = jQuery.trim(val.t);
+			}
+		}
+
+		// An error occurred with the selector;
+		// just return an empty set instead
+		if ( t )
+			ret = [];
+
+		// Remove the root context
+		if ( ret && context == ret[0] )
+			ret.shift();
+
+		// And combine the results
+		done = jQuery.merge( done, ret );
+
+		return done;
+	},
+
+	classFilter: function(r,m,not){
+		m = " " + m + " ";
+		var tmp = [];
+		for ( var i = 0; r[i]; i++ ) {
+			var pass = (" " + r[i].className + " ").indexOf( m ) >= 0;
+			if ( !not && pass || not && !pass )
+				tmp.push( r[i] );
+		}
+		return tmp;
+	},
+
+	filter: function(t,r,not) {
+		var last;
+
+		// Look for common filter expressions
+		while ( t && t != last ) {
+			last = t;
+
+			var p = jQuery.parse, m;
+
+			for ( var i = 0; p[i]; i++ ) {
+				m = p[i].exec( t );
+
+				if ( m ) {
+					// Remove what we just matched
+					t = t.substring( m[0].length );
+
+					m[2] = m[2].replace(/\\/g, "");
+					break;
+				}
+			}
+
+			if ( !m )
+				break;
+
+			// :not() is a special case that can be optimized by
+			// keeping it out of the expression list
+			if ( m[1] == ":" && m[2] == "not" )
+				// optimize if only one selector found (most common case)
+				r = isSimple.test( m[3] ) ?
+					jQuery.filter(m[3], r, true).r :
+					jQuery( r ).not( m[3] );
+
+			// We can get a big speed boost by filtering by class here
+			else if ( m[1] == "." )
+				r = jQuery.classFilter(r, m[2], not);
+
+			else if ( m[1] == "[" ) {
+				var tmp = [], type = m[3];
+
+				for ( var i = 0, rl = r.length; i < rl; i++ ) {
+					var a = r[i], z = a[ jQuery.props[m[2]] || m[2] ];
+
+					if ( z == null || /href|src|selected/.test(m[2]) )
+						z = jQuery.attr(a,m[2]) || '';
+
+					if ( (type == "" && !!z ||
+						 type == "=" && z == m[5] ||
+						 type == "!=" && z != m[5] ||
+						 type == "^=" && z && !z.indexOf(m[5]) ||
+						 type == "$=" && z.substr(z.length - m[5].length) == m[5] ||
+						 (type == "*=" || type == "~=") && z.indexOf(m[5]) >= 0) ^ not )
+							tmp.push( a );
+				}
+
+				r = tmp;
+
+			// We can get a speed boost by handling nth-child here
+			} else if ( m[1] == ":" && m[2] == "nth-child" ) {
+				var merge = {}, tmp = [],
+					// parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
+					test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
+						m[3] == "even" && "2n" || m[3] == "odd" && "2n+1" ||
+						!/\D/.test(m[3]) && "0n+" + m[3] || m[3]),
+					// calculate the numbers (first)n+(last) including if they are negative
+					first = (test[1] + (test[2] || 1)) - 0, last = test[3] - 0;
+
+				// loop through all the elements left in the jQuery object
+				for ( var i = 0, rl = r.length; i < rl; i++ ) {
+					var node = r[i], parentNode = node.parentNode, id = jQuery.data(parentNode);
+
+					if ( !merge[id] ) {
+						var c = 1;
+
+						for ( var n = parentNode.firstChild; n; n = n.nextSibling )
+							if ( n.nodeType == 1 )
+								n.nodeIndex = c++;
+
+						merge[id] = true;
+					}
+
+					var add = false;
+
+					if ( first == 0 ) {
+						if ( node.nodeIndex == last )
+							add = true;
+					} else if ( (node.nodeIndex - last) % first == 0 && (node.nodeIndex - last) / first >= 0 )
+						add = true;
+
+					if ( add ^ not )
+						tmp.push( node );
+				}
+
+				r = tmp;
+
+			// Otherwise, find the expression to execute
+			} else {
+				var fn = jQuery.expr[ m[1] ];
+				if ( typeof fn == "object" )
+					fn = fn[ m[2] ];
+
+				if ( typeof fn == "string" )
+					fn = eval("false||function(a,i){return " + fn + ";}");
+
+				// Execute it against the current filter
+				r = jQuery.grep( r, function(elem, i){
+					return fn(elem, i, m, r);
+				}, not );
+			}
+		}
+
+		// Return an array of filtered elements (r)
+		// and the modified expression string (t)
+		return { r: r, t: t };
+	},
+
+	dir: function( elem, dir ){
+		var matched = [],
+			cur = elem[dir];
+		while ( cur && cur != document ) {
+			if ( cur.nodeType == 1 )
+				matched.push( cur );
+			cur = cur[dir];
+		}
+		return matched;
+	},
+
+	nth: function(cur,result,dir,elem){
+		result = result || 1;
+		var num = 0;
+
+		for ( ; cur; cur = cur[dir] )
+			if ( cur.nodeType == 1 && ++num == result )
+				break;
+
+		return cur;
+	},
+
+	sibling: function( n, elem ) {
+		var r = [];
+
+		for ( ; n; n = n.nextSibling ) {
+			if ( n.nodeType == 1 && n != elem )
+				r.push( n );
+		}
+
+		return r;
+	}
+});
+/*
+ * A number of helper functions used for managing events.
+ * Many of the ideas behind this code orignated from
+ * Dean Edwards' addEvent library.
+ */
+jQuery.event = {
+
+	// Bind an event to an element
+	// Original by Dean Edwards
+	add: function(elem, types, handler, data) {
+		if ( elem.nodeType == 3 || elem.nodeType == 8 )
+			return;
+
+		// For whatever reason, IE has trouble passing the window object
+		// around, causing it to be cloned in the process
+		if ( jQuery.browser.msie && elem.setInterval )
+			elem = window;
+
+		// Make sure that the function being executed has a unique ID
+		if ( !handler.guid )
+			handler.guid = this.guid++;
+
+		// if data is passed, bind to handler
+		if( data != undefined ) {
+			// Create temporary function pointer to original handler
+			var fn = handler;
+
+			// Create unique handler function, wrapped around original handler
+			handler = this.proxy( fn, function() {
+				// Pass arguments and context to original handler
+				return fn.apply(this, arguments);
+			});
+
+			// Store data in unique handler
+			handler.data = data;
+		}
+
+		// Init the element's event structure
+		var events = jQuery.data(elem, "events") || jQuery.data(elem, "events", {}),
+			handle = jQuery.data(elem, "handle") || jQuery.data(elem, "handle", function(){
+				// Handle the second event of a trigger and when
+				// an event is called after a page has unloaded
+				if ( typeof jQuery != "undefined" && !jQuery.event.triggered )
+					return jQuery.event.handle.apply(arguments.callee.elem, arguments);
+			});
+		// Add elem as a property of the handle function
+		// This is to prevent a memory leak with non-native
+		// event in IE.
+		handle.elem = elem;
+
+		// Handle multiple events separated by a space
+		// jQuery(...).bind("mouseover mouseout", fn);
+		jQuery.each(types.split(/\s+/), function(index, type) {
+			// Namespaced event handlers
+			var parts = type.split(".");
+			type = parts[0];
+			handler.type = parts[1];
+
+			// Get the current list of functions bound to this event
+			var handlers = events[type];
+
+			// Init the event handler queue
+			if (!handlers) {
+				handlers = events[type] = {};
+
+				// Check for a special event handler
+				// Only use addEventListener/attachEvent if the special
+				// events handler returns false
+				if ( !jQuery.event.special[type] || jQuery.event.special[type].setup.call(elem) === false ) {
+					// Bind the global event handler to the element
+					if (elem.addEventListener)
+						elem.addEventListener(type, handle, false);
+					else if (elem.attachEvent)
+						elem.attachEvent("on" + type, handle);
+				}
+			}
+
+			// Add the function to the element's handler list
+			handlers[handler.guid] = handler;
+
+			// Keep track of which events have been used, for global triggering
+			jQuery.event.global[type] = true;
+		});
+
+		// Nullify elem to prevent memory leaks in IE
+		elem = null;
+	},
+
+	guid: 1,
+	global: {},
+
+	// Detach an event or set of events from an element
+	remove: function(elem, types, handler) {
+		// don't do events on text and comment nodes
+		if ( elem.nodeType == 3 || elem.nodeType == 8 )
+			return;
+
+		var events = jQuery.data(elem, "events"), ret, index;
+
+		if ( events ) {
+			// Unbind all events for the element
+			if ( types == undefined || (typeof types == "string" && types.charAt(0) == ".") )
+				for ( var type in events )
+					this.remove( elem, type + (types || "") );
+			else {
+				// types is actually an event object here
+				if ( types.type ) {
+					handler = types.handler;
+					types = types.type;
+				}
+
+				// Handle multiple events seperated by a space
+				// jQuery(...).unbind("mouseover mouseout", fn);
+				jQuery.each(types.split(/\s+/), function(index, type){
+					// Namespaced event handlers
+					var parts = type.split(".");
+					type = parts[0];
+
+					if ( events[type] ) {
+						// remove the given handler for the given type
+						if ( handler )
+							delete events[type][handler.guid];
+
+						// remove all handlers for the given type
+						else
+							for ( handler in events[type] )
+								// Handle the removal of namespaced events
+								if ( !parts[1] || events[type][handler].type == parts[1] )
+									delete events[type][handler];
+
+						// remove generic event handler if no more handlers exist
+						for ( ret in events[type] ) break;
+						if ( !ret ) {
+							if ( !jQuery.event.special[type] || jQuery.event.special[type].teardown.call(elem) === false ) {
+								if (elem.removeEventListener)
+									elem.removeEventListener(type, jQuery.data(elem, "handle"), false);
+								else if (elem.detachEvent)
+									elem.detachEvent("on" + type, jQuery.data(elem, "handle"));
+							}
+							ret = null;
+							delete events[type];
+						}
+					}
+				});
+			}
+
+			// Remove the expando if it's no longer used
+			for ( ret in events ) break;
+			if ( !ret ) {
+				var handle = jQuery.data( elem, "handle" );
+				if ( handle ) handle.elem = null;
+				jQuery.removeData( elem, "events" );
+				jQuery.removeData( elem, "handle" );
+			}
+		}
+	},
+
+	trigger: function(type, data, elem, donative, extra) {
+		// Clone the incoming data, if any
+		data = jQuery.makeArray(data);
+
+		if ( type.indexOf("!") >= 0 ) {
+			type = type.slice(0, -1);
+			var exclusive = true;
+		}
+
+		// Handle a global trigger
+		if ( !elem ) {
+			// Only trigger if we've ever bound an event for it
+			if ( this.global[type] )
+				jQuery("*").add([window, document]).trigger(type, data);
+
+		// Handle triggering a single element
+		} else {
+			// don't do events on text and comment nodes
+			if ( elem.nodeType == 3 || elem.nodeType == 8 )
+				return undefined;
+
+			var val, ret, fn = jQuery.isFunction( elem[ type ] || null ),
+				// Check to see if we need to provide a fake event, or not
+				event = !data[0] || !data[0].preventDefault;
+
+			// Pass along a fake event
+			if ( event ) {
+				data.unshift({
+					type: type,
+					target: elem,
+					preventDefault: function(){},
+					stopPropagation: function(){},
+					timeStamp: now()
+				});
+				data[0][expando] = true; // no need to fix fake event
+			}
+
+			// Enforce the right trigger type
+			data[0].type = type;
+			if ( exclusive )
+				data[0].exclusive = true;
+
+			// Trigger the event, it is assumed that "handle" is a function
+			var handle = jQuery.data(elem, "handle");
+			if ( handle )
+				val = handle.apply( elem, data );
+
+			// Handle triggering native .onfoo handlers (and on links since we don't call .click() for links)
+			if ( (!fn || (jQuery.nodeName(elem, 'a') && type == "click")) && elem["on"+type] && elem["on"+type].apply( elem, data ) === false )
+				val = false;
+
+			// Extra functions don't get the custom event object
+			if ( event )
+				data.shift();
+
+			// Handle triggering of extra function
+			if ( extra && jQuery.isFunction( extra ) ) {
+				// call the extra function and tack the current return value on the end for possible inspection
+				ret = extra.apply( elem, val == null ? data : data.concat( val ) );
+				// if anything is returned, give it precedence and have it overwrite the previous value
+				if (ret !== undefined)
+					val = ret;
+			}
+
+			// Trigger the native events (except for clicks on links)
+			if ( fn && donative !== false && val !== false && !(jQuery.nodeName(elem, 'a') && type == "click") ) {
+				this.triggered = true;
+				try {
+					elem[ type ]();
+				// prevent IE from throwing an error for some hidden elements
+				} catch (e) {}
+			}
+
+			this.triggered = false;
+		}
+
+		return val;
+	},
+
+	handle: function(event) {
+		// returned undefined or false
+		var val, ret, namespace, all, handlers;
+
+		event = arguments[0] = jQuery.event.fix( event || window.event );
+
+		// Namespaced event handlers
+		namespace = event.type.split(".");
+		event.type = namespace[0];
+		namespace = namespace[1];
+		// Cache this now, all = true means, any handler
+		all = !namespace && !event.exclusive;
+
+		handlers = ( jQuery.data(this, "events") || {} )[event.type];
+
+		for ( var j in handlers ) {
+			var handler = handlers[j];
+
+			// Filter the functions by class
+			if ( all || handler.type == namespace ) {
+				// Pass in a reference to the handler function itself
+				// So that we can later remove it
+				event.handler = handler;
+				event.data = handler.data;
+
+				ret = handler.apply( this, arguments );
+
+				if ( val !== false )
+					val = ret;
+
+				if ( ret === false ) {
+					event.preventDefault();
+					event.stopPropagation();
+				}
+			}
+		}
+
+		return val;
+	},
+
+	fix: function(event) {
+		if ( event[expando] == true )
+			return event;
+
+		// store a copy of the original event object
+		// and "clone" to set read-only properties
+		var originalEvent = event;
+		event = { originalEvent: originalEvent };
+		var props = "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target timeStamp toElement type view wheelDelta which".split(" ");
+		for ( var i=props.length; i; i-- )
+			event[ props[i] ] = originalEvent[ props[i] ];
+
+		// Mark it as fixed
+		event[expando] = true;
+
+		// add preventDefault and stopPropagation since
+		// they will not work on the clone
+		event.preventDefault = function() {
+			// if preventDefault exists run it on the original event
+			if (originalEvent.preventDefault)
+				originalEvent.preventDefault();
+			// otherwise set the returnValue property of the original event to false (IE)
+			originalEvent.returnValue = false;
+		};
+		event.stopPropagation = function() {
+			// if stopPropagation exists run it on the original event
+			if (originalEvent.stopPropagation)
+				originalEvent.stopPropagation();
+			// otherwise set the cancelBubble property of the original event to true (IE)
+			originalEvent.cancelBubble = true;
+		};
+
+		// Fix timeStamp
+		event.timeStamp = event.timeStamp || now();
+
+		// Fix target property, if necessary
+		if ( !event.target )
+			event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
+
+		// check if target is a textnode (safari)
+		if ( event.target.nodeType == 3 )
+			event.target = event.target.parentNode;
+
+		// Add relatedTarget, if necessary
+		if ( !event.relatedTarget && event.fromElement )
+			event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement;
+
+		// Calculate pageX/Y if missing and clientX/Y available
+		if ( event.pageX == null && event.clientX != null ) {
+			var doc = document.documentElement, body = document.body;
+			event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc.clientLeft || 0);
+			event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc.clientTop || 0);
+		}
+
+		// Add which for key events
+		if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) )
+			event.which = event.charCode || event.keyCode;
+
+		// Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
+		if ( !event.metaKey && event.ctrlKey )
+			event.metaKey = event.ctrlKey;
+
+		// Add which for click: 1 == left; 2 == middle; 3 == right
+		// Note: button is not normalized, so don't use it
+		if ( !event.which && event.button )
+			event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
+
+		return event;
+	},
+
+	proxy: function( fn, proxy ){
+		// Set the guid of unique handler to the same of original handler, so it can be removed
+		proxy.guid = fn.guid = fn.guid || proxy.guid || this.guid++;
+		// So proxy can be declared as an argument
+		return proxy;
+	},
+
+	special: {
+		ready: {
+			setup: function() {
+				// Make sure the ready event is setup
+				bindReady();
+				return;
+			},
+
+			teardown: function() { return; }
+		},
+
+		mouseenter: {
+			setup: function() {
+				if ( jQuery.browser.msie ) return false;
+				jQuery(this).bind("mouseover", jQuery.event.special.mouseenter.handler);
+				return true;
+			},
+
+			teardown: function() {
+				if ( jQuery.browser.msie ) return false;
+				jQuery(this).unbind("mouseover", jQuery.event.special.mouseenter.handler);
+				return true;
+			},
+
+			handler: function(event) {
+				// If we actually just moused on to a sub-element, ignore it
+				if ( withinElement(event, this) ) return true;
+				// Execute the right handlers by setting the event type to mouseenter
+				event.type = "mouseenter";
+				return jQuery.event.handle.apply(this, arguments);
+			}
+		},
+
+		mouseleave: {
+			setup: function() {
+				if ( jQuery.browser.msie ) return false;
+				jQuery(this).bind("mouseout", jQuery.event.special.mouseleave.handler);
+				return true;
+			},
+
+			teardown: function() {
+				if ( jQuery.browser.msie ) return false;
+				jQuery(this).unbind("mouseout", jQuery.event.special.mouseleave.handler);
+				return true;
+			},
+
+			handler: function(event) {
+				// If we actually just moused on to a sub-element, ignore it
+				if ( withinElement(event, this) ) return true;
+				// Execute the right handlers by setting the event type to mouseleave
+				event.type = "mouseleave";
+				return jQuery.event.handle.apply(this, arguments);
+			}
+		}
+	}
+};
+
+jQuery.fn.extend({
+	bind: function( type, data, fn ) {
+		return type == "unload" ? this.one(type, data, fn) : this.each(function(){
+			jQuery.event.add( this, type, fn || data, fn && data );
+		});
+	},
+
+	one: function( type, data, fn ) {
+		var one = jQuery.event.proxy( fn || data, function(event) {
+			jQuery(this).unbind(event, one);
+			return (fn || data).apply( this, arguments );
+		});
+		return this.each(function(){
+			jQuery.event.add( this, type, one, fn && data);
+		});
+	},
+
+	unbind: function( type, fn ) {
+		return this.each(function(){
+			jQuery.event.remove( this, type, fn );
+		});
+	},
+
+	trigger: function( type, data, fn ) {
+		return this.each(function(){
+			jQuery.event.trigger( type, data, this, true, fn );
+		});
+	},
+
+	triggerHandler: function( type, data, fn ) {
+		return this[0] && jQuery.event.trigger( type, data, this[0], false, fn );
+	},
+
+	toggle: function( fn ) {
+		// Save reference to arguments for access in closure
+		var args = arguments, i = 1;
+
+		// link all the functions, so any of them can unbind this click handler
+		while( i < args.length )
+			jQuery.event.proxy( fn, args[i++] );
+
+		return this.click( jQuery.event.proxy( fn, function(event) {
+			// Figure out which function to execute
+			this.lastToggle = ( this.lastToggle || 0 ) % i;
+
+			// Make sure that clicks stop
+			event.preventDefault();
+
+			// and execute the function
+			return args[ this.lastToggle++ ].apply( this, arguments ) || false;
+		}));
+	},
+
+	hover: function(fnOver, fnOut) {
+		return this.bind('mouseenter', fnOver).bind('mouseleave', fnOut);
+	},
+
+	ready: function(fn) {
+		// Attach the listeners
+		bindReady();
+
+		// If the DOM is already ready
+		if ( jQuery.isReady )
+			// Execute the function immediately
+			fn.call( document, jQuery );
+
+		// Otherwise, remember the function for later
+		else
+			// Add the function to the wait list
+			jQuery.readyList.push( function() { return fn.call(this, jQuery); } );
+
+		return this;
+	}
+});
+
+jQuery.extend({
+	isReady: false,
+	readyList: [],
+	// Handle when the DOM is ready
+	ready: function() {
+		// Make sure that the DOM is not already loaded
+		if ( !jQuery.isReady ) {
+			// Remember that the DOM is ready
+			jQuery.isReady = true;
+
+			// If there are functions bound, to execute
+			if ( jQuery.readyList ) {
+				// Execute all of them
+				jQuery.each( jQuery.readyList, function(){
+					this.call( document );
+				});
+
+				// Reset the list of functions
+				jQuery.readyList = null;
+			}
+
+			// Trigger any bound ready events
+			jQuery(document).triggerHandler("ready");
+		}
+	}
+});
+
+var readyBound = false;
+
+function bindReady(){
+	if ( readyBound ) return;
+	readyBound = true;
+
+	// Mozilla, Opera (see further below for it) and webkit nightlies currently support this event
+	if ( document.addEventListener && !jQuery.browser.opera)
+		// Use the handy event callback
+		document.addEventListener( "DOMContentLoaded", jQuery.ready, false );
+
+	// If IE is used and is not in a frame
+	// Continually check to see if the document is ready
+	if ( jQuery.browser.msie && window == top ) (function(){
+		if (jQuery.isReady) return;
+		try {
+			// If IE is used, use the trick by Diego Perini
+			// http://javascript.nwbox.com/IEContentLoaded/
+			document.documentElement.doScroll("left");
+		} catch( error ) {
+			setTimeout( arguments.callee, 0 );
+			return;
+		}
+		// and execute any waiting functions
+		jQuery.ready();
+	})();
+
+	if ( jQuery.browser.opera )
+		document.addEventListener( "DOMContentLoaded", function () {
+			if (jQuery.isReady) return;
+			for (var i = 0; i < document.styleSheets.length; i++)
+				if (document.styleSheets[i].disabled) {
+					setTimeout( arguments.callee, 0 );
+					return;
+				}
+			// and execute any waiting functions
+			jQuery.ready();
+		}, false);
+
+	if ( jQuery.browser.safari ) {
+		var numStyles;
+		(function(){
+			if (jQuery.isReady) return;
+			if ( document.readyState != "loaded" && document.readyState != "complete" ) {
+				setTimeout( arguments.callee, 0 );
+				return;
+			}
+			if ( numStyles === undefined )
+				numStyles = jQuery("style, link[rel=stylesheet]").length;
+			if ( document.styleSheets.length != numStyles ) {
+				setTimeout( arguments.callee, 0 );
+				return;
+			}
+			// and execute any waiting functions
+			jQuery.ready();
+		})();
+	}
+
+	// A fallback to window.onload, that will always work
+	jQuery.event.add( window, "load", jQuery.ready );
+}
+
+jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," +
+	"mousedown,mouseup,mousemove,mouseover,mouseout,change,select," +
+	"submit,keydown,keypress,keyup,error").split(","), function(i, name){
+
+	// Handle event binding
+	jQuery.fn[name] = function(fn){
+		return fn ? this.bind(name, fn) : this.trigger(name);
+	};
+});
+
+// Checks if an event happened on an element within another element
+// Used in jQuery.event.special.mouseenter and mouseleave handlers
+var withinElement = function(event, elem) {
+	// Check if mouse(over|out) are still within the same parent element
+	var parent = event.relatedTarget;
+	// Traverse up the tree
+	while ( parent && parent != elem ) try { parent = parent.parentNode; } catch(error) { parent = elem; }
+	// Return true if we actually just moused on to a sub-element
+	return parent == elem;
+};
+
+// Prevent memory leaks in IE
+// And prevent errors on refresh with events like mouseover in other browsers
+// Window isn't included so as not to unbind existing unload events
+jQuery(window).bind("unload", function() {
+	jQuery("*").add(document).unbind();
+});
+jQuery.fn.extend({
+	// Keep a copy of the old load
+	_load: jQuery.fn.load,
+
+	load: function( url, params, callback ) {
+		if ( typeof url != 'string' )
+			return this._load( url );
+
+		var off = url.indexOf(" ");
+		if ( off >= 0 ) {
+			var selector = url.slice(off, url.length);
+			url = url.slice(0, off);
+		}
+
+		callback = callback || function(){};
+
+		// Default to a GET request
+		var type = "GET";
+
+		// If the second parameter was provided
+		if ( params )
+			// If it's a function
+			if ( jQuery.isFunction( params ) ) {
+				// We assume that it's the callback
+				callback = params;
+				params = null;
+
+			// Otherwise, build a param string
+			} else {
+				params = jQuery.param( params );
+				type = "POST";
+			}
+
+		var self = this;
+
+		// Request the remote document
+		jQuery.ajax({
+			url: url,
+			type: type,
+			dataType: "html",
+			data: params,
+			complete: function(res, status){
+				// If successful, inject the HTML into all the matched elements
+				if ( status == "success" || status == "notmodified" )
+					// See if a selector was specified
+					self.html( selector ?
+						// Create a dummy div to hold the results
+						jQuery("<div/>")
+							// inject the contents of the document in, removing the scripts
+							// to avoid any 'Permission Denied' errors in IE
+							.append(res.responseText.replace(/<script(.|\s)*?\/script>/g, ""))
+
+							// Locate the specified elements
+							.find(selector) :
+
+						// If not, just inject the full result
+						res.responseText );
+
+				self.each( callback, [res.responseText, status, res] );
+			}
+		});
+		return this;
+	},
+
+	serialize: function() {
+		return jQuery.param(this.serializeArray());
+	},
+	serializeArray: function() {
+		return this.map(function(){
+			return jQuery.nodeName(this, "form") ?
+				jQuery.makeArray(this.elements) : this;
+		})
+		.filter(function(){
+			return this.name && !this.disabled &&
+				(this.checked || /select|textarea/i.test(this.nodeName) ||
+					/text|hidden|password/i.test(this.type));
+		})
+		.map(function(i, elem){
+			var val = jQuery(this).val();
+			return val == null ? null :
+				val.constructor == Array ?
+					jQuery.map( val, function(val, i){
+						return {name: elem.name, value: val};
+					}) :
+					{name: elem.name, value: val};
+		}).get();
+	}
+});
+
+// Attach a bunch of functions for handling common AJAX events
+jQuery.each( "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","), function(i,o){
+	jQuery.fn[o] = function(f){
+		return this.bind(o, f);
+	};
+});
+
+var jsc = now();
+
+jQuery.extend({
+	get: function( url, data, callback, type ) {
+		// shift arguments if data argument was ommited
+		if ( jQuery.isFunction( data ) ) {
+			callback = data;
+			data = null;
+		}
+
+		return jQuery.ajax({
+			type: "GET",
+			url: url,
+			data: data,
+			success: callback,
+			dataType: type
+		});
+	},
+
+	getScript: function( url, callback ) {
+		return jQuery.get(url, null, callback, "script");
+	},
+
+	getJSON: function( url, data, callback ) {
+		return jQuery.get(url, data, callback, "json");
+	},
+
+	post: function( url, data, callback, type ) {
+		if ( jQuery.isFunction( data ) ) {
+			callback = data;
+			data = {};
+		}
+
+		return jQuery.ajax({
+			type: "POST",
+			url: url,
+			data: data,
+			success: callback,
+			dataType: type
+		});
+	},
+
+	ajaxSetup: function( settings ) {
+		jQuery.extend( jQuery.ajaxSettings, settings );
+	},
+
+	ajaxSettings: {
+		url: location.href,
+		global: true,
+		type: "GET",
+		timeout: 0,
+		contentType: "application/x-www-form-urlencoded",
+		processData: true,
+		async: true,
+		data: null,
+		username: null,
+		password: null,
+		accepts: {
+			xml: "application/xml, text/xml",
+			html: "text/html",
+			script: "text/javascript, application/javascript",
+			json: "application/json, text/javascript",
+			text: "text/plain",
+			_default: "*/*"
+		}
+	},
+
+	// Last-Modified header cache for next request
+	lastModified: {},
+
+	ajax: function( s ) {
+		// Extend the settings, but re-extend 's' so that it can be
+		// checked again later (in the test suite, specifically)
+		s = jQuery.extend(true, s, jQuery.extend(true, {}, jQuery.ajaxSettings, s));
+
+		var jsonp, jsre = /=\?(&|$)/g, status, data,
+			type = s.type.toUpperCase();
+
+		// convert data if not already a string
+		if ( s.data && s.processData && typeof s.data != "string" )
+			s.data = jQuery.param(s.data);
+
+		// Handle JSONP Parameter Callbacks
+		if ( s.dataType == "jsonp" ) {
+			if ( type == "GET" ) {
+				if ( !s.url.match(jsre) )
+					s.url += (s.url.match(/\?/) ? "&" : "?") + (s.jsonp || "callback") + "=?";
+			} else if ( !s.data || !s.data.match(jsre) )
+				s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
+			s.dataType = "json";
+		}
+
+		// Build temporary JSONP function
+		if ( s.dataType == "json" && (s.data && s.data.match(jsre) || s.url.match(jsre)) ) {
+			jsonp = "jsonp" + jsc++;
+
+			// Replace the =? sequence both in the query string and the data
+			if ( s.data )
+				s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
+			s.url = s.url.replace(jsre, "=" + jsonp + "$1");
+
+			// We need to make sure
+			// that a JSONP style response is executed properly
+			s.dataType = "script";
+
+			// Handle JSONP-style loading
+			window[ jsonp ] = function(tmp){
+				data = tmp;
+				success();
+				complete();
+				// Garbage collect
+				window[ jsonp ] = undefined;
+				try{ delete window[ jsonp ]; } catch(e){}
+				if ( head )
+					head.removeChild( script );
+			};
+		}
+
+		if ( s.dataType == "script" && s.cache == null )
+			s.cache = false;
+
+		if ( s.cache === false && type == "GET" ) {
+			var ts = now();
+			// try replacing _= if it is there
+			var ret = s.url.replace(/(\?|&)_=.*?(&|$)/, "$1_=" + ts + "$2");
+			// if nothing was replaced, add timestamp to the end
+			s.url = ret + ((ret == s.url) ? (s.url.match(/\?/) ? "&" : "?") + "_=" + ts : "");
+		}
+
+		// If data is available, append data to url for get requests
+		if ( s.data && type == "GET" ) {
+			s.url += (s.url.match(/\?/) ? "&" : "?") + s.data;
+
+			// IE likes to send both get and post data, prevent this
+			s.data = null;
+		}
+
+		// Watch for a new set of requests
+		if ( s.global && ! jQuery.active++ )
+			jQuery.event.trigger( "ajaxStart" );
+
+		// Matches an absolute URL, and saves the domain
+		var remote = /^(?:\w+:)?\/\/([^\/?#]+)/;
+
+		// If we're requesting a remote document
+		// and trying to load JSON or Script with a GET
+		if ( s.dataType == "script" && type == "GET"
+				&& remote.test(s.url) && remote.exec(s.url)[1] != location.host ){
+			var head = document.getElementsByTagName("head")[0];
+			var script = document.createElement("script");
+			script.src = s.url;
+			if (s.scriptCharset)
+				script.charset = s.scriptCharset;
+
+			// Handle Script loading
+			if ( !jsonp ) {
+				var done = false;
+
+				// Attach handlers for all browsers
+				script.onload = script.onreadystatechange = function(){
+					if ( !done && (!this.readyState ||
+							this.readyState == "loaded" || this.readyState == "complete") ) {
+						done = true;
+						success();
+						complete();
+						head.removeChild( script );
+					}
+				};
+			}
+
+			head.appendChild(script);
+
+			// We handle everything using the script element injection
+			return undefined;
+		}
+
+		var requestDone = false;
+
+		// Create the request object; Microsoft failed to properly
+		// implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available
+		var xhr = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
+
+		// Open the socket
+		// Passing null username, generates a login popup on Opera (#2865)
+		if( s.username )
+			xhr.open(type, s.url, s.async, s.username, s.password);
+		else
+			xhr.open(type, s.url, s.async);
+
+		// Need an extra try/catch for cross domain requests in Firefox 3
+		try {
+			// Set the correct header, if data is being sent
+			if ( s.data )
+				xhr.setRequestHeader("Content-Type", s.contentType);
+
+			// Set the If-Modified-Since header, if ifModified mode.
+			if ( s.ifModified )
+				xhr.setRequestHeader("If-Modified-Since",
+					jQuery.lastModified[s.url] || "Thu, 01 Jan 1970 00:00:00 GMT" );
+
+			// Set header so the called script knows that it's an XMLHttpRequest
+			xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
+
+			// Set the Accepts header for the server, depending on the dataType
+			xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?
+				s.accepts[ s.dataType ] + ", */*" :
+				s.accepts._default );
+		} catch(e){}
+
+		// Allow custom headers/mimetypes
+		if ( s.beforeSend && s.beforeSend(xhr, s) === false ) {
+			// cleanup active request counter
+			s.global && jQuery.active--;
+			// close opended socket
+			xhr.abort();
+			return false;
+		}
+
+		if ( s.global )
+			jQuery.event.trigger("ajaxSend", [xhr, s]);
+
+		// Wait for a response to come back
+		var onreadystatechange = function(isTimeout){
+			// The transfer is complete and the data is available, or the request timed out
+			if ( !requestDone && xhr && (xhr.readyState == 4 || isTimeout == "timeout") ) {
+				requestDone = true;
+
+				// clear poll interval
+				if (ival) {
+					clearInterval(ival);
+					ival = null;
+				}
+
+				status = isTimeout == "timeout" && "timeout" ||
+					!jQuery.httpSuccess( xhr ) && "error" ||
+					s.ifModified && jQuery.httpNotModified( xhr, s.url ) && "notmodified" ||
+					"success";
+
+				if ( status == "success" ) {
+					// Watch for, and catch, XML document parse errors
+					try {
+						// process the data (runs the xml through httpData regardless of callback)
+						data = jQuery.httpData( xhr, s.dataType, s.dataFilter );
+					} catch(e) {
+						status = "parsererror";
+					}
+				}
+
+				// Make sure that the request was successful or notmodified
+				if ( status == "success" ) {
+					// Cache Last-Modified header, if ifModified mode.
+					var modRes;
+					try {
+						modRes = xhr.getResponseHeader("Last-Modified");
+					} catch(e) {} // swallow exception thrown by FF if header is not available
+
+					if ( s.ifModified && modRes )
+						jQuery.lastModified[s.url] = modRes;
+
+					// JSONP handles its own success callback
+					if ( !jsonp )
+						success();
+				} else
+					jQuery.handleError(s, xhr, status);
+
+				// Fire the complete handlers
+				complete();
+
+				// Stop memory leaks
+				if ( s.async )
+					xhr = null;
+			}
+		};
+
+		if ( s.async ) {
+			// don't attach the handler to the request, just poll it instead
+			var ival = setInterval(onreadystatechange, 13);
+
+			// Timeout checker
+			if ( s.timeout > 0 )
+				setTimeout(function(){
+					// Check to see if the request is still happening
+					if ( xhr ) {
+						// Cancel the request
+						xhr.abort();
+
+						if( !requestDone )
+							onreadystatechange( "timeout" );
+					}
+				}, s.timeout);
+		}
+
+		// Send the data
+		try {
+			xhr.send(s.data);
+		} catch(e) {
+			jQuery.handleError(s, xhr, null, e);
+		}
+
+		// firefox 1.5 doesn't fire statechange for sync requests
+		if ( !s.async )
+			onreadystatechange();
+
+		function success(){
+			// If a local callback was specified, fire it and pass it the data
+			if ( s.success )
+				s.success( data, status );
+
+			// Fire the global callback
+			if ( s.global )
+				jQuery.event.trigger( "ajaxSuccess", [xhr, s] );
+		}
+
+		function complete(){
+			// Process result
+			if ( s.complete )
+				s.complete(xhr, status);
+
+			// The request was completed
+			if ( s.global )
+				jQuery.event.trigger( "ajaxComplete", [xhr, s] );
+
+			// Handle the global AJAX counter
+			if ( s.global && ! --jQuery.active )
+				jQuery.event.trigger( "ajaxStop" );
+		}
+
+		// return XMLHttpRequest to allow aborting the request etc.
+		return xhr;
+	},
+
+	handleError: function( s, xhr, status, e ) {
+		// If a local callback was specified, fire it
+		if ( s.error ) s.error( xhr, status, e );
+
+		// Fire the global callback
+		if ( s.global )
+			jQuery.event.trigger( "ajaxError", [xhr, s, e] );
+	},
+
+	// Counter for holding the number of active queries
+	active: 0,
+
+	// Determines if an XMLHttpRequest was successful or not
+	httpSuccess: function( xhr ) {
+		try {
+			// IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
+			return !xhr.status && location.protocol == "file:" ||
+				( xhr.status >= 200 && xhr.status < 300 ) || xhr.status == 304 || xhr.status == 1223 ||
+				jQuery.browser.safari && xhr.status == undefined;
+		} catch(e){}
+		return false;
+	},
+
+	// Determines if an XMLHttpRequest returns NotModified
+	httpNotModified: function( xhr, url ) {
+		try {
+			var xhrRes = xhr.getResponseHeader("Last-Modified");
+
+			// Firefox always returns 200. check Last-Modified date
+			return xhr.status == 304 || xhrRes == jQuery.lastModified[url] ||
+				jQuery.browser.safari && xhr.status == undefined;
+		} catch(e){}
+		return false;
+	},
+
+	httpData: function( xhr, type, filter ) {
+		var ct = xhr.getResponseHeader("content-type"),
+			xml = type == "xml" || !type && ct && ct.indexOf("xml") >= 0,
+			data = xml ? xhr.responseXML : xhr.responseText;
+
+		if ( xml && data.documentElement.tagName == "parsererror" )
+			throw "parsererror";
+			
+		// Allow a pre-filtering function to sanitize the response
+		if( filter )
+			data = filter( data, type );
+
+		// If the type is "script", eval it in global context
+		if ( type == "script" )
+			jQuery.globalEval( data );
+
+		// Get the JavaScript object, if JSON is used.
+		if ( type == "json" )
+			data = eval("(" + data + ")");
+
+		return data;
+	},
+
+	// Serialize an array of form elements or a set of
+	// key/values into a query string
+	param: function( a ) {
+		var s = [];
+
+		// If an array was passed in, assume that it is an array
+		// of form elements
+		if ( a.constructor == Array || a.jquery )
+			// Serialize the form elements
+			jQuery.each( a, function(){
+				s.push( encodeURIComponent(this.name) + "=" + encodeURIComponent( this.value ) );
+			});
+
+		// Otherwise, assume that it's an object of key/value pairs
+		else
+			// Serialize the key/values
+			for ( var j in a )
+				// If the value is an array then the key names need to be repeated
+				if ( a[j] && a[j].constructor == Array )
+					jQuery.each( a[j], function(){
+						s.push( encodeURIComponent(j) + "=" + encodeURIComponent( this ) );
+					});
+				else
+					s.push( encodeURIComponent(j) + "=" + encodeURIComponent( jQuery.isFunction(a[j]) ? a[j]() : a[j] ) );
+
+		// Return the resulting serialization
+		return s.join("&").replace(/%20/g, "+");
+	}
+
+});
+jQuery.fn.extend({
+	show: function(speed,callback){
+		return speed ?
+			this.animate({
+				height: "show", width: "show", opacity: "show"
+			}, speed, callback) :
+
+			this.filter(":hidden").each(function(){
+				this.style.display = this.oldblock || "";
+				if ( jQuery.css(this,"display") == "none" ) {
+					var elem = jQuery("<" + this.tagName + " />").appendTo("body");
+					this.style.display = elem.css("display");
+					// handle an edge condition where css is - div { display:none; } or similar
+					if (this.style.display == "none")
+						this.style.display = "block";
+					elem.remove();
+				}
+			}).end();
+	},
+
+	hide: function(speed,callback){
+		return speed ?
+			this.animate({
+				height: "hide", width: "hide", opacity: "hide"
+			}, speed, callback) :
+
+			this.filter(":visible").each(function(){
+				this.oldblock = this.oldblock || jQuery.css(this,"display");
+				this.style.display = "none";
+			}).end();
+	},
+
+	// Save the old toggle function
+	_toggle: jQuery.fn.toggle,
+
+	toggle: function( fn, fn2 ){
+		return jQuery.isFunction(fn) && jQuery.isFunction(fn2) ?
+			this._toggle.apply( this, arguments ) :
+			fn ?
+				this.animate({
+					height: "toggle", width: "toggle", opacity: "toggle"
+				}, fn, fn2) :
+				this.each(function(){
+					jQuery(this)[ jQuery(this).is(":hidden") ? "show" : "hide" ]();
+				});
+	},
+
+	slideDown: function(speed,callback){
+		return this.animate({height: "show"}, speed, callback);
+	},
+
+	slideUp: function(speed,callback){
+		return this.animate({height: "hide"}, speed, callback);
+	},
+
+	slideToggle: function(speed, callback){
+		return this.animate({height: "toggle"}, speed, callback);
+	},
+
+	fadeIn: function(speed, callback){
+		return this.animate({opacity: "show"}, speed, callback);
+	},
+
+	fadeOut: function(speed, callback){
+		return this.animate({opacity: "hide"}, speed, callback);
+	},
+
+	fadeTo: function(speed,to,callback){
+		return this.animate({opacity: to}, speed, callback);
+	},
+
+	animate: function( prop, speed, easing, callback ) {
+		var optall = jQuery.speed(speed, easing, callback);
+
+		return this[ optall.queue === false ? "each" : "queue" ](function(){
+			if ( this.nodeType != 1)
+				return false;
+
+			var opt = jQuery.extend({}, optall), p,
+				hidden = jQuery(this).is(":hidden"), self = this;
+
+			for ( p in prop ) {
+				if ( prop[p] == "hide" && hidden || prop[p] == "show" && !hidden )
+					return opt.complete.call(this);
+
+				if ( p == "height" || p == "width" ) {
+					// Store display property
+					opt.display = jQuery.css(this, "display");
+
+					// Make sure that nothing sneaks out
+					opt.overflow = this.style.overflow;
+				}
+			}
+
+			if ( opt.overflow != null )
+				this.style.overflow = "hidden";
+
+			opt.curAnim = jQuery.extend({}, prop);
+
+			jQuery.each( prop, function(name, val){
+				var e = new jQuery.fx( self, opt, name );
+
+				if ( /toggle|show|hide/.test(val) )
+					e[ val == "toggle" ? hidden ? "show" : "hide" : val ]( prop );
+				else {
+					var parts = val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),
+						start = e.cur(true) || 0;
+
+					if ( parts ) {
+						var end = parseFloat(parts[2]),
+							unit = parts[3] || "px";
+
+						// We need to compute starting value
+						if ( unit != "px" ) {
+							self.style[ name ] = (end || 1) + unit;
+							start = ((end || 1) / e.cur(true)) * start;
+							self.style[ name ] = start + unit;
+						}
+
+						// If a +=/-= token was provided, we're doing a relative animation
+						if ( parts[1] )
+							end = ((parts[1] == "-=" ? -1 : 1) * end) + start;
+
+						e.custom( start, end, unit );
+					} else
+						e.custom( start, val, "" );
+				}
+			});
+
+			// For JS strict compliance
+			return true;
+		});
+	},
+
+	queue: function(type, fn){
+		if ( jQuery.isFunction(type) || ( type && type.constructor == Array )) {
+			fn = type;
+			type = "fx";
+		}
+
+		if ( !type || (typeof type == "string" && !fn) )
+			return queue( this[0], type );
+
+		return this.each(function(){
+			if ( fn.constructor == Array )
+				queue(this, type, fn);
+			else {
+				queue(this, type).push( fn );
+
+				if ( queue(this, type).length == 1 )
+					fn.call(this);
+			}
+		});
+	},
+
+	stop: function(clearQueue, gotoEnd){
+		var timers = jQuery.timers;
+
+		if (clearQueue)
+			this.queue([]);
+
+		this.each(function(){
+			// go in reverse order so anything added to the queue during the loop is ignored
+			for ( var i = timers.length - 1; i >= 0; i-- )
+				if ( timers[i].elem == this ) {
+					if (gotoEnd)
+						// force the next step to be the last
+						timers[i](true);
+					timers.splice(i, 1);
+				}
+		});
+
+		// start the next in the queue if the last step wasn't forced
+		if (!gotoEnd)
+			this.dequeue();
+
+		return this;
+	}
+
+});
+
+var queue = function( elem, type, array ) {
+	if ( elem ){
+
+		type = type || "fx";
+
+		var q = jQuery.data( elem, type + "queue" );
+
+		if ( !q || array )
+			q = jQuery.data( elem, type + "queue", jQuery.makeArray(array) );
+
+	}
+	return q;
+};
+
+jQuery.fn.dequeue = function(type){
+	type = type || "fx";
+
+	return this.each(function(){
+		var q = queue(this, type);
+
+		q.shift();
+
+		if ( q.length )
+			q[0].call( this );
+	});
+};
+
+jQuery.extend({
+
+	speed: function(speed, easing, fn) {
+		var opt = speed && speed.constructor == Object ? speed : {
+			complete: fn || !fn && easing ||
+				jQuery.isFunction( speed ) && speed,
+			duration: speed,
+			easing: fn && easing || easing && easing.constructor != Function && easing
+		};
+
+		opt.duration = (opt.duration && opt.duration.constructor == Number ?
+			opt.duration :
+			jQuery.fx.speeds[opt.duration]) || jQuery.fx.speeds.def;
+
+		// Queueing
+		opt.old = opt.complete;
+		opt.complete = function(){
+			if ( opt.queue !== false )
+				jQuery(this).dequeue();
+			if ( jQuery.isFunction( opt.old ) )
+				opt.old.call( this );
+		};
+
+		return opt;
+	},
+
+	easing: {
+		linear: function( p, n, firstNum, diff ) {
+			return firstNum + diff * p;
+		},
+		swing: function( p, n, firstNum, diff ) {
+			return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
+		}
+	},
+
+	timers: [],
+	timerId: null,
+
+	fx: function( elem, options, prop ){
+		this.options = options;
+		this.elem = elem;
+		this.prop = prop;
+
+		if ( !options.orig )
+			options.orig = {};
+	}
+
+});
+
+jQuery.fx.prototype = {
+
+	// Simple function for setting a style value
+	update: function(){
+		if ( this.options.step )
+			this.options.step.call( this.elem, this.now, this );
+
+		(jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
+
+		// Set display property to block for height/width animations
+		if ( this.prop == "height" || this.prop == "width" )
+			this.elem.style.display = "block";
+	},
+
+	// Get the current size
+	cur: function(force){
+		if ( this.elem[this.prop] != null && this.elem.style[this.prop] == null )
+			return this.elem[ this.prop ];
+
+		var r = parseFloat(jQuery.css(this.elem, this.prop, force));
+		return r && r > -10000 ? r : parseFloat(jQuery.curCSS(this.elem, this.prop)) || 0;
+	},
+
+	// Start an animation from one number to another
+	custom: function(from, to, unit){
+		this.startTime = now();
+		this.start = from;
+		this.end = to;
+		this.unit = unit || this.unit || "px";
+		this.now = this.start;
+		this.pos = this.state = 0;
+		this.update();
+
+		var self = this;
+		function t(gotoEnd){
+			return self.step(gotoEnd);
+		}
+
+		t.elem = this.elem;
+
+		jQuery.timers.push(t);
+
+		if ( jQuery.timerId == null ) {
+			jQuery.timerId = setInterval(function(){
+				var timers = jQuery.timers;
+
+				for ( var i = 0; i < timers.length; i++ )
+					if ( !timers[i]() )
+						timers.splice(i--, 1);
+
+				if ( !timers.length ) {
+					clearInterval( jQuery.timerId );
+					jQuery.timerId = null;
+				}
+			}, 13);
+		}
+	},
+
+	// Simple 'show' function
+	show: function(){
+		// Remember where we started, so that we can go back to it later
+		this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
+		this.options.show = true;
+
+		// Begin the animation
+		this.custom(0, this.cur());
+
+		// Make sure that we start at a small width/height to avoid any
+		// flash of content
+		if ( this.prop == "width" || this.prop == "height" )
+			this.elem.style[this.prop] = "1px";
+
+		// Start by showing the element
+		jQuery(this.elem).show();
+	},
+
+	// Simple 'hide' function
+	hide: function(){
+		// Remember where we started, so that we can go back to it later
+		this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
+		this.options.hide = true;
+
+		// Begin the animation
+		this.custom(this.cur(), 0);
+	},
+
+	// Each step of an animation
+	step: function(gotoEnd){
+		var t = now();
+
+		if ( gotoEnd || t > this.options.duration + this.startTime ) {
+			this.now = this.end;
+			this.pos = this.state = 1;
+			this.update();
+
+			this.options.curAnim[ this.prop ] = true;
+
+			var done = true;
+			for ( var i in this.options.curAnim )
+				if ( this.options.curAnim[i] !== true )
+					done = false;
+
+			if ( done ) {
+				if ( this.options.display != null ) {
+					// Reset the overflow
+					this.elem.style.overflow = this.options.overflow;
+
+					// Reset the display
+					this.elem.style.display = this.options.display;
+					if ( jQuery.css(this.elem, "display") == "none" )
+						this.elem.style.display = "block";
+				}
+
+				// Hide the element if the "hide" operation was done
+				if ( this.options.hide )
+					this.elem.style.display = "none";
+
+				// Reset the properties, if the item has been hidden or shown
+				if ( this.options.hide || this.options.show )
+					for ( var p in this.options.curAnim )
+						jQuery.attr(this.elem.style, p, this.options.orig[p]);
+			}
+
+			if ( done )
+				// Execute the complete function
+				this.options.complete.call( this.elem );
+
+			return false;
+		} else {
+			var n = t - this.startTime;
+			this.state = n / this.options.duration;
+
+			// Perform the easing function, defaults to swing
+			this.pos = jQuery.easing[this.options.easing || (jQuery.easing.swing ? "swing" : "linear")](this.state, n, 0, 1, this.options.duration);
+			this.now = this.start + ((this.end - this.start) * this.pos);
+
+			// Perform the next step of the animation
+			this.update();
+		}
+
+		return true;
+	}
+
+};
+
+jQuery.extend( jQuery.fx, {
+	speeds:{
+		slow: 600,
+ 		fast: 200,
+ 		// Default speed
+ 		def: 400
+	},
+	step: {
+		scrollLeft: function(fx){
+			fx.elem.scrollLeft = fx.now;
+		},
+
+		scrollTop: function(fx){
+			fx.elem.scrollTop = fx.now;
+		},
+
+		opacity: function(fx){
+			jQuery.attr(fx.elem.style, "opacity", fx.now);
+		},
+
+		_default: function(fx){
+			fx.elem.style[ fx.prop ] = fx.now + fx.unit;
+		}
+	}
+});
+// The Offset Method
+// Originally By Brandon Aaron, part of the Dimension Plugin
+// http://jquery.com/plugins/project/dimensions
+jQuery.fn.offset = function() {
+	var left = 0, top = 0, elem = this[0], results;
+
+	if ( elem ) with ( jQuery.browser ) {
+		var parent       = elem.parentNode,
+		    offsetChild  = elem,
+		    offsetParent = elem.offsetParent,
+		    doc          = elem.ownerDocument,
+		    safari2      = safari && parseInt(version) < 522 && !/adobeair/i.test(userAgent),
+		    css          = jQuery.curCSS,
+		    fixed        = css(elem, "position") == "fixed";
+
+		// Use getBoundingClientRect if available
+		if ( elem.getBoundingClientRect ) {
+			var box = elem.getBoundingClientRect();
+
+			// Add the document scroll offsets
+			add(box.left + Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft),
+				box.top  + Math.max(doc.documentElement.scrollTop,  doc.body.scrollTop));
+
+			// IE adds the HTML element's border, by default it is medium which is 2px
+			// IE 6 and 7 quirks mode the border width is overwritable by the following css html { border: 0; }
+			// IE 7 standards mode, the border is always 2px
+			// This border/offset is typically represented by the clientLeft and clientTop properties
+			// However, in IE6 and 7 quirks mode the clientLeft and clientTop properties are not updated when overwriting it via CSS
+			// Therefore this method will be off by 2px in IE while in quirksmode
+			add( -doc.documentElement.clientLeft, -doc.documentElement.clientTop );
+
+		// Otherwise loop through the offsetParents and parentNodes
+		} else {
+
+			// Initial element offsets
+			add( elem.offsetLeft, elem.offsetTop );
+
+			// Get parent offsets
+			while ( offsetParent ) {
+				// Add offsetParent offsets
+				add( offsetParent.offsetLeft, offsetParent.offsetTop );
+
+				// Mozilla and Safari > 2 does not include the border on offset parents
+				// However Mozilla adds the border for table or table cells
+				if ( mozilla && !/^t(able|d|h)$/i.test(offsetParent.tagName) || safari && !safari2 )
+					border( offsetParent );
+
+				// Add the document scroll offsets if position is fixed on any offsetParent
+				if ( !fixed && css(offsetParent, "position") == "fixed" )
+					fixed = true;
+
+				// Set offsetChild to previous offsetParent unless it is the body element
+				offsetChild  = /^body$/i.test(offsetParent.tagName) ? offsetChild : offsetParent;
+				// Get next offsetParent
+				offsetParent = offsetParent.offsetParent;
+			}
+
+			// Get parent scroll offsets
+			while ( parent && parent.tagName && !/^body|html$/i.test(parent.tagName) ) {
+				// Remove parent scroll UNLESS that parent is inline or a table to work around Opera inline/table scrollLeft/Top bug
+				if ( !/^inline|table.*$/i.test(css(parent, "display")) )
+					// Subtract parent scroll offsets
+					add( -parent.scrollLeft, -parent.scrollTop );
+
+				// Mozilla does not add the border for a parent that has overflow != visible
+				if ( mozilla && css(parent, "overflow") != "visible" )
+					border( parent );
+
+				// Get next parent
+				parent = parent.parentNode;
+			}
+
+			// Safari <= 2 doubles body offsets with a fixed position element/offsetParent or absolutely positioned offsetChild
+			// Mozilla doubles body offsets with a non-absolutely positioned offsetChild
+			if ( (safari2 && (fixed || css(offsetChild, "position") == "absolute")) ||
+				(mozilla && css(offsetChild, "position") != "absolute") )
+					add( -doc.body.offsetLeft, -doc.body.offsetTop );
+
+			// Add the document scroll offsets if position is fixed
+			if ( fixed )
+				add(Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft),
+					Math.max(doc.documentElement.scrollTop,  doc.body.scrollTop));
+		}
+
+		// Return an object with top and left properties
+		results = { top: top, left: left };
+	}
+
+	function border(elem) {
+		add( jQuery.curCSS(elem, "borderLeftWidth", true), jQuery.curCSS(elem, "borderTopWidth", true) );
+	}
+
+	function add(l, t) {
+		left += parseInt(l, 10) || 0;
+		top += parseInt(t, 10) || 0;
+	}
+
+	return results;
+};
+
+
+jQuery.fn.extend({
+	position: function() {
+		var left = 0, top = 0, results;
+
+		if ( this[0] ) {
+			// Get *real* offsetParent
+			var offsetParent = this.offsetParent(),
+
+			// Get correct offsets
+			offset       = this.offset(),
+			parentOffset = /^body|html$/i.test(offsetParent[0].tagName) ? { top: 0, left: 0 } : offsetParent.offset();
+
+			// Subtract element margins
+			// note: when an element has margin: auto the offsetLeft and marginLeft 
+			// are the same in Safari causing offset.left to incorrectly be 0
+			offset.top  -= num( this, 'marginTop' );
+			offset.left -= num( this, 'marginLeft' );
+
+			// Add offsetParent borders
+			parentOffset.top  += num( offsetParent, 'borderTopWidth' );
+			parentOffset.left += num( offsetParent, 'borderLeftWidth' );
+
+			// Subtract the two offsets
+			results = {
+				top:  offset.top  - parentOffset.top,
+				left: offset.left - parentOffset.left
+			};
+		}
+
+		return results;
+	},
+
+	offsetParent: function() {
+		var offsetParent = this[0].offsetParent;
+		while ( offsetParent && (!/^body|html$/i.test(offsetParent.tagName) && jQuery.css(offsetParent, 'position') == 'static') )
+			offsetParent = offsetParent.offsetParent;
+		return jQuery(offsetParent);
+	}
+});
+
+
+// Create scrollLeft and scrollTop methods
+jQuery.each( ['Left', 'Top'], function(i, name) {
+	var method = 'scroll' + name;
+	
+	jQuery.fn[ method ] = function(val) {
+		if (!this[0]) return;
+
+		return val != undefined ?
+
+			// Set the scroll offset
+			this.each(function() {
+				this == window || this == document ?
+					window.scrollTo(
+						!i ? val : jQuery(window).scrollLeft(),
+						 i ? val : jQuery(window).scrollTop()
+					) :
+					this[ method ] = val;
+			}) :
+
+			// Return the scroll offset
+			this[0] == window || this[0] == document ?
+				self[ i ? 'pageYOffset' : 'pageXOffset' ] ||
+					jQuery.boxModel && document.documentElement[ method ] ||
+					document.body[ method ] :
+				this[0][ method ];
+	};
+});
+// Create innerHeight, innerWidth, outerHeight and outerWidth methods
+jQuery.each([ "Height", "Width" ], function(i, name){
+
+	var tl = i ? "Left"  : "Top",  // top or left
+		br = i ? "Right" : "Bottom"; // bottom or right
+
+	// innerHeight and innerWidth
+	jQuery.fn["inner" + name] = function(){
+		return this[ name.toLowerCase() ]() +
+			num(this, "padding" + tl) +
+			num(this, "padding" + br);
+	};
+
+	// outerHeight and outerWidth
+	jQuery.fn["outer" + name] = function(margin) {
+		return this["inner" + name]() +
+			num(this, "border" + tl + "Width") +
+			num(this, "border" + br + "Width") +
+			(margin ?
+				num(this, "margin" + tl) + num(this, "margin" + br) : 0);
+	};
+
+});})();
Index: /tags/2.0.2/template-common/lib/jquery.packed.js
===================================================================
--- /tags/2.0.2/template-common/lib/jquery.packed.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/jquery.packed.js	(revision 3278)
@@ -0,0 +1,11 @@
+/*
+ * jQuery 1.2.6 - New Wave Javascript
+ *
+ * Copyright (c) 2008 John Resig (jquery.com)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * $Date: 2008-05-24 14:22:17 -0400 (Sat, 24 May 2008) $
+ * $Rev: 5685 $
+ */
+eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(H(){J w=1b.4M,3m$=1b.$;J D=1b.4M=1b.$=H(a,b){I 2B D.17.5j(a,b)};J u=/^[^<]*(<(.|\\s)+>)[^>]*$|^#(\\w+)$/,62=/^.[^:#\\[\\.]*$/,12;D.17=D.44={5j:H(d,b){d=d||S;G(d.16){7[0]=d;7.K=1;I 7}G(1j d=="23"){J c=u.2D(d);G(c&&(c[1]||!b)){G(c[1])d=D.4h([c[1]],b);N{J a=S.61(c[3]);G(a){G(a.2v!=c[3])I D().2q(d);I D(a)}d=[]}}N I D(b).2q(d)}N G(D.1D(d))I D(S)[D.17.27?"27":"43"](d);I 7.6Y(D.2d(d))},5w:"1.2.6",8G:H(){I 7.K},K:0,3p:H(a){I a==12?D.2d(7):7[a]},2I:H(b){J a=D(b);a.5n=7;I a},6Y:H(a){7.K=0;2p.44.1p.1w(7,a);I 7},P:H(a,b){I D.P(7,a,b)},5i:H(b){J a=-1;I D.2L(b&&b.5w?b[0]:b,7)},1K:H(c,a,b){J d=c;G(c.1q==56)G(a===12)I 7[0]&&D[b||"1K"](7[0],c);N{d={};d[c]=a}I 7.P(H(i){R(c 1n d)D.1K(b?7.V:7,c,D.1i(7,d[c],b,i,c))})},1g:H(b,a){G((b==\'2h\'||b==\'1Z\')&&3d(a)<0)a=12;I 7.1K(b,a,"2a")},1r:H(b){G(1j b!="49"&&b!=U)I 7.4E().3v((7[0]&&7[0].2z||S).5F(b));J a="";D.P(b||7,H(){D.P(7.3t,H(){G(7.16!=8)a+=7.16!=1?7.76:D.17.1r([7])})});I a},5z:H(b){G(7[0])D(b,7[0].2z).5y().39(7[0]).2l(H(){J a=7;1B(a.1x)a=a.1x;I a}).3v(7);I 7},8Y:H(a){I 7.P(H(){D(7).6Q().5z(a)})},8R:H(a){I 7.P(H(){D(7).5z(a)})},3v:H(){I 7.3W(19,M,Q,H(a){G(7.16==1)7.3U(a)})},6F:H(){I 7.3W(19,M,M,H(a){G(7.16==1)7.39(a,7.1x)})},6E:H(){I 7.3W(19,Q,Q,H(a){7.1d.39(a,7)})},5q:H(){I 7.3W(19,Q,M,H(a){7.1d.39(a,7.2H)})},3l:H(){I 7.5n||D([])},2q:H(b){J c=D.2l(7,H(a){I D.2q(b,a)});I 7.2I(/[^+>] [^+>]/.11(b)||b.1h("..")>-1?D.4r(c):c)},5y:H(e){J f=7.2l(H(){G(D.14.1f&&!D.4n(7)){J a=7.6o(M),5h=S.3h("1v");5h.3U(a);I D.4h([5h.4H])[0]}N I 7.6o(M)});J d=f.2q("*").5c().P(H(){G(7[E]!=12)7[E]=U});G(e===M)7.2q("*").5c().P(H(i){G(7.16==3)I;J c=D.L(7,"3w");R(J a 1n c)R(J b 1n c[a])D.W.1e(d[i],a,c[a][b],c[a][b].L)});I f},1E:H(b){I 7.2I(D.1D(b)&&D.3C(7,H(a,i){I b.1k(a,i)})||D.3g(b,7))},4Y:H(b){G(b.1q==56)G(62.11(b))I 7.2I(D.3g(b,7,M));N b=D.3g(b,7);J a=b.K&&b[b.K-1]!==12&&!b.16;I 7.1E(H(){I a?D.2L(7,b)<0:7!=b})},1e:H(a){I 7.2I(D.4r(D.2R(7.3p(),1j a==\'23\'?D(a):D.2d(a))))},3F:H(a){I!!a&&D.3g(a,7).K>0},7T:H(a){I 7.3F("."+a)},6e:H(b){G(b==12){G(7.K){J c=7[0];G(D.Y(c,"2A")){J e=c.64,63=[],15=c.15,2V=c.O=="2A-2V";G(e<0)I U;R(J i=2V?e:0,2f=2V?e+1:15.K;i<2f;i++){J d=15[i];G(d.2W){b=D.14.1f&&!d.at.2x.an?d.1r:d.2x;G(2V)I b;63.1p(b)}}I 63}N I(7[0].2x||"").1o(/\\r/g,"")}I 12}G(b.1q==4L)b+=\'\';I 7.P(H(){G(7.16!=1)I;G(b.1q==2p&&/5O|5L/.11(7.O))7.4J=(D.2L(7.2x,b)>=0||D.2L(7.34,b)>=0);N G(D.Y(7,"2A")){J a=D.2d(b);D("9R",7).P(H(){7.2W=(D.2L(7.2x,a)>=0||D.2L(7.1r,a)>=0)});G(!a.K)7.64=-1}N 7.2x=b})},2K:H(a){I a==12?(7[0]?7[0].4H:U):7.4E().3v(a)},7b:H(a){I 7.5q(a).21()},79:H(i){I 7.3s(i,i+1)},3s:H(){I 7.2I(2p.44.3s.1w(7,19))},2l:H(b){I 7.2I(D.2l(7,H(a,i){I b.1k(a,i,a)}))},5c:H(){I 7.1e(7.5n)},L:H(d,b){J a=d.1R(".");a[1]=a[1]?"."+a[1]:"";G(b===12){J c=7.5C("9z"+a[1]+"!",[a[0]]);G(c===12&&7.K)c=D.L(7[0],d);I c===12&&a[1]?7.L(a[0]):c}N I 7.1P("9u"+a[1]+"!",[a[0],b]).P(H(){D.L(7,d,b)})},3b:H(a){I 7.P(H(){D.3b(7,a)})},3W:H(g,f,h,d){J e=7.K>1,3x;I 7.P(H(){G(!3x){3x=D.4h(g,7.2z);G(h)3x.9o()}J b=7;G(f&&D.Y(7,"1T")&&D.Y(3x[0],"4F"))b=7.3H("22")[0]||7.3U(7.2z.3h("22"));J c=D([]);D.P(3x,H(){J a=e?D(7).5y(M)[0]:7;G(D.Y(a,"1m"))c=c.1e(a);N{G(a.16==1)c=c.1e(D("1m",a).21());d.1k(b,a)}});c.P(6T)})}};D.17.5j.44=D.17;H 6T(i,a){G(a.4d)D.3Y({1a:a.4d,31:Q,1O:"1m"});N D.5u(a.1r||a.6O||a.4H||"");G(a.1d)a.1d.37(a)}H 1z(){I+2B 8J}D.1l=D.17.1l=H(){J b=19[0]||{},i=1,K=19.K,4x=Q,15;G(b.1q==8I){4x=b;b=19[1]||{};i=2}G(1j b!="49"&&1j b!="H")b={};G(K==i){b=7;--i}R(;i<K;i++)G((15=19[i])!=U)R(J c 1n 15){J a=b[c],2w=15[c];G(b===2w)6M;G(4x&&2w&&1j 2w=="49"&&!2w.16)b[c]=D.1l(4x,a||(2w.K!=U?[]:{}),2w);N G(2w!==12)b[c]=2w}I b};J E="4M"+1z(),6K=0,5r={},6G=/z-?5i|8B-?8A|1y|6B|8v-?1Z/i,3P=S.3P||{};D.1l({8u:H(a){1b.$=3m$;G(a)1b.4M=w;I D},1D:H(a){I!!a&&1j a!="23"&&!a.Y&&a.1q!=2p&&/^[\\s[]?H/.11(a+"")},4n:H(a){I a.1C&&!a.1c||a.2j&&a.2z&&!a.2z.1c},5u:H(a){a=D.3k(a);G(a){J b=S.3H("6w")[0]||S.1C,1m=S.3h("1m");1m.O="1r/4t";G(D.14.1f)1m.1r=a;N 1m.3U(S.5F(a));b.39(1m,b.1x);b.37(1m)}},Y:H(b,a){I b.Y&&b.Y.2r()==a.2r()},1Y:{},L:H(c,d,b){c=c==1b?5r:c;J a=c[E];G(!a)a=c[E]=++6K;G(d&&!D.1Y[a])D.1Y[a]={};G(b!==12)D.1Y[a][d]=b;I d?D.1Y[a][d]:a},3b:H(c,b){c=c==1b?5r:c;J a=c[E];G(b){G(D.1Y[a]){2U D.1Y[a][b];b="";R(b 1n D.1Y[a])1X;G(!b)D.3b(c)}}N{1U{2U c[E]}1V(e){G(c.5l)c.5l(E)}2U D.1Y[a]}},P:H(d,a,c){J e,i=0,K=d.K;G(c){G(K==12){R(e 1n d)G(a.1w(d[e],c)===Q)1X}N R(;i<K;)G(a.1w(d[i++],c)===Q)1X}N{G(K==12){R(e 1n d)G(a.1k(d[e],e,d[e])===Q)1X}N R(J b=d[0];i<K&&a.1k(b,i,b)!==Q;b=d[++i]){}}I d},1i:H(b,a,c,i,d){G(D.1D(a))a=a.1k(b,i);I a&&a.1q==4L&&c=="2a"&&!6G.11(d)?a+"2X":a},1F:{1e:H(c,b){D.P((b||"").1R(/\\s+/),H(i,a){G(c.16==1&&!D.1F.3T(c.1F,a))c.1F+=(c.1F?" ":"")+a})},21:H(c,b){G(c.16==1)c.1F=b!=12?D.3C(c.1F.1R(/\\s+/),H(a){I!D.1F.3T(b,a)}).6s(" "):""},3T:H(b,a){I D.2L(a,(b.1F||b).6r().1R(/\\s+/))>-1}},6q:H(b,c,a){J e={};R(J d 1n c){e[d]=b.V[d];b.V[d]=c[d]}a.1k(b);R(J d 1n c)b.V[d]=e[d]},1g:H(d,e,c){G(e=="2h"||e=="1Z"){J b,3X={30:"5x",5g:"1G",18:"3I"},35=e=="2h"?["5e","6k"]:["5G","6i"];H 5b(){b=e=="2h"?d.8f:d.8c;J a=0,2C=0;D.P(35,H(){a+=3d(D.2a(d,"57"+7,M))||0;2C+=3d(D.2a(d,"2C"+7+"4b",M))||0});b-=29.83(a+2C)}G(D(d).3F(":4j"))5b();N D.6q(d,3X,5b);I 29.2f(0,b)}I D.2a(d,e,c)},2a:H(f,l,k){J e,V=f.V;H 3E(b){G(!D.14.2k)I Q;J a=3P.54(b,U);I!a||a.52("3E")==""}G(l=="1y"&&D.14.1f){e=D.1K(V,"1y");I e==""?"1":e}G(D.14.2G&&l=="18"){J d=V.50;V.50="0 7Y 7W";V.50=d}G(l.1I(/4i/i))l=y;G(!k&&V&&V[l])e=V[l];N G(3P.54){G(l.1I(/4i/i))l="4i";l=l.1o(/([A-Z])/g,"-$1").3y();J c=3P.54(f,U);G(c&&!3E(f))e=c.52(l);N{J g=[],2E=[],a=f,i=0;R(;a&&3E(a);a=a.1d)2E.6h(a);R(;i<2E.K;i++)G(3E(2E[i])){g[i]=2E[i].V.18;2E[i].V.18="3I"}e=l=="18"&&g[2E.K-1]!=U?"2F":(c&&c.52(l))||"";R(i=0;i<g.K;i++)G(g[i]!=U)2E[i].V.18=g[i]}G(l=="1y"&&e=="")e="1"}N G(f.4g){J h=l.1o(/\\-(\\w)/g,H(a,b){I b.2r()});e=f.4g[l]||f.4g[h];G(!/^\\d+(2X)?$/i.11(e)&&/^\\d/.11(e)){J j=V.1A,66=f.65.1A;f.65.1A=f.4g.1A;V.1A=e||0;e=V.aM+"2X";V.1A=j;f.65.1A=66}}I e},4h:H(l,h){J k=[];h=h||S;G(1j h.3h==\'12\')h=h.2z||h[0]&&h[0].2z||S;D.P(l,H(i,d){G(!d)I;G(d.1q==4L)d+=\'\';G(1j d=="23"){d=d.1o(/(<(\\w+)[^>]*?)\\/>/g,H(b,a,c){I c.1I(/^(aK|4f|7E|aG|4T|7A|aB|3n|az|ay|av)$/i)?b:a+"></"+c+">"});J f=D.3k(d).3y(),1v=h.3h("1v");J e=!f.1h("<au")&&[1,"<2A 7w=\'7w\'>","</2A>"]||!f.1h("<ar")&&[1,"<7v>","</7v>"]||f.1I(/^<(aq|22|am|ak|ai)/)&&[1,"<1T>","</1T>"]||!f.1h("<4F")&&[2,"<1T><22>","</22></1T>"]||(!f.1h("<af")||!f.1h("<ad"))&&[3,"<1T><22><4F>","</4F></22></1T>"]||!f.1h("<7E")&&[2,"<1T><22></22><7q>","</7q></1T>"]||D.14.1f&&[1,"1v<1v>","</1v>"]||[0,"",""];1v.4H=e[1]+d+e[2];1B(e[0]--)1v=1v.5T;G(D.14.1f){J g=!f.1h("<1T")&&f.1h("<22")<0?1v.1x&&1v.1x.3t:e[1]=="<1T>"&&f.1h("<22")<0?1v.3t:[];R(J j=g.K-1;j>=0;--j)G(D.Y(g[j],"22")&&!g[j].3t.K)g[j].1d.37(g[j]);G(/^\\s/.11(d))1v.39(h.5F(d.1I(/^\\s*/)[0]),1v.1x)}d=D.2d(1v.3t)}G(d.K===0&&(!D.Y(d,"3V")&&!D.Y(d,"2A")))I;G(d[0]==12||D.Y(d,"3V")||d.15)k.1p(d);N k=D.2R(k,d)});I k},1K:H(d,f,c){G(!d||d.16==3||d.16==8)I 12;J e=!D.4n(d),40=c!==12,1f=D.14.1f;f=e&&D.3X[f]||f;G(d.2j){J g=/5Q|4d|V/.11(f);G(f=="2W"&&D.14.2k)d.1d.64;G(f 1n d&&e&&!g){G(40){G(f=="O"&&D.Y(d,"4T")&&d.1d)7p"O a3 a1\'t 9V 9U";d[f]=c}G(D.Y(d,"3V")&&d.7i(f))I d.7i(f).76;I d[f]}G(1f&&e&&f=="V")I D.1K(d.V,"9T",c);G(40)d.9Q(f,""+c);J h=1f&&e&&g?d.4G(f,2):d.4G(f);I h===U?12:h}G(1f&&f=="1y"){G(40){d.6B=1;d.1E=(d.1E||"").1o(/7f\\([^)]*\\)/,"")+(3r(c)+\'\'=="9L"?"":"7f(1y="+c*7a+")")}I d.1E&&d.1E.1h("1y=")>=0?(3d(d.1E.1I(/1y=([^)]*)/)[1])/7a)+\'\':""}f=f.1o(/-([a-z])/9H,H(a,b){I b.2r()});G(40)d[f]=c;I d[f]},3k:H(a){I(a||"").1o(/^\\s+|\\s+$/g,"")},2d:H(b){J a=[];G(b!=U){J i=b.K;G(i==U||b.1R||b.4I||b.1k)a[0]=b;N 1B(i)a[--i]=b[i]}I a},2L:H(b,a){R(J i=0,K=a.K;i<K;i++)G(a[i]===b)I i;I-1},2R:H(a,b){J i=0,T,2S=a.K;G(D.14.1f){1B(T=b[i++])G(T.16!=8)a[2S++]=T}N 1B(T=b[i++])a[2S++]=T;I a},4r:H(a){J c=[],2o={};1U{R(J i=0,K=a.K;i<K;i++){J b=D.L(a[i]);G(!2o[b]){2o[b]=M;c.1p(a[i])}}}1V(e){c=a}I c},3C:H(c,a,d){J b=[];R(J i=0,K=c.K;i<K;i++)G(!d!=!a(c[i],i))b.1p(c[i]);I b},2l:H(d,a){J c=[];R(J i=0,K=d.K;i<K;i++){J b=a(d[i],i);G(b!=U)c[c.K]=b}I c.7d.1w([],c)}});J v=9B.9A.3y();D.14={5B:(v.1I(/.+(?:9y|9x|9w|9v)[\\/: ]([\\d.]+)/)||[])[1],2k:/75/.11(v),2G:/2G/.11(v),1f:/1f/.11(v)&&!/2G/.11(v),42:/42/.11(v)&&!/(9s|75)/.11(v)};J y=D.14.1f?"7o":"72";D.1l({71:!D.14.1f||S.70=="6Z",3X:{"R":"9n","9k":"1F","4i":y,72:y,7o:y,9h:"9f",9e:"9d",9b:"99"}});D.P({6W:H(a){I a.1d},97:H(a){I D.4S(a,"1d")},95:H(a){I D.3a(a,2,"2H")},91:H(a){I D.3a(a,2,"4l")},8Z:H(a){I D.4S(a,"2H")},8X:H(a){I D.4S(a,"4l")},8W:H(a){I D.5v(a.1d.1x,a)},8V:H(a){I D.5v(a.1x)},6Q:H(a){I D.Y(a,"8U")?a.8T||a.8S.S:D.2d(a.3t)}},H(c,d){D.17[c]=H(b){J a=D.2l(7,d);G(b&&1j b=="23")a=D.3g(b,a);I 7.2I(D.4r(a))}});D.P({6P:"3v",8Q:"6F",39:"6E",8P:"5q",8O:"7b"},H(c,b){D.17[c]=H(){J a=19;I 7.P(H(){R(J i=0,K=a.K;i<K;i++)D(a[i])[b](7)})}});D.P({8N:H(a){D.1K(7,a,"");G(7.16==1)7.5l(a)},8M:H(a){D.1F.1e(7,a)},8L:H(a){D.1F.21(7,a)},8K:H(a){D.1F[D.1F.3T(7,a)?"21":"1e"](7,a)},21:H(a){G(!a||D.1E(a,[7]).r.K){D("*",7).1e(7).P(H(){D.W.21(7);D.3b(7)});G(7.1d)7.1d.37(7)}},4E:H(){D(">*",7).21();1B(7.1x)7.37(7.1x)}},H(a,b){D.17[a]=H(){I 7.P(b,19)}});D.P(["6N","4b"],H(i,c){J b=c.3y();D.17[b]=H(a){I 7[0]==1b?D.14.2G&&S.1c["5t"+c]||D.14.2k&&1b["5s"+c]||S.70=="6Z"&&S.1C["5t"+c]||S.1c["5t"+c]:7[0]==S?29.2f(29.2f(S.1c["4y"+c],S.1C["4y"+c]),29.2f(S.1c["2i"+c],S.1C["2i"+c])):a==12?(7.K?D.1g(7[0],b):U):7.1g(b,a.1q==56?a:a+"2X")}});H 25(a,b){I a[0]&&3r(D.2a(a[0],b,M),10)||0}J C=D.14.2k&&3r(D.14.5B)<8H?"(?:[\\\\w*3m-]|\\\\\\\\.)":"(?:[\\\\w\\8F-\\8E*3m-]|\\\\\\\\.)",6L=2B 4v("^>\\\\s*("+C+"+)"),6J=2B 4v("^("+C+"+)(#)("+C+"+)"),6I=2B 4v("^([#.]?)("+C+"*)");D.1l({6H:{"":H(a,i,m){I m[2]=="*"||D.Y(a,m[2])},"#":H(a,i,m){I a.4G("2v")==m[2]},":":{8D:H(a,i,m){I i<m[3]-0},8C:H(a,i,m){I i>m[3]-0},3a:H(a,i,m){I m[3]-0==i},79:H(a,i,m){I m[3]-0==i},3o:H(a,i){I i==0},3S:H(a,i,m,r){I i==r.K-1},6D:H(a,i){I i%2==0},6C:H(a,i){I i%2},"3o-4u":H(a){I a.1d.3H("*")[0]==a},"3S-4u":H(a){I D.3a(a.1d.5T,1,"4l")==a},"8z-4u":H(a){I!D.3a(a.1d.5T,2,"4l")},6W:H(a){I a.1x},4E:H(a){I!a.1x},8y:H(a,i,m){I(a.6O||a.8x||D(a).1r()||"").1h(m[3])>=0},4j:H(a){I"1G"!=a.O&&D.1g(a,"18")!="2F"&&D.1g(a,"5g")!="1G"},1G:H(a){I"1G"==a.O||D.1g(a,"18")=="2F"||D.1g(a,"5g")=="1G"},8w:H(a){I!a.3R},3R:H(a){I a.3R},4J:H(a){I a.4J},2W:H(a){I a.2W||D.1K(a,"2W")},1r:H(a){I"1r"==a.O},5O:H(a){I"5O"==a.O},5L:H(a){I"5L"==a.O},5p:H(a){I"5p"==a.O},3Q:H(a){I"3Q"==a.O},5o:H(a){I"5o"==a.O},6A:H(a){I"6A"==a.O},6z:H(a){I"6z"==a.O},2s:H(a){I"2s"==a.O||D.Y(a,"2s")},4T:H(a){I/4T|2A|6y|2s/i.11(a.Y)},3T:H(a,i,m){I D.2q(m[3],a).K},8t:H(a){I/h\\d/i.11(a.Y)},8s:H(a){I D.3C(D.3O,H(b){I a==b.T}).K}}},6x:[/^(\\[) *@?([\\w-]+) *([!*$^~=]*) *(\'?"?)(.*?)\\4 *\\]/,/^(:)([\\w-]+)\\("?\'?(.*?(\\(.*?\\))?[^(]*?)"?\'?\\)/,2B 4v("^([:.#]*)("+C+"+)")],3g:H(a,c,b){J d,1t=[];1B(a&&a!=d){d=a;J f=D.1E(a,c,b);a=f.t.1o(/^\\s*,\\s*/,"");1t=b?c=f.r:D.2R(1t,f.r)}I 1t},2q:H(t,o){G(1j t!="23")I[t];G(o&&o.16!=1&&o.16!=9)I[];o=o||S;J d=[o],2o=[],3S,Y;1B(t&&3S!=t){J r=[];3S=t;t=D.3k(t);J l=Q,3j=6L,m=3j.2D(t);G(m){Y=m[1].2r();R(J i=0;d[i];i++)R(J c=d[i].1x;c;c=c.2H)G(c.16==1&&(Y=="*"||c.Y.2r()==Y))r.1p(c);d=r;t=t.1o(3j,"");G(t.1h(" ")==0)6M;l=M}N{3j=/^([>+~])\\s*(\\w*)/i;G((m=3j.2D(t))!=U){r=[];J k={};Y=m[2].2r();m=m[1];R(J j=0,3i=d.K;j<3i;j++){J n=m=="~"||m=="+"?d[j].2H:d[j].1x;R(;n;n=n.2H)G(n.16==1){J g=D.L(n);G(m=="~"&&k[g])1X;G(!Y||n.Y.2r()==Y){G(m=="~")k[g]=M;r.1p(n)}G(m=="+")1X}}d=r;t=D.3k(t.1o(3j,""));l=M}}G(t&&!l){G(!t.1h(",")){G(o==d[0])d.4s();2o=D.2R(2o,d);r=d=[o];t=" "+t.6v(1,t.K)}N{J h=6J;J m=h.2D(t);G(m){m=[0,m[2],m[3],m[1]]}N{h=6I;m=h.2D(t)}m[2]=m[2].1o(/\\\\/g,"");J f=d[d.K-1];G(m[1]=="#"&&f&&f.61&&!D.4n(f)){J p=f.61(m[2]);G((D.14.1f||D.14.2G)&&p&&1j p.2v=="23"&&p.2v!=m[2])p=D(\'[@2v="\'+m[2]+\'"]\',f)[0];d=r=p&&(!m[3]||D.Y(p,m[3]))?[p]:[]}N{R(J i=0;d[i];i++){J a=m[1]=="#"&&m[3]?m[3]:m[1]!=""||m[0]==""?"*":m[2];G(a=="*"&&d[i].Y.3y()=="49")a="3n";r=D.2R(r,d[i].3H(a))}G(m[1]==".")r=D.5m(r,m[2]);G(m[1]=="#"){J e=[];R(J i=0;r[i];i++)G(r[i].4G("2v")==m[2]){e=[r[i]];1X}r=e}d=r}t=t.1o(h,"")}}G(t){J b=D.1E(t,r);d=r=b.r;t=D.3k(b.t)}}G(t)d=[];G(d&&o==d[0])d.4s();2o=D.2R(2o,d);I 2o},5m:H(r,m,a){m=" "+m+" ";J c=[];R(J i=0;r[i];i++){J b=(" "+r[i].1F+" ").1h(m)>=0;G(!a&&b||a&&!b)c.1p(r[i])}I c},1E:H(t,r,h){J d;1B(t&&t!=d){d=t;J p=D.6x,m;R(J i=0;p[i];i++){m=p[i].2D(t);G(m){t=t.8r(m[0].K);m[2]=m[2].1o(/\\\\/g,"");1X}}G(!m)1X;G(m[1]==":"&&m[2]=="4Y")r=62.11(m[3])?D.1E(m[3],r,M).r:D(r).4Y(m[3]);N G(m[1]==".")r=D.5m(r,m[2],h);N G(m[1]=="["){J g=[],O=m[3];R(J i=0,3i=r.K;i<3i;i++){J a=r[i],z=a[D.3X[m[2]]||m[2]];G(z==U||/5Q|4d|2W/.11(m[2]))z=D.1K(a,m[2])||\'\';G((O==""&&!!z||O=="="&&z==m[5]||O=="!="&&z!=m[5]||O=="^="&&z&&!z.1h(m[5])||O=="$="&&z.6v(z.K-m[5].K)==m[5]||(O=="*="||O=="~=")&&z.1h(m[5])>=0)^h)g.1p(a)}r=g}N G(m[1]==":"&&m[2]=="3a-4u"){J e={},g=[],11=/(-?)(\\d*)n((?:\\+|-)?\\d*)/.2D(m[3]=="6D"&&"2n"||m[3]=="6C"&&"2n+1"||!/\\D/.11(m[3])&&"8q+"+m[3]||m[3]),3o=(11[1]+(11[2]||1))-0,d=11[3]-0;R(J i=0,3i=r.K;i<3i;i++){J j=r[i],1d=j.1d,2v=D.L(1d);G(!e[2v]){J c=1;R(J n=1d.1x;n;n=n.2H)G(n.16==1)n.4q=c++;e[2v]=M}J b=Q;G(3o==0){G(j.4q==d)b=M}N G((j.4q-d)%3o==0&&(j.4q-d)/3o>=0)b=M;G(b^h)g.1p(j)}r=g}N{J f=D.6H[m[1]];G(1j f=="49")f=f[m[2]];G(1j f=="23")f=6u("Q||H(a,i){I "+f+";}");r=D.3C(r,H(a,i){I f(a,i,m,r)},h)}}I{r:r,t:t}},4S:H(b,c){J a=[],1t=b[c];1B(1t&&1t!=S){G(1t.16==1)a.1p(1t);1t=1t[c]}I a},3a:H(a,e,c,b){e=e||1;J d=0;R(;a;a=a[c])G(a.16==1&&++d==e)1X;I a},5v:H(n,a){J r=[];R(;n;n=n.2H){G(n.16==1&&n!=a)r.1p(n)}I r}});D.W={1e:H(f,i,g,e){G(f.16==3||f.16==8)I;G(D.14.1f&&f.4I)f=1b;G(!g.24)g.24=7.24++;G(e!=12){J h=g;g=7.3M(h,H(){I h.1w(7,19)});g.L=e}J j=D.L(f,"3w")||D.L(f,"3w",{}),1H=D.L(f,"1H")||D.L(f,"1H",H(){G(1j D!="12"&&!D.W.5k)I D.W.1H.1w(19.3L.T,19)});1H.T=f;D.P(i.1R(/\\s+/),H(c,b){J a=b.1R(".");b=a[0];g.O=a[1];J d=j[b];G(!d){d=j[b]={};G(!D.W.2t[b]||D.W.2t[b].4p.1k(f)===Q){G(f.3K)f.3K(b,1H,Q);N G(f.6t)f.6t("4o"+b,1H)}}d[g.24]=g;D.W.26[b]=M});f=U},24:1,26:{},21:H(e,h,f){G(e.16==3||e.16==8)I;J i=D.L(e,"3w"),1L,5i;G(i){G(h==12||(1j h=="23"&&h.8p(0)=="."))R(J g 1n i)7.21(e,g+(h||""));N{G(h.O){f=h.2y;h=h.O}D.P(h.1R(/\\s+/),H(b,a){J c=a.1R(".");a=c[0];G(i[a]){G(f)2U i[a][f.24];N R(f 1n i[a])G(!c[1]||i[a][f].O==c[1])2U i[a][f];R(1L 1n i[a])1X;G(!1L){G(!D.W.2t[a]||D.W.2t[a].4A.1k(e)===Q){G(e.6p)e.6p(a,D.L(e,"1H"),Q);N G(e.6n)e.6n("4o"+a,D.L(e,"1H"))}1L=U;2U i[a]}}})}R(1L 1n i)1X;G(!1L){J d=D.L(e,"1H");G(d)d.T=U;D.3b(e,"3w");D.3b(e,"1H")}}},1P:H(h,c,f,g,i){c=D.2d(c);G(h.1h("!")>=0){h=h.3s(0,-1);J a=M}G(!f){G(7.26[h])D("*").1e([1b,S]).1P(h,c)}N{G(f.16==3||f.16==8)I 12;J b,1L,17=D.1D(f[h]||U),W=!c[0]||!c[0].32;G(W){c.6h({O:h,2J:f,32:H(){},3J:H(){},4C:1z()});c[0][E]=M}c[0].O=h;G(a)c[0].6m=M;J d=D.L(f,"1H");G(d)b=d.1w(f,c);G((!17||(D.Y(f,\'a\')&&h=="4V"))&&f["4o"+h]&&f["4o"+h].1w(f,c)===Q)b=Q;G(W)c.4s();G(i&&D.1D(i)){1L=i.1w(f,b==U?c:c.7d(b));G(1L!==12)b=1L}G(17&&g!==Q&&b!==Q&&!(D.Y(f,\'a\')&&h=="4V")){7.5k=M;1U{f[h]()}1V(e){}}7.5k=Q}I b},1H:H(b){J a,1L,38,5f,4m;b=19[0]=D.W.6l(b||1b.W);38=b.O.1R(".");b.O=38[0];38=38[1];5f=!38&&!b.6m;4m=(D.L(7,"3w")||{})[b.O];R(J j 1n 4m){J c=4m[j];G(5f||c.O==38){b.2y=c;b.L=c.L;1L=c.1w(7,19);G(a!==Q)a=1L;G(1L===Q){b.32();b.3J()}}}I a},6l:H(b){G(b[E]==M)I b;J d=b;b={8o:d};J c="8n 8m 8l 8k 2s 8j 47 5d 6j 5E 8i L 8h 8g 4K 2y 5a 59 8e 8b 58 6f 8a 88 4k 87 86 84 6d 2J 4C 6c O 82 81 35".1R(" ");R(J i=c.K;i;i--)b[c[i]]=d[c[i]];b[E]=M;b.32=H(){G(d.32)d.32();d.80=Q};b.3J=H(){G(d.3J)d.3J();d.7Z=M};b.4C=b.4C||1z();G(!b.2J)b.2J=b.6d||S;G(b.2J.16==3)b.2J=b.2J.1d;G(!b.4k&&b.4K)b.4k=b.4K==b.2J?b.6c:b.4K;G(b.58==U&&b.5d!=U){J a=S.1C,1c=S.1c;b.58=b.5d+(a&&a.2e||1c&&1c.2e||0)-(a.6b||0);b.6f=b.6j+(a&&a.2c||1c&&1c.2c||0)-(a.6a||0)}G(!b.35&&((b.47||b.47===0)?b.47:b.5a))b.35=b.47||b.5a;G(!b.59&&b.5E)b.59=b.5E;G(!b.35&&b.2s)b.35=(b.2s&1?1:(b.2s&2?3:(b.2s&4?2:0)));I b},3M:H(a,b){b.24=a.24=a.24||b.24||7.24++;I b},2t:{27:{4p:H(){55();I},4A:H(){I}},3D:{4p:H(){G(D.14.1f)I Q;D(7).2O("53",D.W.2t.3D.2y);I M},4A:H(){G(D.14.1f)I Q;D(7).4e("53",D.W.2t.3D.2y);I M},2y:H(a){G(F(a,7))I M;a.O="3D";I D.W.1H.1w(7,19)}},3N:{4p:H(){G(D.14.1f)I Q;D(7).2O("51",D.W.2t.3N.2y);I M},4A:H(){G(D.14.1f)I Q;D(7).4e("51",D.W.2t.3N.2y);I M},2y:H(a){G(F(a,7))I M;a.O="3N";I D.W.1H.1w(7,19)}}}};D.17.1l({2O:H(c,a,b){I c=="4X"?7.2V(c,a,b):7.P(H(){D.W.1e(7,c,b||a,b&&a)})},2V:H(d,b,c){J e=D.W.3M(c||b,H(a){D(7).4e(a,e);I(c||b).1w(7,19)});I 7.P(H(){D.W.1e(7,d,e,c&&b)})},4e:H(a,b){I 7.P(H(){D.W.21(7,a,b)})},1P:H(c,a,b){I 7.P(H(){D.W.1P(c,a,7,M,b)})},5C:H(c,a,b){I 7[0]&&D.W.1P(c,a,7[0],Q,b)},2m:H(b){J c=19,i=1;1B(i<c.K)D.W.3M(b,c[i++]);I 7.4V(D.W.3M(b,H(a){7.4Z=(7.4Z||0)%i;a.32();I c[7.4Z++].1w(7,19)||Q}))},7X:H(a,b){I 7.2O(\'3D\',a).2O(\'3N\',b)},27:H(a){55();G(D.2Q)a.1k(S,D);N D.3A.1p(H(){I a.1k(7,D)});I 7}});D.1l({2Q:Q,3A:[],27:H(){G(!D.2Q){D.2Q=M;G(D.3A){D.P(D.3A,H(){7.1k(S)});D.3A=U}D(S).5C("27")}}});J x=Q;H 55(){G(x)I;x=M;G(S.3K&&!D.14.2G)S.3K("69",D.27,Q);G(D.14.1f&&1b==1S)(H(){G(D.2Q)I;1U{S.1C.7V("1A")}1V(3e){3B(19.3L,0);I}D.27()})();G(D.14.2G)S.3K("69",H(){G(D.2Q)I;R(J i=0;i<S.4W.K;i++)G(S.4W[i].3R){3B(19.3L,0);I}D.27()},Q);G(D.14.2k){J a;(H(){G(D.2Q)I;G(S.3f!="68"&&S.3f!="1J"){3B(19.3L,0);I}G(a===12)a=D("V, 7A[7U=7S]").K;G(S.4W.K!=a){3B(19.3L,0);I}D.27()})()}D.W.1e(1b,"43",D.27)}D.P(("7R,7Q,43,85,4y,4X,4V,7P,"+"7O,7N,89,53,51,7M,2A,"+"5o,7L,7K,8d,3e").1R(","),H(i,b){D.17[b]=H(a){I a?7.2O(b,a):7.1P(b)}});J F=H(a,c){J b=a.4k;1B(b&&b!=c)1U{b=b.1d}1V(3e){b=c}I b==c};D(1b).2O("4X",H(){D("*").1e(S).4e()});D.17.1l({67:D.17.43,43:H(g,d,c){G(1j g!=\'23\')I 7.67(g);J e=g.1h(" ");G(e>=0){J i=g.3s(e,g.K);g=g.3s(0,e)}c=c||H(){};J f="2P";G(d)G(D.1D(d)){c=d;d=U}N{d=D.3n(d);f="6g"}J h=7;D.3Y({1a:g,O:f,1O:"2K",L:d,1J:H(a,b){G(b=="1W"||b=="7J")h.2K(i?D("<1v/>").3v(a.4U.1o(/<1m(.|\\s)*?\\/1m>/g,"")).2q(i):a.4U);h.P(c,[a.4U,b,a])}});I 7},aL:H(){I D.3n(7.7I())},7I:H(){I 7.2l(H(){I D.Y(7,"3V")?D.2d(7.aH):7}).1E(H(){I 7.34&&!7.3R&&(7.4J||/2A|6y/i.11(7.Y)||/1r|1G|3Q/i.11(7.O))}).2l(H(i,c){J b=D(7).6e();I b==U?U:b.1q==2p?D.2l(b,H(a,i){I{34:c.34,2x:a}}):{34:c.34,2x:b}}).3p()}});D.P("7H,7G,7F,7D,7C,7B".1R(","),H(i,o){D.17[o]=H(f){I 7.2O(o,f)}});J B=1z();D.1l({3p:H(d,b,a,c){G(D.1D(b)){a=b;b=U}I D.3Y({O:"2P",1a:d,L:b,1W:a,1O:c})},aE:H(b,a){I D.3p(b,U,a,"1m")},aD:H(c,b,a){I D.3p(c,b,a,"3z")},aC:H(d,b,a,c){G(D.1D(b)){a=b;b={}}I D.3Y({O:"6g",1a:d,L:b,1W:a,1O:c})},aA:H(a){D.1l(D.60,a)},60:{1a:5Z.5Q,26:M,O:"2P",2T:0,7z:"4R/x-ax-3V-aw",7x:M,31:M,L:U,5Y:U,3Q:U,4Q:{2N:"4R/2N, 1r/2N",2K:"1r/2K",1m:"1r/4t, 4R/4t",3z:"4R/3z, 1r/4t",1r:"1r/as",4w:"*/*"}},4z:{},3Y:H(s){s=D.1l(M,s,D.1l(M,{},D.60,s));J g,2Z=/=\\?(&|$)/g,1u,L,O=s.O.2r();G(s.L&&s.7x&&1j s.L!="23")s.L=D.3n(s.L);G(s.1O=="4P"){G(O=="2P"){G(!s.1a.1I(2Z))s.1a+=(s.1a.1I(/\\?/)?"&":"?")+(s.4P||"7u")+"=?"}N G(!s.L||!s.L.1I(2Z))s.L=(s.L?s.L+"&":"")+(s.4P||"7u")+"=?";s.1O="3z"}G(s.1O=="3z"&&(s.L&&s.L.1I(2Z)||s.1a.1I(2Z))){g="4P"+B++;G(s.L)s.L=(s.L+"").1o(2Z,"="+g+"$1");s.1a=s.1a.1o(2Z,"="+g+"$1");s.1O="1m";1b[g]=H(a){L=a;1W();1J();1b[g]=12;1U{2U 1b[g]}1V(e){}G(i)i.37(h)}}G(s.1O=="1m"&&s.1Y==U)s.1Y=Q;G(s.1Y===Q&&O=="2P"){J j=1z();J k=s.1a.1o(/(\\?|&)3m=.*?(&|$)/,"$ap="+j+"$2");s.1a=k+((k==s.1a)?(s.1a.1I(/\\?/)?"&":"?")+"3m="+j:"")}G(s.L&&O=="2P"){s.1a+=(s.1a.1I(/\\?/)?"&":"?")+s.L;s.L=U}G(s.26&&!D.4O++)D.W.1P("7H");J n=/^(?:\\w+:)?\\/\\/([^\\/?#]+)/;G(s.1O=="1m"&&O=="2P"&&n.11(s.1a)&&n.2D(s.1a)[1]!=5Z.al){J i=S.3H("6w")[0];J h=S.3h("1m");h.4d=s.1a;G(s.7t)h.aj=s.7t;G(!g){J l=Q;h.ah=h.ag=H(){G(!l&&(!7.3f||7.3f=="68"||7.3f=="1J")){l=M;1W();1J();i.37(h)}}}i.3U(h);I 12}J m=Q;J c=1b.7s?2B 7s("ae.ac"):2B 7r();G(s.5Y)c.6R(O,s.1a,s.31,s.5Y,s.3Q);N c.6R(O,s.1a,s.31);1U{G(s.L)c.4B("ab-aa",s.7z);G(s.5S)c.4B("a9-5R-a8",D.4z[s.1a]||"a7, a6 a5 a4 5N:5N:5N a2");c.4B("X-9Z-9Y","7r");c.4B("9W",s.1O&&s.4Q[s.1O]?s.4Q[s.1O]+", */*":s.4Q.4w)}1V(e){}G(s.7m&&s.7m(c,s)===Q){s.26&&D.4O--;c.7l();I Q}G(s.26)D.W.1P("7B",[c,s]);J d=H(a){G(!m&&c&&(c.3f==4||a=="2T")){m=M;G(f){7k(f);f=U}1u=a=="2T"&&"2T"||!D.7j(c)&&"3e"||s.5S&&D.7h(c,s.1a)&&"7J"||"1W";G(1u=="1W"){1U{L=D.6X(c,s.1O,s.9S)}1V(e){1u="5J"}}G(1u=="1W"){J b;1U{b=c.5I("7g-5R")}1V(e){}G(s.5S&&b)D.4z[s.1a]=b;G(!g)1W()}N D.5H(s,c,1u);1J();G(s.31)c=U}};G(s.31){J f=4I(d,13);G(s.2T>0)3B(H(){G(c){c.7l();G(!m)d("2T")}},s.2T)}1U{c.9P(s.L)}1V(e){D.5H(s,c,U,e)}G(!s.31)d();H 1W(){G(s.1W)s.1W(L,1u);G(s.26)D.W.1P("7C",[c,s])}H 1J(){G(s.1J)s.1J(c,1u);G(s.26)D.W.1P("7F",[c,s]);G(s.26&&!--D.4O)D.W.1P("7G")}I c},5H:H(s,a,b,e){G(s.3e)s.3e(a,b,e);G(s.26)D.W.1P("7D",[a,s,e])},4O:0,7j:H(a){1U{I!a.1u&&5Z.9O=="5p:"||(a.1u>=7e&&a.1u<9N)||a.1u==7c||a.1u==9K||D.14.2k&&a.1u==12}1V(e){}I Q},7h:H(a,c){1U{J b=a.5I("7g-5R");I a.1u==7c||b==D.4z[c]||D.14.2k&&a.1u==12}1V(e){}I Q},6X:H(a,c,b){J d=a.5I("9J-O"),2N=c=="2N"||!c&&d&&d.1h("2N")>=0,L=2N?a.9I:a.4U;G(2N&&L.1C.2j=="5J")7p"5J";G(b)L=b(L,c);G(c=="1m")D.5u(L);G(c=="3z")L=6u("("+L+")");I L},3n:H(a){J s=[];G(a.1q==2p||a.5w)D.P(a,H(){s.1p(3u(7.34)+"="+3u(7.2x))});N R(J j 1n a)G(a[j]&&a[j].1q==2p)D.P(a[j],H(){s.1p(3u(j)+"="+3u(7))});N s.1p(3u(j)+"="+3u(D.1D(a[j])?a[j]():a[j]));I s.6s("&").1o(/%20/g,"+")}});D.17.1l({1N:H(c,b){I c?7.2g({1Z:"1N",2h:"1N",1y:"1N"},c,b):7.1E(":1G").P(H(){7.V.18=7.5D||"";G(D.1g(7,"18")=="2F"){J a=D("<"+7.2j+" />").6P("1c");7.V.18=a.1g("18");G(7.V.18=="2F")7.V.18="3I";a.21()}}).3l()},1M:H(b,a){I b?7.2g({1Z:"1M",2h:"1M",1y:"1M"},b,a):7.1E(":4j").P(H(){7.5D=7.5D||D.1g(7,"18");7.V.18="2F"}).3l()},78:D.17.2m,2m:H(a,b){I D.1D(a)&&D.1D(b)?7.78.1w(7,19):a?7.2g({1Z:"2m",2h:"2m",1y:"2m"},a,b):7.P(H(){D(7)[D(7).3F(":1G")?"1N":"1M"]()})},9G:H(b,a){I 7.2g({1Z:"1N"},b,a)},9F:H(b,a){I 7.2g({1Z:"1M"},b,a)},9E:H(b,a){I 7.2g({1Z:"2m"},b,a)},9D:H(b,a){I 7.2g({1y:"1N"},b,a)},9M:H(b,a){I 7.2g({1y:"1M"},b,a)},9C:H(c,a,b){I 7.2g({1y:a},c,b)},2g:H(k,j,i,g){J h=D.77(j,i,g);I 7[h.36===Q?"P":"36"](H(){G(7.16!=1)I Q;J f=D.1l({},h),p,1G=D(7).3F(":1G"),46=7;R(p 1n k){G(k[p]=="1M"&&1G||k[p]=="1N"&&!1G)I f.1J.1k(7);G(p=="1Z"||p=="2h"){f.18=D.1g(7,"18");f.33=7.V.33}}G(f.33!=U)7.V.33="1G";f.45=D.1l({},k);D.P(k,H(c,a){J e=2B D.28(46,f,c);G(/2m|1N|1M/.11(a))e[a=="2m"?1G?"1N":"1M":a](k);N{J b=a.6r().1I(/^([+-]=)?([\\d+-.]+)(.*)$/),2b=e.1t(M)||0;G(b){J d=3d(b[2]),2M=b[3]||"2X";G(2M!="2X"){46.V[c]=(d||1)+2M;2b=((d||1)/e.1t(M))*2b;46.V[c]=2b+2M}G(b[1])d=((b[1]=="-="?-1:1)*d)+2b;e.3G(2b,d,2M)}N e.3G(2b,a,"")}});I M})},36:H(a,b){G(D.1D(a)||(a&&a.1q==2p)){b=a;a="28"}G(!a||(1j a=="23"&&!b))I A(7[0],a);I 7.P(H(){G(b.1q==2p)A(7,a,b);N{A(7,a).1p(b);G(A(7,a).K==1)b.1k(7)}})},9X:H(b,c){J a=D.3O;G(b)7.36([]);7.P(H(){R(J i=a.K-1;i>=0;i--)G(a[i].T==7){G(c)a[i](M);a.7n(i,1)}});G(!c)7.5A();I 7}});J A=H(b,c,a){G(b){c=c||"28";J q=D.L(b,c+"36");G(!q||a)q=D.L(b,c+"36",D.2d(a))}I q};D.17.5A=H(a){a=a||"28";I 7.P(H(){J q=A(7,a);q.4s();G(q.K)q[0].1k(7)})};D.1l({77:H(b,a,c){J d=b&&b.1q==a0?b:{1J:c||!c&&a||D.1D(b)&&b,2u:b,41:c&&a||a&&a.1q!=9t&&a};d.2u=(d.2u&&d.2u.1q==4L?d.2u:D.28.5K[d.2u])||D.28.5K.74;d.5M=d.1J;d.1J=H(){G(d.36!==Q)D(7).5A();G(D.1D(d.5M))d.5M.1k(7)};I d},41:{73:H(p,n,b,a){I b+a*p},5P:H(p,n,b,a){I((-29.9r(p*29.9q)/2)+0.5)*a+b}},3O:[],48:U,28:H(b,c,a){7.15=c;7.T=b;7.1i=a;G(!c.3Z)c.3Z={}}});D.28.44={4D:H(){G(7.15.2Y)7.15.2Y.1k(7.T,7.1z,7);(D.28.2Y[7.1i]||D.28.2Y.4w)(7);G(7.1i=="1Z"||7.1i=="2h")7.T.V.18="3I"},1t:H(a){G(7.T[7.1i]!=U&&7.T.V[7.1i]==U)I 7.T[7.1i];J r=3d(D.1g(7.T,7.1i,a));I r&&r>-9p?r:3d(D.2a(7.T,7.1i))||0},3G:H(c,b,d){7.5V=1z();7.2b=c;7.3l=b;7.2M=d||7.2M||"2X";7.1z=7.2b;7.2S=7.4N=0;7.4D();J e=7;H t(a){I e.2Y(a)}t.T=7.T;D.3O.1p(t);G(D.48==U){D.48=4I(H(){J a=D.3O;R(J i=0;i<a.K;i++)G(!a[i]())a.7n(i--,1);G(!a.K){7k(D.48);D.48=U}},13)}},1N:H(){7.15.3Z[7.1i]=D.1K(7.T.V,7.1i);7.15.1N=M;7.3G(0,7.1t());G(7.1i=="2h"||7.1i=="1Z")7.T.V[7.1i]="9m";D(7.T).1N()},1M:H(){7.15.3Z[7.1i]=D.1K(7.T.V,7.1i);7.15.1M=M;7.3G(7.1t(),0)},2Y:H(a){J t=1z();G(a||t>7.15.2u+7.5V){7.1z=7.3l;7.2S=7.4N=1;7.4D();7.15.45[7.1i]=M;J b=M;R(J i 1n 7.15.45)G(7.15.45[i]!==M)b=Q;G(b){G(7.15.18!=U){7.T.V.33=7.15.33;7.T.V.18=7.15.18;G(D.1g(7.T,"18")=="2F")7.T.V.18="3I"}G(7.15.1M)7.T.V.18="2F";G(7.15.1M||7.15.1N)R(J p 1n 7.15.45)D.1K(7.T.V,p,7.15.3Z[p])}G(b)7.15.1J.1k(7.T);I Q}N{J n=t-7.5V;7.4N=n/7.15.2u;7.2S=D.41[7.15.41||(D.41.5P?"5P":"73")](7.4N,n,0,1,7.15.2u);7.1z=7.2b+((7.3l-7.2b)*7.2S);7.4D()}I M}};D.1l(D.28,{5K:{9l:9j,9i:7e,74:9g},2Y:{2e:H(a){a.T.2e=a.1z},2c:H(a){a.T.2c=a.1z},1y:H(a){D.1K(a.T.V,"1y",a.1z)},4w:H(a){a.T.V[a.1i]=a.1z+a.2M}}});D.17.2i=H(){J b=0,1S=0,T=7[0],3q;G(T)ao(D.14){J d=T.1d,4a=T,1s=T.1s,1Q=T.2z,5U=2k&&3r(5B)<9c&&!/9a/i.11(v),1g=D.2a,3c=1g(T,"30")=="3c";G(T.7y){J c=T.7y();1e(c.1A+29.2f(1Q.1C.2e,1Q.1c.2e),c.1S+29.2f(1Q.1C.2c,1Q.1c.2c));1e(-1Q.1C.6b,-1Q.1C.6a)}N{1e(T.5X,T.5W);1B(1s){1e(1s.5X,1s.5W);G(42&&!/^t(98|d|h)$/i.11(1s.2j)||2k&&!5U)2C(1s);G(!3c&&1g(1s,"30")=="3c")3c=M;4a=/^1c$/i.11(1s.2j)?4a:1s;1s=1s.1s}1B(d&&d.2j&&!/^1c|2K$/i.11(d.2j)){G(!/^96|1T.*$/i.11(1g(d,"18")))1e(-d.2e,-d.2c);G(42&&1g(d,"33")!="4j")2C(d);d=d.1d}G((5U&&(3c||1g(4a,"30")=="5x"))||(42&&1g(4a,"30")!="5x"))1e(-1Q.1c.5X,-1Q.1c.5W);G(3c)1e(29.2f(1Q.1C.2e,1Q.1c.2e),29.2f(1Q.1C.2c,1Q.1c.2c))}3q={1S:1S,1A:b}}H 2C(a){1e(D.2a(a,"6V",M),D.2a(a,"6U",M))}H 1e(l,t){b+=3r(l,10)||0;1S+=3r(t,10)||0}I 3q};D.17.1l({30:H(){J a=0,1S=0,3q;G(7[0]){J b=7.1s(),2i=7.2i(),4c=/^1c|2K$/i.11(b[0].2j)?{1S:0,1A:0}:b.2i();2i.1S-=25(7,\'94\');2i.1A-=25(7,\'aF\');4c.1S+=25(b,\'6U\');4c.1A+=25(b,\'6V\');3q={1S:2i.1S-4c.1S,1A:2i.1A-4c.1A}}I 3q},1s:H(){J a=7[0].1s;1B(a&&(!/^1c|2K$/i.11(a.2j)&&D.1g(a,\'30\')==\'93\'))a=a.1s;I D(a)}});D.P([\'5e\',\'5G\'],H(i,b){J c=\'4y\'+b;D.17[c]=H(a){G(!7[0])I;I a!=12?7.P(H(){7==1b||7==S?1b.92(!i?a:D(1b).2e(),i?a:D(1b).2c()):7[c]=a}):7[0]==1b||7[0]==S?46[i?\'aI\':\'aJ\']||D.71&&S.1C[c]||S.1c[c]:7[0][c]}});D.P(["6N","4b"],H(i,b){J c=i?"5e":"5G",4f=i?"6k":"6i";D.17["5s"+b]=H(){I 7[b.3y()]()+25(7,"57"+c)+25(7,"57"+4f)};D.17["90"+b]=H(a){I 7["5s"+b]()+25(7,"2C"+c+"4b")+25(7,"2C"+4f+"4b")+(a?25(7,"6S"+c)+25(7,"6S"+4f):0)}})})();',62,669,'|||||||this|||||||||||||||||||||||||||||||||||if|function|return|var|length|data|true|else|type|each|false|for|document|elem|null|style|event||nodeName|||test|undefined||browser|options|nodeType|fn|display|arguments|url|window|body|parentNode|add|msie|css|indexOf|prop|typeof|call|extend|script|in|replace|push|constructor|text|offsetParent|cur|status|div|apply|firstChild|opacity|now|left|while|documentElement|isFunction|filter|className|hidden|handle|match|complete|attr|ret|hide|show|dataType|trigger|doc|split|top|table|try|catch|success|break|cache|height||remove|tbody|string|guid|num|global|ready|fx|Math|curCSS|start|scrollTop|makeArray|scrollLeft|max|animate|width|offset|tagName|safari|map|toggle||done|Array|find|toUpperCase|button|special|duration|id|copy|value|handler|ownerDocument|select|new|border|exec|stack|none|opera|nextSibling|pushStack|target|html|inArray|unit|xml|bind|GET|isReady|merge|pos|timeout|delete|one|selected|px|step|jsre|position|async|preventDefault|overflow|name|which|queue|removeChild|namespace|insertBefore|nth|removeData|fixed|parseFloat|error|readyState|multiFilter|createElement|rl|re|trim|end|_|param|first|get|results|parseInt|slice|childNodes|encodeURIComponent|append|events|elems|toLowerCase|json|readyList|setTimeout|grep|mouseenter|color|is|custom|getElementsByTagName|block|stopPropagation|addEventListener|callee|proxy|mouseleave|timers|defaultView|password|disabled|last|has|appendChild|form|domManip|props|ajax|orig|set|easing|mozilla|load|prototype|curAnim|self|charCode|timerId|object|offsetChild|Width|parentOffset|src|unbind|br|currentStyle|clean|float|visible|relatedTarget|previousSibling|handlers|isXMLDoc|on|setup|nodeIndex|unique|shift|javascript|child|RegExp|_default|deep|scroll|lastModified|teardown|setRequestHeader|timeStamp|update|empty|tr|getAttribute|innerHTML|setInterval|checked|fromElement|Number|jQuery|state|active|jsonp|accepts|application|dir|input|responseText|click|styleSheets|unload|not|lastToggle|outline|mouseout|getPropertyValue|mouseover|getComputedStyle|bindReady|String|padding|pageX|metaKey|keyCode|getWH|andSelf|clientX|Left|all|visibility|container|index|init|triggered|removeAttribute|classFilter|prevObject|submit|file|after|windowData|inner|client|globalEval|sibling|jquery|absolute|clone|wrapAll|dequeue|version|triggerHandler|oldblock|ctrlKey|createTextNode|Top|handleError|getResponseHeader|parsererror|speeds|checkbox|old|00|radio|swing|href|Modified|ifModified|lastChild|safari2|startTime|offsetTop|offsetLeft|username|location|ajaxSettings|getElementById|isSimple|values|selectedIndex|runtimeStyle|rsLeft|_load|loaded|DOMContentLoaded|clientTop|clientLeft|toElement|srcElement|val|pageY|POST|unshift|Bottom|clientY|Right|fix|exclusive|detachEvent|cloneNode|removeEventListener|swap|toString|join|attachEvent|eval|substr|head|parse|textarea|reset|image|zoom|odd|even|before|prepend|exclude|expr|quickClass|quickID|uuid|quickChild|continue|Height|textContent|appendTo|contents|open|margin|evalScript|borderTopWidth|borderLeftWidth|parent|httpData|setArray|CSS1Compat|compatMode|boxModel|cssFloat|linear|def|webkit|nodeValue|speed|_toggle|eq|100|replaceWith|304|concat|200|alpha|Last|httpNotModified|getAttributeNode|httpSuccess|clearInterval|abort|beforeSend|splice|styleFloat|throw|colgroup|XMLHttpRequest|ActiveXObject|scriptCharset|callback|fieldset|multiple|processData|getBoundingClientRect|contentType|link|ajaxSend|ajaxSuccess|ajaxError|col|ajaxComplete|ajaxStop|ajaxStart|serializeArray|notmodified|keypress|keydown|change|mouseup|mousedown|dblclick|focus|blur|stylesheet|hasClass|rel|doScroll|black|hover|solid|cancelBubble|returnValue|wheelDelta|view|round|shiftKey|resize|screenY|screenX|relatedNode|mousemove|prevValue|originalTarget|offsetHeight|keyup|newValue|offsetWidth|eventPhase|detail|currentTarget|cancelable|bubbles|attrName|attrChange|altKey|originalEvent|charAt|0n|substring|animated|header|noConflict|line|enabled|innerText|contains|only|weight|font|gt|lt|uFFFF|u0128|size|417|Boolean|Date|toggleClass|removeClass|addClass|removeAttr|replaceAll|insertAfter|prependTo|wrap|contentWindow|contentDocument|iframe|children|siblings|prevAll|wrapInner|nextAll|outer|prev|scrollTo|static|marginTop|next|inline|parents|able|cellSpacing|adobeair|cellspacing|522|maxLength|maxlength|readOnly|400|readonly|fast|600|class|slow|1px|htmlFor|reverse|10000|PI|cos|compatible|Function|setData|ie|ra|it|rv|getData|userAgent|navigator|fadeTo|fadeIn|slideToggle|slideUp|slideDown|ig|responseXML|content|1223|NaN|fadeOut|300|protocol|send|setAttribute|option|dataFilter|cssText|changed|be|Accept|stop|With|Requested|Object|can|GMT|property|1970|Jan|01|Thu|Since|If|Type|Content|XMLHTTP|th|Microsoft|td|onreadystatechange|onload|cap|charset|colg|host|tfoot|specified|with|1_|thead|leg|plain|attributes|opt|embed|urlencoded|www|area|hr|ajaxSetup|meta|post|getJSON|getScript|marginLeft|img|elements|pageYOffset|pageXOffset|abbr|serialize|pixelLeft'.split('|'),0,{}))
Index: /tags/2.0.2/template-common/lib/plugins/jquery.autogrow-textarea.js
===================================================================
--- /tags/2.0.2/template-common/lib/plugins/jquery.autogrow-textarea.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/plugins/jquery.autogrow-textarea.js	(revision 3278)
@@ -0,0 +1,47 @@
+(function($) {
+
+    /*
+     * Auto-growing textareas; technique ripped from Facebook
+     */
+    $.fn.autogrow = function(options) {
+        
+        this.filter('textarea').each(function() {
+            
+            var $this       = $(this),
+                minHeight   = $this.height(),
+                lineHeight  = $this.css('lineHeight');
+            
+            var shadow = $('<div></div>').css({
+                position:   'absolute',
+                top:        -10000,
+                left:       -10000,
+                width:      $(this).width(),
+                fontSize:   $this.css('fontSize'),
+                fontFamily: $this.css('fontFamily'),
+                lineHeight: $this.css('lineHeight'),
+                resize:     'none'
+            }).appendTo(document.body);
+            
+            var update = function() {
+                
+                var val = this.value.replace(/</g, '&lt;')
+                                    .replace(/>/g, '&gt;')
+                                    .replace(/&/g, '&amp;')
+                                    .replace(/\n/g, '<br/>');
+                
+                shadow.html(val);
+                $(this).css('height', Math.max(shadow.height() + 20, minHeight));
+            
+            }
+            
+            $(this).change(update).keyup(update).keydown(update);
+            
+            update.apply(this);
+            
+        });
+        
+        return this;
+        
+    }
+    
+})(jQuery);
Index: /tags/2.0.2/template-common/lib/plugins/jquery.cluetip.js
===================================================================
--- /tags/2.0.2/template-common/lib/plugins/jquery.cluetip.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/plugins/jquery.cluetip.js	(revision 3278)
@@ -0,0 +1,543 @@
+/*
+ * jQuery clueTip plugin
+ * Version 0.9.8  (05/22/2008)
+ * @requires jQuery v1.1.4+
+ * @requires Dimensions plugin (for jQuery versions < 1.2.5)
+ *
+ * Dual licensed under the MIT and GPL licenses:
+ * http://www.opensource.org/licenses/mit-license.php
+ * http://www.gnu.org/licenses/gpl.html
+ *
+ */
+;(function($) { 
+/*
+ * @name clueTip
+ * @type jQuery
+ * @cat Plugins/tooltip
+ * @return jQuery
+ * @author Karl Swedberg
+ *
+ * @credit Inspired by Cody Lindley's jTip (http://www.codylindley.com)
+ * @credit Thanks to the following people for their many and varied contributions:
+      Shelane Enos, Glen Lipka, Hector Santos, Torben Schreiter, Dan G. Switzer, Jörn Zaefferer 
+ * @credit Thanks to Jonathan Chaffer, as always, for help with the hard parts. :-)
+ */
+
+ /**
+ * 
+ * Displays a highly customizable tooltip when the user hovers (default) or clicks (optional) the matched element. 
+ * By default, the clueTip plugin loads a page indicated by the "rel" attribute via ajax and displays its contents.
+ * If a "title" attribute is specified, its value is used as the clueTip's heading.
+ * The attribute to be used for both the body and the heading of the clueTip is user-configurable. 
+ * Optionally, the clueTip's body can display content from an element on the same page.
+ * * Just indicate the element's id (e.g. "#some-id") in the rel attribute.
+ * Optionally, the clueTip's body can display content from the title attribute, when a delimiter is indicated. 
+ * * The string before the first instance of the delimiter is set as the clueTip's heading.
+ * * All subsequent strings are wrapped in separate DIVs and placed in the clueTip's body.
+ * The clueTip plugin allows for many, many more options. Pleasee see the examples and the option descriptions below...
+ * 
+ * 
+ * @example $('#tip).cluetip();
+ * @desc This is the most basic clueTip. It displays a 275px-wide clueTip on mouseover of the element with an ID of "tip." On mouseout of the element, the clueTip is hidden.
+ *
+ *
+ * @example $('a.clue').cluetip({
+ *  hoverClass: 'highlight',
+ *  sticky: true,
+ *  closePosition: 'bottom',
+ *  closeText: '<img src="cross.png" alt="close" />',
+ *  truncate: 60,
+ *  ajaxSettings: {
+ *    type: 'POST'
+ *  }
+ * });
+ * @desc Displays a clueTip on mouseover of all <a> elements with class="clue". The hovered element gets a class of "highlight" added to it (so that it can be styled appropriately. This is esp. useful for non-anchor elements.). The clueTip is "sticky," which means that it will not be hidden until the user either clicks on its "close" text/graphic or displays another clueTip. The "close" text/graphic is set to diplay at the bottom of the clueTip (default is top) and display an image rather than the default "Close" text. Moreover, the body of the clueTip is truncated to the first 60 characters, which are followed by an ellipsis (...). Finally, the clueTip retrieves the content using POST rather than the $.ajax method's default "GET."
+ * 
+ * More examples can be found at http://plugins.learningjquery.com/cluetip/demo/
+ * 
+ * Full list of options/settings can be found at the bottom of this file and at http://plugins.learningjquery.com/cluetip/
+ */
+
+  var $cluetip, $cluetipInner, $cluetipOuter, $cluetipTitle, $cluetipArrows, $dropShadow, imgCount;
+  $.fn.cluetip = function(js, options) {
+    if (typeof js == 'object') {
+      options = js;
+      js = null;
+    }
+    return this.each(function(index) {
+      var $this = $(this);      
+      
+      // support metadata plugin (v1.0 and 2.0)
+      var opts = $.extend(false, {}, $.fn.cluetip.defaults, options || {}, $.metadata ? $this.metadata() : $.meta ? $this.data() : {});
+
+      // start out with no contents (for ajax activation)
+      var cluetipContents = false;
+      var cluezIndex = parseInt(opts.cluezIndex, 10)-1;
+      var isActive = false, closeOnDelay = 0;
+
+      // create the cluetip divs
+      if (!$('#cluetip').length) {
+        $cluetipInner = $('<div id="cluetip-inner"></div>');
+        $cluetipTitle = $('<h3 id="cluetip-title"></h3>');        
+        $cluetipOuter = $('<div id="cluetip-outer"></div>').append($cluetipInner).prepend($cluetipTitle);
+        $cluetip = $('<div id="cluetip"></div>').css({zIndex: opts.cluezIndex})
+        .append($cluetipOuter).append('<div id="cluetip-extra"></div>')[insertionType](insertionElement).hide();
+        $('<div id="cluetip-waitimage"></div>').css({position: 'absolute', zIndex: cluezIndex-1})
+        .insertBefore('#cluetip').hide();
+        $cluetip.css({position: 'absolute', zIndex: cluezIndex});
+        $cluetipOuter.css({position: 'relative', zIndex: cluezIndex+1});
+        $cluetipArrows = $('<div id="cluetip-arrows" class="cluetip-arrows"></div>').css({zIndex: cluezIndex+1}).appendTo('#cluetip');
+      }
+      var dropShadowSteps = (opts.dropShadow) ? +opts.dropShadowSteps : 0;
+      if (!$dropShadow) {
+        $dropShadow = $([]);
+        for (var i=0; i < dropShadowSteps; i++) {
+          $dropShadow = $dropShadow.add($('<div></div>').css({zIndex: cluezIndex-i-1, opacity:.1, top: 1+i, left: 1+i}));
+        };
+        $dropShadow.css({position: 'absolute', backgroundColor: '#000'})
+        .prependTo($cluetip);
+      }
+      var tipAttribute = $this.attr(opts.attribute), ctClass = opts.cluetipClass;
+      if (!tipAttribute && !opts.splitTitle && !js) return true;
+      // if hideLocal is set to true, on DOM ready hide the local content that will be displayed in the clueTip      
+      if (opts.local && opts.hideLocal) { $(tipAttribute + ':first').hide(); }
+      var tOffset = parseInt(opts.topOffset, 10), lOffset = parseInt(opts.leftOffset, 10);
+      // vertical measurement variables
+      var tipHeight, wHeight;
+      var defHeight = isNaN(parseInt(opts.height, 10)) ? 'auto' : (/\D/g).test(opts.height) ? opts.height : opts.height + 'px';
+      var sTop, linkTop, posY, tipY, mouseY, baseline;
+      // horizontal measurement variables
+      var tipInnerWidth = isNaN(parseInt(opts.width, 10)) ? 275 : parseInt(opts.width, 10);
+      var tipWidth = tipInnerWidth + (parseInt($cluetip.css('paddingLeft'))||0) + (parseInt($cluetip.css('paddingRight'))||0) + dropShadowSteps;
+      var linkWidth = this.offsetWidth;
+      var linkLeft, posX, tipX, mouseX, winWidth;
+            
+      // parse the title
+      var tipParts;
+      var tipTitle = (opts.attribute != 'title') ? $this.attr(opts.titleAttribute) : '';
+      if (opts.splitTitle) {
+        if(tipTitle == undefined) {tipTitle = '';}
+        tipParts = tipTitle.split(opts.splitTitle);
+        tipTitle = tipParts.shift();
+      }
+      var localContent;
+
+/***************************************      
+* ACTIVATION
+****************************************/
+    
+//activate clueTip
+    var activate = function(event) {
+      if (!opts.onActivate($this)) {
+        return false;
+      }
+      isActive = true;
+      $cluetip.removeClass().css({width: tipInnerWidth});
+      if (tipAttribute == $this.attr('href')) {
+        $this.css('cursor', opts.cursor);
+      }
+      $this.attr('title','');
+      if (opts.hoverClass) {
+        $this.addClass(opts.hoverClass);
+      }
+      linkTop = posY = $this.offset().top;
+      linkLeft = $this.offset().left;
+      mouseX = event.pageX;
+      mouseY = event.pageY;
+      if ($this[0].tagName.toLowerCase() != 'area') {
+        sTop = $(document).scrollTop();
+        winWidth = $(window).width();
+      }
+// position clueTip horizontally
+      if (opts.positionBy == 'fixed') {
+        posX = linkWidth + linkLeft + lOffset;
+        $cluetip.css({left: posX});
+      } else {
+        posX = (linkWidth > linkLeft && linkLeft > tipWidth)
+          || linkLeft + linkWidth + tipWidth + lOffset > winWidth 
+          ? linkLeft - tipWidth - lOffset 
+          : linkWidth + linkLeft + lOffset;
+        if ($this[0].tagName.toLowerCase() == 'area' || opts.positionBy == 'mouse' || linkWidth + tipWidth > winWidth) { // position by mouse
+          if (mouseX + 20 + tipWidth > winWidth) {  
+            $cluetip.addClass(' cluetip-' + ctClass);
+            posX = (mouseX - tipWidth - lOffset) >= 0 ? mouseX - tipWidth - lOffset - parseInt($cluetip.css('marginLeft'),10) + parseInt($cluetipInner.css('marginRight'),10) :  mouseX - (tipWidth/2);
+          } else {
+            posX = mouseX + lOffset;
+          }
+        }
+        var pY = posX < 0 ? event.pageY + tOffset : event.pageY;
+        $cluetip.css({left: (posX > 0 && opts.positionBy != 'bottomTop') ? posX : (mouseX + (tipWidth/2) > winWidth) ? winWidth/2 - tipWidth/2 : Math.max(mouseX - (tipWidth/2),0)});
+      }
+        wHeight = $(window).height();
+
+/***************************************
+* load a string from cluetip method's first argument
+***************************************/
+      if (js) {
+        $cluetipInner.html(js);
+        cluetipShow(pY);
+      }
+/***************************************
+* load the title attribute only (or user-selected attribute). 
+* clueTip title is the string before the first delimiter
+* subsequent delimiters place clueTip body text on separate lines
+***************************************/
+
+      else if (tipParts) {
+        var tpl = tipParts.length;
+        for (var i=0; i < tpl; i++){
+          if (i == 0) {
+            $cluetipInner.html(tipParts[i]);
+          } else { 
+            $cluetipInner.append('<div class="split-body">' + tipParts[i] + '</div>');
+          }            
+        };
+        cluetipShow(pY);
+      }
+/***************************************
+* load external file via ajax          
+***************************************/
+
+      else if (!opts.local && tipAttribute.indexOf('#') != 0) {
+        if (cluetipContents && opts.ajaxCache) {
+          $cluetipInner.html(cluetipContents);
+          cluetipShow(pY);
+        }
+        else {
+          var ajaxSettings = opts.ajaxSettings;
+          ajaxSettings.url = tipAttribute;
+          ajaxSettings.beforeSend = function() {
+            $cluetipOuter.children().empty();
+            if (opts.waitImage) {
+              $('#cluetip-waitimage')
+              .css({top: mouseY+20, left: mouseX+20})
+              .show();
+            }
+          };
+         ajaxSettings.error = function() {
+            if (isActive) {
+              $cluetipInner.html('<i>sorry, the contents could not be loaded</i>');
+            }
+          };
+          ajaxSettings.success = function(data) {
+            cluetipContents = opts.ajaxProcess(data);
+            if (isActive) {
+              $cluetipInner.html(cluetipContents);
+            }
+          };
+          ajaxSettings.complete = function() {
+          	imgCount = $('#cluetip-inner img').length;
+        		if (imgCount && !$.browser.opera) {
+        		  $('#cluetip-inner img').load(function() {
+          			imgCount--;
+          			if (imgCount<1) {
+          				$('#cluetip-waitimage').hide();
+          			  if (isActive) cluetipShow(pY);
+          			}
+        		  }); 
+        		} else {
+      				$('#cluetip-waitimage').hide();
+        		  if (isActive) cluetipShow(pY);    
+        		} 
+          };
+          $.ajax(ajaxSettings);
+        }
+
+/***************************************
+* load an element from the same page
+***************************************/
+      } else if (opts.local){
+        var $localContent = $(tipAttribute + ':first');
+        var localCluetip = $.fn.wrapInner ? $localContent.wrapInner('<div></div>').children().clone(true) : $localContent.html();
+        $.fn.wrapInner ? $cluetipInner.empty().append(localCluetip) : $cluetipInner.html(localCluetip);
+        cluetipShow(pY);
+      }
+    };
+
+// get dimensions and options for cluetip and prepare it to be shown
+    var cluetipShow = function(bpY) {
+      $cluetip.addClass('cluetip-' + ctClass);
+      
+      if (opts.truncate) { 
+        var $truncloaded = $cluetipInner.text().slice(0,opts.truncate) + '...';
+        $cluetipInner.html($truncloaded);
+      }
+      function doNothing() {}; //empty function
+      tipTitle ? $cluetipTitle.show().html(tipTitle) : (opts.showTitle) ? $cluetipTitle.show().html('&nbsp;') : $cluetipTitle.hide();
+      if (opts.sticky) {
+        var $closeLink = $('<div id="cluetip-close"><a href="#">' + opts.closeText + '</a></div>');
+        (opts.closePosition == 'bottom') ? $closeLink.appendTo($cluetipInner) : (opts.closePosition == 'title') ? $closeLink.prependTo($cluetipTitle) : $closeLink.prependTo($cluetipInner);
+        $closeLink.click(function() {
+          cluetipClose();
+          return false;
+        });
+        if (opts.mouseOutClose) {
+          if ($.fn.hoverIntent && opts.hoverIntent) { 
+            $cluetip.hoverIntent({
+              over: doNothing, 
+              timeout: opts.hoverIntent.timeout,  
+              out: function() { $closeLink.trigger('click'); }
+            });
+          } else {
+            $cluetip.hover(doNothing, 
+            function() {$closeLink.trigger('click'); });
+          }
+        } else {
+          $cluetip.unbind('mouseout');
+        }
+      }
+// now that content is loaded, finish the positioning 
+      var direction = '';
+      $cluetipOuter.css({overflow: defHeight == 'auto' ? 'visible' : 'auto', height: defHeight});
+      tipHeight = defHeight == 'auto' ? Math.max($cluetip.outerHeight(),$cluetip.height()) : parseInt(defHeight,10);   
+      tipY = posY;
+      baseline = sTop + wHeight;
+      if (opts.positionBy == 'fixed') {
+        tipY = posY - opts.dropShadowSteps + tOffset;
+      } else if ( (posX < mouseX && Math.max(posX, 0) + tipWidth > mouseX) || opts.positionBy == 'bottomTop') {
+        if (posY + tipHeight + tOffset > baseline && mouseY - sTop > tipHeight + tOffset) { 
+          tipY = mouseY - tipHeight - tOffset;
+          direction = 'top';
+        } else { 
+          tipY = mouseY + tOffset;
+          direction = 'bottom';
+        }
+      } else if ( posY + tipHeight + tOffset > baseline ) {
+        tipY = (tipHeight >= wHeight) ? sTop : baseline - tipHeight - tOffset;
+      } else if ($this.css('display') == 'block' || $this[0].tagName.toLowerCase() == 'area' || opts.positionBy == "mouse") {
+        tipY = bpY - tOffset;
+      } else {
+        tipY = posY - opts.dropShadowSteps;
+      }
+      if (direction == '') {
+        posX < linkLeft ? direction = 'left' : direction = 'right';
+      }
+      $cluetip.css({top: tipY + 'px'}).removeClass().addClass('clue-' + direction + '-' + ctClass).addClass(' cluetip-' + ctClass);
+      if (opts.arrows) { // set up arrow positioning to align with element
+        var bgY = (posY - tipY - opts.dropShadowSteps);
+        $cluetipArrows.css({top: (/(left|right)/.test(direction) && posX >=0 && bgY > 0) ? bgY + 'px' : /(left|right)/.test(direction) ? 0 : ''}).show();
+      } else {
+        $cluetipArrows.hide();
+      }
+
+// (first hide, then) ***SHOW THE CLUETIP***
+      $dropShadow.hide();
+      $cluetip.hide()[opts.fx.open](opts.fx.open != 'show' && opts.fx.openSpeed);
+      if (opts.dropShadow) $dropShadow.css({height: tipHeight, width: tipInnerWidth}).show();
+      if ($.fn.bgiframe) { $cluetip.bgiframe(); }
+      // trigger the optional onShow function
+      if (opts.delayedClose > 0) {
+        closeOnDelay = setTimeout(cluetipClose, opts.delayedClose);
+      }
+      opts.onShow($cluetip, $cluetipInner);
+      
+    };
+
+/***************************************
+   =INACTIVATION
+-------------------------------------- */
+    var inactivate = function() {
+      isActive = false;
+      $('#cluetip-waitimage').hide();
+      if (!opts.sticky || (/click|toggle/).test(opts.activation) ) {
+        cluetipClose();
+clearTimeout(closeOnDelay);        
+      };
+      if (opts.hoverClass) {
+        $this.removeClass(opts.hoverClass);
+      }
+      $('.cluetip-clicked').removeClass('cluetip-clicked');
+    };
+// close cluetip and reset some things
+    var cluetipClose = function() {
+      $cluetipOuter 
+      .parent().hide().removeClass().end()
+      .children().empty();
+      if (tipTitle) {
+        $this.attr(opts.titleAttribute, tipTitle);
+      }
+      $this.css('cursor','');
+      if (opts.arrows) $cluetipArrows.css({top: ''});
+    };
+
+/***************************************
+   =BIND EVENTS
+-------------------------------------- */
+  // activate by click
+      if ( (/click|toggle/).test(opts.activation) ) {
+        $this.click(function(event) {
+          if ($cluetip.is(':hidden') || !$this.is('.cluetip-clicked')) {
+            activate(event);
+            $('.cluetip-clicked').removeClass('cluetip-clicked');
+            $this.addClass('cluetip-clicked');
+
+          } else {
+            inactivate(event);
+
+          }
+          this.blur();
+          return false;
+        });
+  // activate by focus; inactivate by blur    
+      } else if (opts.activation == 'focus') {
+        $this.focus(function(event) {
+          activate(event);
+        });
+        $this.blur(function(event) {
+          inactivate(event);
+        });
+  // activate by hover
+    // clicking is returned false if cluetip url is same as href url
+      } else {
+        $this.click(function() {
+          if ($this.attr('href') && $this.attr('href') == tipAttribute && !opts.clickThrough) {
+            return false;
+          }
+        });
+        //set up mouse tracking
+        var mouseTracks = function(evt) {
+          if (opts.tracking == true) {
+            var trackX = posX - evt.pageX;
+            var trackY = tipY ? tipY - evt.pageY : posY - evt.pageY;
+            $this.mousemove(function(evt) {
+              $cluetip.css({left: evt.pageX + trackX, top: evt.pageY + trackY });
+            });
+          }
+        };
+        if ($.fn.hoverIntent && opts.hoverIntent) {
+          $this.mouseover(function() {$this.attr('title',''); })
+          .hoverIntent({
+            sensitivity: opts.hoverIntent.sensitivity,
+            interval: opts.hoverIntent.interval,  
+            over: function(event) {
+              activate(event);
+              mouseTracks(event);
+            }, 
+            timeout: opts.hoverIntent.timeout,  
+            out: function(event) {inactivate(event); $this.unbind('mousemove');}
+          });           
+        } else {
+          $this.hover(function(event) {
+            activate(event);
+            mouseTracks(event);
+          }, function(event) {
+            inactivate(event);
+            $this.unbind('mousemove');
+          });
+        }
+      }
+    });
+  };
+  
+/*
+ * options for clueTip
+ *
+ * each one can be explicitly overridden by changing its value. 
+ * for example: $.fn.cluetip.defaults.width = 200; 
+ * would change the default width for all clueTips to 200. 
+ *
+ * each one can also be overridden by passing an options map to the cluetip method.
+ * for example: $('a.example').cluetip({width: 200}); 
+ * would change the default width to 200 for clueTips invoked by a link with class of "example"
+ *
+ */
+  
+  $.fn.cluetip.defaults = {  // set up default options
+    width:            275,      // The width of the clueTip
+    height:           'auto',   // The height of the clueTip
+    cluezIndex:       97,       // Sets the z-index style property of the clueTip
+    positionBy:       'auto',   // Sets the type of positioning: 'auto', 'mouse','bottomTop', 'fixed'
+    topOffset:        15,       // Number of px to offset clueTip from top of invoking element
+    leftOffset:       15,       // Number of px to offset clueTip from left of invoking element
+    local:            false,    // Whether to use content from the same page for the clueTip's body
+    hideLocal:        true,     // If local option is set to true, this determines whether local content
+                                // to be shown in clueTip should be hidden at its original location
+    attribute:        'rel',    // the attribute to be used for fetching the clueTip's body content
+    titleAttribute:   'title',  // the attribute to be used for fetching the clueTip's title
+    splitTitle:       '',       // A character used to split the title attribute into the clueTip title and divs
+                                // within the clueTip body. more info below [6]
+    showTitle:        true,     // show title bar of the clueTip, even if title attribute not set
+    cluetipClass:     'default',// class added to outermost clueTip div in the form of 'cluetip-' + clueTipClass.
+    hoverClass:       '',       // class applied to the invoking element onmouseover and removed onmouseout
+    waitImage:        true,     // whether to show a "loading" img, which is set in jquery.cluetip.css
+    cursor:           'help',
+    arrows:           false,    // if true, displays arrow on appropriate side of clueTip
+    dropShadow:       true,     // set to false if you don't want the drop-shadow effect on the clueTip
+    dropShadowSteps:  6,        // adjusts the size of the drop shadow
+    sticky:           false,    // keep visible until manually closed
+    mouseOutClose:    false,    // close when clueTip is moused out
+    activation:       'hover',  // set to 'click' to force user to click to show clueTip
+                                // set to 'focus' to show on focus of a form element and hide on blur
+    clickThrough:     false,    // if true, and activation is not 'click', then clicking on link will take user to the link's href,
+                                // even if href and tipAttribute are equal
+    tracking:         false,    // if true, clueTip will track mouse movement (experimental)
+    delayedClose:     0,        // close clueTip on a timed delay (experimental)
+    closePosition:    'top',    // location of close text for sticky cluetips; can be 'top' or 'bottom' or 'title'
+    closeText:        'Close',  // text (or HTML) to to be clicked to close sticky clueTips
+    truncate:         0,        // number of characters to truncate clueTip's contents. if 0, no truncation occurs
+
+    // effect and speed for opening clueTips
+    fx: {             
+                      open:       'show', // can be 'show' or 'slideDown' or 'fadeIn'
+                      openSpeed:  ''
+    },     
+
+    // settings for when hoverIntent plugin is used             
+    hoverIntent: {    
+                      sensitivity:  3,
+              			  interval:     50,
+              			  timeout:      0
+    },
+
+    // function to run just before clueTip is shown.           
+    onActivate:       function(e) {return true;},
+
+    // function to run just after clueTip is shown.
+    onShow:           function(ct, c){},
+    
+    // whether to cache results of ajax request to avoid unnecessary hits to server    
+    ajaxCache:        true,  
+
+    // process data retrieved via xhr before it's displayed
+    ajaxProcess:      function(data) {
+                        data = data.replace(/<s(cript|tyle)(.|\s)*?\/s(cript|tyle)>/g, '').replace(/<(link|title)(.|\s)*?\/(link|title)>/g,'');
+                        return data;
+    },                
+
+    // can pass in standard $.ajax() parameters, not including error, complete, success, and url
+    ajaxSettings: {   
+                      dataType: 'html'
+    },
+    debug: false
+  };
+
+
+/*
+ * Global defaults for clueTips. Apply to all calls to the clueTip plugin.
+ *
+ * @example $.cluetip.setup({
+ *   insertionType: 'prependTo',
+ *   insertionElement: '#container'
+ * });
+ * 
+ * @property
+ * @name $.cluetip.setup
+ * @type Map
+ * @cat Plugins/tooltip
+ * @option String insertionType: Default is 'appendTo'. Determines the method to be used for inserting the clueTip into the DOM. Permitted values are 'appendTo', 'prependTo', 'insertBefore', and 'insertAfter'
+ * @option String insertionElement: Default is 'body'. Determines which element in the DOM the plugin will reference when inserting the clueTip.
+ *
+ */
+   
+  var insertionType = 'appendTo', insertionElement = 'body';
+  $.cluetip = {};
+  $.cluetip.setup = function(options) {
+    if (options && options.insertionType && (options.insertionType).match(/appendTo|prependTo|insertBefore|insertAfter/)) {
+      insertionType = options.insertionType;
+    }
+    if (options && options.insertionElement) {
+      insertionElement = options.insertionElement;
+    }
+  };
+  
+})(jQuery);
Index: /tags/2.0.2/template-common/lib/plugins/jquery.cluetip.packed.js
===================================================================
--- /tags/2.0.2/template-common/lib/plugins/jquery.cluetip.packed.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/plugins/jquery.cluetip.packed.js	(revision 3278)
@@ -0,0 +1,1 @@
+;(function($){var $cluetip,$cluetipInner,$cluetipOuter,$cluetipTitle,$cluetipArrows,$dropShadow,imgCount;$.fn.cluetip=function(js,options){if(typeof js=='object'){options=js;js=null}return this.each(function(index){var $this=$(this);var opts=$.extend(false,{},$.fn.cluetip.defaults,options||{},$.metadata?$this.metadata():$.meta?$this.data():{});var cluetipContents=false;var cluezIndex=parseInt(opts.cluezIndex,10)-1;var isActive=false,closeOnDelay=0;if(!$('#cluetip').length){$cluetipInner=$('<div id="cluetip-inner"></div>');$cluetipTitle=$('<h3 id="cluetip-title"></h3>');$cluetipOuter=$('<div id="cluetip-outer"></div>').append($cluetipInner).prepend($cluetipTitle);$cluetip=$('<div id="cluetip"></div>').css({zIndex:opts.cluezIndex}).append($cluetipOuter).append('<div id="cluetip-extra"></div>')[insertionType](insertionElement).hide();$('<div id="cluetip-waitimage"></div>').css({position:'absolute',zIndex:cluezIndex-1}).insertBefore('#cluetip').hide();$cluetip.css({position:'absolute',zIndex:cluezIndex});$cluetipOuter.css({position:'relative',zIndex:cluezIndex+1});$cluetipArrows=$('<div id="cluetip-arrows" class="cluetip-arrows"></div>').css({zIndex:cluezIndex+1}).appendTo('#cluetip')}var dropShadowSteps=(opts.dropShadow)?+opts.dropShadowSteps:0;if(!$dropShadow){$dropShadow=$([]);for(var i=0;i<dropShadowSteps;i++){$dropShadow=$dropShadow.add($('<div></div>').css({zIndex:cluezIndex-i-1,opacity:.1,top:1+i,left:1+i}))};$dropShadow.css({position:'absolute',backgroundColor:'#000'}).prependTo($cluetip)}var tipAttribute=$this.attr(opts.attribute),ctClass=opts.cluetipClass;if(!tipAttribute&&!opts.splitTitle&&!js)return true;if(opts.local&&opts.hideLocal){$(tipAttribute+':first').hide()}var tOffset=parseInt(opts.topOffset,10),lOffset=parseInt(opts.leftOffset,10);var tipHeight,wHeight;var defHeight=isNaN(parseInt(opts.height,10))?'auto':(/\D/g).test(opts.height)?opts.height:opts.height+'px';var sTop,linkTop,posY,tipY,mouseY,baseline;var tipInnerWidth=isNaN(parseInt(opts.width,10))?275:parseInt(opts.width,10);var tipWidth=tipInnerWidth+(parseInt($cluetip.css('paddingLeft'))||0)+(parseInt($cluetip.css('paddingRight'))||0)+dropShadowSteps;var linkWidth=this.offsetWidth;var linkLeft,posX,tipX,mouseX,winWidth;var tipParts;var tipTitle=(opts.attribute!='title')?$this.attr(opts.titleAttribute):'';if(opts.splitTitle){if(tipTitle==undefined){tipTitle=''}tipParts=tipTitle.split(opts.splitTitle);tipTitle=tipParts.shift()}var localContent;var activate=function(event){if(!opts.onActivate($this)){return false}isActive=true;$cluetip.removeClass().css({width:tipInnerWidth});if(tipAttribute==$this.attr('href')){$this.css('cursor',opts.cursor)}$this.attr('title','');if(opts.hoverClass){$this.addClass(opts.hoverClass)}linkTop=posY=$this.offset().top;linkLeft=$this.offset().left;mouseX=event.pageX;mouseY=event.pageY;if($this[0].tagName.toLowerCase()!='area'){sTop=$(document).scrollTop();winWidth=$(window).width()}if(opts.positionBy=='fixed'){posX=linkWidth+linkLeft+lOffset;$cluetip.css({left:posX})}else{posX=(linkWidth>linkLeft&&linkLeft>tipWidth)||linkLeft+linkWidth+tipWidth+lOffset>winWidth?linkLeft-tipWidth-lOffset:linkWidth+linkLeft+lOffset;if($this[0].tagName.toLowerCase()=='area'||opts.positionBy=='mouse'||linkWidth+tipWidth>winWidth){if(mouseX+20+tipWidth>winWidth){$cluetip.addClass(' cluetip-'+ctClass);posX=(mouseX-tipWidth-lOffset)>=0?mouseX-tipWidth-lOffset-parseInt($cluetip.css('marginLeft'),10)+parseInt($cluetipInner.css('marginRight'),10):mouseX-(tipWidth/2)}else{posX=mouseX+lOffset}}var pY=posX<0?event.pageY+tOffset:event.pageY;$cluetip.css({left:(posX>0&&opts.positionBy!='bottomTop')?posX:(mouseX+(tipWidth/2)>winWidth)?winWidth/2-tipWidth/2:Math.max(mouseX-(tipWidth/2),0)})}wHeight=$(window).height();if(js){$cluetipInner.html(js);cluetipShow(pY)}else if(tipParts){var tpl=tipParts.length;for(var i=0;i<tpl;i++){if(i==0){$cluetipInner.html(tipParts[i])}else{$cluetipInner.append('<div class="split-body">'+tipParts[i]+'</div>')}};cluetipShow(pY)}else if(!opts.local&&tipAttribute.indexOf('#')!=0){if(cluetipContents&&opts.ajaxCache){$cluetipInner.html(cluetipContents);cluetipShow(pY)}else{var ajaxSettings=opts.ajaxSettings;ajaxSettings.url=tipAttribute;ajaxSettings.beforeSend=function(){$cluetipOuter.children().empty();if(opts.waitImage){$('#cluetip-waitimage').css({top:mouseY+20,left:mouseX+20}).show()}};ajaxSettings.error=function(){if(isActive){$cluetipInner.html('<i>sorry, the contents could not be loaded</i>')}};ajaxSettings.success=function(data){cluetipContents=opts.ajaxProcess(data);if(isActive){$cluetipInner.html(cluetipContents)}};ajaxSettings.complete=function(){imgCount=$('#cluetip-inner img').length;if(imgCount&&!$.browser.opera){$('#cluetip-inner img').load(function(){imgCount--;if(imgCount<1){$('#cluetip-waitimage').hide();if(isActive)cluetipShow(pY)}})}else{$('#cluetip-waitimage').hide();if(isActive)cluetipShow(pY)}};$.ajax(ajaxSettings)}}else if(opts.local){var $localContent=$(tipAttribute+':first');var localCluetip=$.fn.wrapInner?$localContent.wrapInner('<div></div>').children().clone(true):$localContent.html();$.fn.wrapInner?$cluetipInner.empty().append(localCluetip):$cluetipInner.html(localCluetip);cluetipShow(pY)}};var cluetipShow=function(bpY){$cluetip.addClass('cluetip-'+ctClass);if(opts.truncate){var $truncloaded=$cluetipInner.text().slice(0,opts.truncate)+'...';$cluetipInner.html($truncloaded)}function doNothing(){};tipTitle?$cluetipTitle.show().html(tipTitle):(opts.showTitle)?$cluetipTitle.show().html('&nbsp;'):$cluetipTitle.hide();if(opts.sticky){var $closeLink=$('<div id="cluetip-close"><a href="#">'+opts.closeText+'</a></div>');(opts.closePosition=='bottom')?$closeLink.appendTo($cluetipInner):(opts.closePosition=='title')?$closeLink.prependTo($cluetipTitle):$closeLink.prependTo($cluetipInner);$closeLink.click(function(){cluetipClose();return false});if(opts.mouseOutClose){if($.fn.hoverIntent&&opts.hoverIntent){$cluetip.hoverIntent({over:doNothing,timeout:opts.hoverIntent.timeout,out:function(){$closeLink.trigger('click')}})}else{$cluetip.hover(doNothing,function(){$closeLink.trigger('click')})}}else{$cluetip.unbind('mouseout')}}var direction='';$cluetipOuter.css({overflow:defHeight=='auto'?'visible':'auto',height:defHeight});tipHeight=defHeight=='auto'?Math.max($cluetip.outerHeight(),$cluetip.height()):parseInt(defHeight,10);tipY=posY;baseline=sTop+wHeight;if(opts.positionBy=='fixed'){tipY=posY-opts.dropShadowSteps+tOffset}else if((posX<mouseX&&Math.max(posX,0)+tipWidth>mouseX)||opts.positionBy=='bottomTop'){if(posY+tipHeight+tOffset>baseline&&mouseY-sTop>tipHeight+tOffset){tipY=mouseY-tipHeight-tOffset;direction='top'}else{tipY=mouseY+tOffset;direction='bottom'}}else if(posY+tipHeight+tOffset>baseline){tipY=(tipHeight>=wHeight)?sTop:baseline-tipHeight-tOffset}else if($this.css('display')=='block'||$this[0].tagName.toLowerCase()=='area'||opts.positionBy=="mouse"){tipY=bpY-tOffset}else{tipY=posY-opts.dropShadowSteps}if(direction==''){posX<linkLeft?direction='left':direction='right'}$cluetip.css({top:tipY+'px'}).removeClass().addClass('clue-'+direction+'-'+ctClass).addClass(' cluetip-'+ctClass);if(opts.arrows){var bgY=(posY-tipY-opts.dropShadowSteps);$cluetipArrows.css({top:(/(left|right)/.test(direction)&&posX>=0&&bgY>0)?bgY+'px':/(left|right)/.test(direction)?0:''}).show()}else{$cluetipArrows.hide()}$dropShadow.hide();$cluetip.hide()[opts.fx.open](opts.fx.open!='show'&&opts.fx.openSpeed);if(opts.dropShadow)$dropShadow.css({height:tipHeight,width:tipInnerWidth}).show();if($.fn.bgiframe){$cluetip.bgiframe()}if(opts.delayedClose>0){closeOnDelay=setTimeout(cluetipClose,opts.delayedClose)}opts.onShow($cluetip,$cluetipInner)};var inactivate=function(){isActive=false;$('#cluetip-waitimage').hide();if(!opts.sticky||(/click|toggle/).test(opts.activation)){cluetipClose();clearTimeout(closeOnDelay)};if(opts.hoverClass){$this.removeClass(opts.hoverClass)}$('.cluetip-clicked').removeClass('cluetip-clicked')};var cluetipClose=function(){$cluetipOuter.parent().hide().removeClass().end().children().empty();if(tipTitle){$this.attr(opts.titleAttribute,tipTitle)}$this.css('cursor','');if(opts.arrows)$cluetipArrows.css({top:''})};if((/click|toggle/).test(opts.activation)){$this.click(function(event){if($cluetip.is(':hidden')||!$this.is('.cluetip-clicked')){activate(event);$('.cluetip-clicked').removeClass('cluetip-clicked');$this.addClass('cluetip-clicked')}else{inactivate(event)}this.blur();return false})}else if(opts.activation=='focus'){$this.focus(function(event){activate(event)});$this.blur(function(event){inactivate(event)})}else{$this.click(function(){if($this.attr('href')&&$this.attr('href')==tipAttribute&&!opts.clickThrough){return false}});var mouseTracks=function(evt){if(opts.tracking==true){var trackX=posX-evt.pageX;var trackY=tipY?tipY-evt.pageY:posY-evt.pageY;$this.mousemove(function(evt){$cluetip.css({left:evt.pageX+trackX,top:evt.pageY+trackY})})}};if($.fn.hoverIntent&&opts.hoverIntent){$this.mouseover(function(){$this.attr('title','')}).hoverIntent({sensitivity:opts.hoverIntent.sensitivity,interval:opts.hoverIntent.interval,over:function(event){activate(event);mouseTracks(event)},timeout:opts.hoverIntent.timeout,out:function(event){inactivate(event);$this.unbind('mousemove')}})}else{$this.hover(function(event){activate(event);mouseTracks(event)},function(event){inactivate(event);$this.unbind('mousemove')})}}})};$.fn.cluetip.defaults={width:275,height:'auto',cluezIndex:97,positionBy:'auto',topOffset:15,leftOffset:15,local:false,hideLocal:true,attribute:'rel',titleAttribute:'title',splitTitle:'',showTitle:true,cluetipClass:'default',hoverClass:'',waitImage:true,cursor:'help',arrows:false,dropShadow:true,dropShadowSteps:6,sticky:false,mouseOutClose:false,activation:'hover',clickThrough:false,tracking:false,delayedClose:0,closePosition:'top',closeText:'Close',truncate:0,fx:{open:'show',openSpeed:''},hoverIntent:{sensitivity:3,interval:50,timeout:0},onActivate:function(e){return true},onShow:function(ct,c){},ajaxCache:true,ajaxProcess:function(data){data=data.replace(/<s(cript|tyle)(.|\s)*?\/s(cript|tyle)>/g,'').replace(/<(link|title)(.|\s)*?\/(link|title)>/g,'');return data},ajaxSettings:{dataType:'html'},debug:false};var insertionType='appendTo',insertionElement='body';$.cluetip={};$.cluetip.setup=function(options){if(options&&options.insertionType&&(options.insertionType).match(/appendTo|prependTo|insertBefore|insertAfter/)){insertionType=options.insertionType}if(options&&options.insertionElement){insertionElement=options.insertionElement}}})(jQuery);
Index: /tags/2.0.2/template-common/lib/plugins/jquery.dimensions.js
===================================================================
--- /tags/2.0.2/template-common/lib/plugins/jquery.dimensions.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/plugins/jquery.dimensions.js	(revision 3278)
@@ -0,0 +1,119 @@
+/* Copyright (c) 2007 Paul Bakaus (paul.bakaus@googlemail.com) and Brandon Aaron (brandon.aaron@gmail.com || http://brandonaaron.net)
+ * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
+ * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
+ *
+ * $LastChangedDate$
+ * $Rev$
+ *
+ * Version: 1.2
+ *
+ * Requires: jQuery 1.2+
+ */
+
+(function($){
+	
+$.dimensions = {
+	version: '1.2'
+};
+
+// Create innerHeight, innerWidth, outerHeight and outerWidth methods
+$.each( [ 'Height', 'Width' ], function(i, name){
+	
+	// innerHeight and innerWidth
+	$.fn[ 'inner' + name ] = function() {
+		if (!this[0]) return;
+		
+		var torl = name == 'Height' ? 'Top'    : 'Left',  // top or left
+		    borr = name == 'Height' ? 'Bottom' : 'Right'; // bottom or right
+		
+		return this.is(':visible') ? this[0]['client' + name] : num( this, name.toLowerCase() ) + num(this, 'padding' + torl) + num(this, 'padding' + borr);
+	};
+	
+	// outerHeight and outerWidth
+	$.fn[ 'outer' + name ] = function(options) {
+		if (!this[0]) return;
+		
+		var torl = name == 'Height' ? 'Top'    : 'Left',  // top or left
+		    borr = name == 'Height' ? 'Bottom' : 'Right'; // bottom or right
+		
+		options = $.extend({ margin: false }, options || {});
+		
+		var val = this.is(':visible') ? 
+				this[0]['offset' + name] : 
+				num( this, name.toLowerCase() )
+					+ num(this, 'border' + torl + 'Width') + num(this, 'border' + borr + 'Width')
+					+ num(this, 'padding' + torl) + num(this, 'padding' + borr);
+		
+		return val + (options.margin ? (num(this, 'margin' + torl) + num(this, 'margin' + borr)) : 0);
+	};
+});
+
+// Create scrollLeft and scrollTop methods
+$.each( ['Left', 'Top'], function(i, name) {
+	$.fn[ 'scroll' + name ] = function(val) {
+		if (!this[0]) return;
+		
+		return val != undefined ?
+		
+			// Set the scroll offset
+			this.each(function() {
+				this == window || this == document ?
+					window.scrollTo( 
+						name == 'Left' ? val : $(window)[ 'scrollLeft' ](),
+						name == 'Top'  ? val : $(window)[ 'scrollTop'  ]()
+					) :
+					this[ 'scroll' + name ] = val;
+			}) :
+			
+			// Return the scroll offset
+			this[0] == window || this[0] == document ?
+				self[ (name == 'Left' ? 'pageXOffset' : 'pageYOffset') ] ||
+					$.boxModel && document.documentElement[ 'scroll' + name ] ||
+					document.body[ 'scroll' + name ] :
+				this[0][ 'scroll' + name ];
+	};
+});
+
+$.fn.extend({
+	position: function() {
+		var left = 0, top = 0, elem = this[0], offset, parentOffset, offsetParent, results;
+		
+		if (elem) {
+			// Get *real* offsetParent
+			offsetParent = this.offsetParent();
+			
+			// Get correct offsets
+			offset       = this.offset();
+			parentOffset = offsetParent.offset();
+			
+			// Subtract element margins
+			offset.top  -= num(elem, 'marginTop');
+			offset.left -= num(elem, 'marginLeft');
+			
+			// Add offsetParent borders
+			parentOffset.top  += num(offsetParent, 'borderTopWidth');
+			parentOffset.left += num(offsetParent, 'borderLeftWidth');
+			
+			// Subtract the two offsets
+			results = {
+				top:  offset.top  - parentOffset.top,
+				left: offset.left - parentOffset.left
+			};
+		}
+		
+		return results;
+	},
+	
+	offsetParent: function() {
+		var offsetParent = this[0].offsetParent;
+		while ( offsetParent && (!/^body|html$/i.test(offsetParent.tagName) && $.css(offsetParent, 'position') == 'static') )
+			offsetParent = offsetParent.offsetParent;
+		return $(offsetParent);
+	}
+});
+
+function num(el, prop) {
+	return parseInt($.curCSS(el.jquery?el[0]:el,prop,true))||0;
+};
+
+})(jQuery);
Index: /tags/2.0.2/template-common/lib/plugins/jquery.dimensions.packed.js
===================================================================
--- /tags/2.0.2/template-common/lib/plugins/jquery.dimensions.packed.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/plugins/jquery.dimensions.packed.js	(revision 3278)
@@ -0,0 +1,1 @@
+eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(5($){$.19={P:\'1.2\'};$.u([\'j\',\'w\'],5(i,d){$.q[\'O\'+d]=5(){p(!3[0])6;g a=d==\'j\'?\'s\':\'m\',e=d==\'j\'?\'D\':\'C\';6 3.B(\':y\')?3[0][\'L\'+d]:4(3,d.x())+4(3,\'n\'+a)+4(3,\'n\'+e)};$.q[\'I\'+d]=5(b){p(!3[0])6;g c=d==\'j\'?\'s\':\'m\',e=d==\'j\'?\'D\':\'C\';b=$.F({t:Z},b||{});g a=3.B(\':y\')?3[0][\'8\'+d]:4(3,d.x())+4(3,\'E\'+c+\'w\')+4(3,\'E\'+e+\'w\')+4(3,\'n\'+c)+4(3,\'n\'+e);6 a+(b.t?(4(3,\'t\'+c)+4(3,\'t\'+e)):0)}});$.u([\'m\',\'s\'],5(i,b){$.q[\'l\'+b]=5(a){p(!3[0])6;6 a!=W?3.u(5(){3==h||3==r?h.V(b==\'m\'?a:$(h)[\'U\'](),b==\'s\'?a:$(h)[\'T\']()):3[\'l\'+b]=a}):3[0]==h||3[0]==r?S[(b==\'m\'?\'R\':\'Q\')]||$.N&&r.M[\'l\'+b]||r.A[\'l\'+b]:3[0][\'l\'+b]}});$.q.F({z:5(){g a=0,f=0,o=3[0],8,9,7,v;p(o){7=3.7();8=3.8();9=7.8();8.f-=4(o,\'K\');8.k-=4(o,\'J\');9.f+=4(7,\'H\');9.k+=4(7,\'Y\');v={f:8.f-9.f,k:8.k-9.k}}6 v},7:5(){g a=3[0].7;G(a&&(!/^A|10$/i.16(a.15)&&$.14(a,\'z\')==\'13\'))a=a.7;6 $(a)}});5 4(a,b){6 12($.11(a.17?a[0]:a,b,18))||0}})(X);',62,72,'|||this|num|function|return|offsetParent|offset|parentOffset|||||borr|top|var|window||Height|left|scroll|Left|padding|elem|if|fn|document|Top|margin|each|results|Width|toLowerCase|visible|position|body|is|Right|Bottom|border|extend|while|borderTopWidth|outer|marginLeft|marginTop|client|documentElement|boxModel|inner|version|pageYOffset|pageXOffset|self|scrollTop|scrollLeft|scrollTo|undefined|jQuery|borderLeftWidth|false|html|curCSS|parseInt|static|css|tagName|test|jquery|true|dimensions'.split('|'),0,{}))
Index: /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-ar.js
===================================================================
--- /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-ar.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-ar.js	(revision 3278)
@@ -0,0 +1,23 @@
+﻿/* Arabic Translation for jQuery UI date picker plugin. */
+/* Khaled Al Horani -- koko.dw@gmail.com */
+/* خالد الحوراني -- koko.dw@gmail.com */
+/* NOTE: monthNames are the original months names and thez are the Arabic names, not the new months name فبراير - يناير and there isnät any Arabic roots for these months */
+jQuery(function($){
+	$.datepicker.regional['ar'] = {
+		clearText: 'مسح', clearStatus: 'امسح التاريخ الحالي',
+		closeText: 'إغلاق', closeStatus: 'إغلاق بدون حفظ',
+		prevText: '<السابق', prevStatus: 'عرض الشهر السابق',
+		nextText: 'التالي>', nextStatus: 'عرض الشهر القادم',
+		currentText: 'اليوم', currentStatus: 'عرض الشهر الحالي',
+		monthNames: ['كانون الثاني', 'شباط', 'آذار', 'نيسان', 'آذار', 'حزيران', 'تموز', 'آب', 'أيلول',	'تشرين الأول', 'تشرين الثاني', 'كانون الأول'],
+		monthNamesShort: ['1','2','3','4','5','6','7','8','9','10','11','12'],
+		monthStatus: 'عرض شهر آخر', yearStatus: 'عرض سنة آخرى',
+		weekHeader: 'أسبوع', weekStatus: 'أسبوع السنة',
+		dayNames: ['السبت', 'الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة'],
+		dayNamesShort: ['سبت', 'أحد', 'اثنين', 'ثلاثاء', 'أربعاء', 'خميس', 'جمعة'],
+		dayNamesMin: ['سبت', 'أحد', 'اثنين', 'ثلاثاء', 'أربعاء', 'خميس', 'جمعة'],
+		dayStatus: 'اختر DD لليوم الأول من الأسبوع', dateStatus: 'اختر D, M d',
+		dateFormat: 'dd/mm/yy', firstDay: 0, 
+		initStatus: 'اختر يوم', isRTL: true};
+	$.datepicker.setDefaults($.datepicker.regional['ar']);
+});
Index: /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-bg.js
===================================================================
--- /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-bg.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-bg.js	(revision 3278)
@@ -0,0 +1,22 @@
+﻿/* Bulgarian initialisation for the jQuery UI date picker plugin. */
+/* Written by Stoyan Kyosev (http://svest.org). */
+jQuery(function($){
+    $.datepicker.regional['bg'] = {clearText: 'изчисти', clearStatus: 'изчисти актуалната дата',
+        closeText: 'затвори', closeStatus: 'затвори без промени',
+        prevText: '&#x3c;назад', prevStatus: 'покажи последния месец',
+        nextText: 'напред&#x3e;', nextStatus: 'покажи следващия месец',
+        currentText: 'днес', currentStatus: '',
+        monthNames: ['Януари','Февруари','Март','Април','Май','Юни',
+        'Юли','Август','Септември','Октомври','Ноември','Декември'],
+        monthNamesShort: ['Яну','Фев','Мар','Апр','Май','Юни',
+        'Юли','Авг','Сеп','Окт','Нов','Дек'],
+        monthStatus: 'покажи друг месец', yearStatus: 'покажи друга година',
+        weekHeader: 'Wk', weekStatus: 'седмица от месеца',
+        dayNames: ['Неделя','Понеделник','Вторник','Сряда','Четвъртък','Петък','Събота'],
+        dayNamesShort: ['Нед','Пон','Вто','Сря','Чет','Пет','Съб'],
+        dayNamesMin: ['Не','По','Вт','Ср','Че','Пе','Съ'],
+        dayStatus: 'Сложи DD като първи ден от седмицата', dateStatus: 'Избери D, M d',
+        dateFormat: 'dd.mm.yy', firstDay: 1,
+        initStatus: 'Избери дата', isRTL: false};
+    $.datepicker.setDefaults($.datepicker.regional['bg']);
+});
Index: /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-ca.js
===================================================================
--- /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-ca.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-ca.js	(revision 3278)
@@ -0,0 +1,22 @@
+/* Inicialització en català per a l'extenció 'calendar' per jQuery. */
+/* Writers: (joan.leon@gmail.com). */
+jQuery(function($){
+	$.datepicker.regional['ca'] = {clearText: 'Netejar', clearStatus: '',
+		closeText: 'Tancar', closeStatus: '',
+		prevText: '&lt;Ant', prevStatus: '',
+		nextText: 'Seg&gt;', nextStatus: '',
+		currentText: 'Avui', currentStatus: '',
+		monthNames: ['Gener','Febrer','Mar&ccedil;','Abril','Maig','Juny',
+		'Juliol','Agost','Setembre','Octubre','Novembre','Desembre'],
+		monthNamesShort: ['Gen','Feb','Mar','Abr','Mai','Jun',
+		'Jul','Ago','Set','Oct','Nov','Des'],
+		monthStatus: '', yearStatus: '',
+		weekHeader: 'Sm', weekStatus: '',
+		dayNames: ['Diumenge','Dilluns','Dimarts','Dimecres','Dijous','Divendres','Dissabte'],
+		dayNamesShort: ['Dug','Dln','Dmt','Dmc','Djs','Dvn','Dsb'],
+		dayNamesMin: ['Dg','Dl','Dt','Dc','Dj','Dv','Ds'],
+		dayStatus: 'DD', dateStatus: 'D, M d',
+		dateFormat: 'mm/dd/yy', firstDay: 0, 
+		initStatus: '', isRTL: false};
+	$.datepicker.setDefaults($.datepicker.regional['ca']);
+});
Index: /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-cs.js
===================================================================
--- /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-cs.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-cs.js	(revision 3278)
@@ -0,0 +1,22 @@
+﻿/* Czech initialisation for the jQuery UI date picker plugin. */
+/* Written by Tomas Muller (tomas@tomas-muller.net). */
+jQuery(function($){
+	$.datepicker.regional['cs'] = {clearText: 'Vymazat', clearStatus: 'Vymaže zadané datum',
+		closeText: 'Zavřít',  closeStatus: 'Zavře kalendář beze změny',
+		prevText: '&#x3c;Dříve', prevStatus: 'Přejít na předchozí měsí',
+		nextText: 'Později&#x3e;', nextStatus: 'Přejít na další měsíc',
+		currentText: 'Nyní', currentStatus: 'Přejde na aktuální měsíc',
+		monthNames: ['leden','únor','březen','duben','květen','červen',
+        'červenec','srpen','září','říjen','listopad','prosinec'],
+		monthNamesShort: ['led','úno','bře','dub','kvě','čer',
+		'čvc','srp','zář','říj','lis','pro'],
+		monthStatus: 'Přejít na jiný měsíc', yearStatus: 'Přejít na jiný rok',
+		weekHeader: 'Týd', weekStatus: 'Týden v roce',
+		dayNames: ['neděle', 'pondělí', 'úterý', 'středa', 'čtvrtek', 'pátek', 'sobota'],
+		dayNamesShort: ['ne', 'po', 'út', 'st', 'čt', 'pá', 'so'],
+		dayNamesMin: ['ne','po','út','st','čt','pá','so'],
+		dayStatus: 'Nastavit DD jako první den v týdnu', dateStatus: '\'Vyber\' DD, M d',
+		dateFormat: 'dd.mm.yy', firstDay: 1, 
+		initStatus: 'Vyberte datum', isRTL: false};
+	$.datepicker.setDefaults($.datepicker.regional['cs']);
+});
Index: /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-da.js
===================================================================
--- /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-da.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-da.js	(revision 3278)
@@ -0,0 +1,22 @@
+﻿/* Danish initialisation for the jQuery UI date picker plugin. */
+/* Written by Jan Christensen ( deletestuff@gmail.com). */
+jQuery(function($){
+    $.datepicker.regional['da'] = {clearText: 'Nulstil', clearStatus: 'Nulstil den aktuelle dato',
+		closeText: 'Luk', closeStatus: 'Luk uden ændringer',
+        prevText: '&#x3c;Forrige', prevStatus: 'Vis forrige måned',
+		nextText: 'Næste&#x3e;', nextStatus: 'Vis næste måned',
+		currentText: 'Idag', currentStatus: 'Vis aktuel måned',
+        monthNames: ['Januar','Februar','Marts','April','Maj','Juni', 
+        'Juli','August','September','Oktober','November','December'],
+        monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun', 
+        'Jul','Aug','Sep','Okt','Nov','Dec'],
+		monthStatus: 'Vis en anden måned', yearStatus: 'Vis et andet år',
+		weekHeader: 'Uge', weekStatus: 'Årets uge',
+		dayNames: ['Søndag','Mandag','Tirsdag','Onsdag','Torsdag','Fredag','Lørdag'],
+		dayNamesShort: ['Søn','Man','Tir','Ons','Tor','Fre','Lør'],
+		dayNamesMin: ['Sø','Ma','Ti','On','To','Fr','Lø'],
+		dayStatus: 'Sæt DD som første ugedag', dateStatus: 'Vælg D, M d',
+        dateFormat: 'dd-mm-yy', firstDay: 0, 
+		initStatus: 'Vælg en dato', isRTL: false};
+    $.datepicker.setDefaults($.datepicker.regional['da']); 
+});
Index: /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-de.js
===================================================================
--- /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-de.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-de.js	(revision 3278)
@@ -0,0 +1,22 @@
+﻿/* German initialisation for the jQuery UI date picker plugin. */
+/* Written by Milian Wolff (mail@milianw.de). */
+jQuery(function($){
+	$.datepicker.regional['de'] = {clearText: 'löschen', clearStatus: 'aktuelles Datum löschen',
+		closeText: 'schließen', closeStatus: 'ohne Änderungen schließen',
+		prevText: '&#x3c;zurück', prevStatus: 'letzten Monat zeigen',
+		nextText: 'Vor&#x3e;', nextStatus: 'nächsten Monat zeigen',
+		currentText: 'heute', currentStatus: '',
+		monthNames: ['Januar','Februar','März','April','Mai','Juni',
+		'Juli','August','September','Oktober','November','Dezember'],
+		monthNamesShort: ['Jan','Feb','Mär','Apr','Mai','Jun',
+		'Jul','Aug','Sep','Okt','Nov','Dez'],
+		monthStatus: 'anderen Monat anzeigen', yearStatus: 'anderes Jahr anzeigen',
+		weekHeader: 'Wo', weekStatus: 'Woche des Monats',
+		dayNames: ['Sonntag','Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag'],
+		dayNamesShort: ['So','Mo','Di','Mi','Do','Fr','Sa'],
+		dayNamesMin: ['So','Mo','Di','Mi','Do','Fr','Sa'],
+		dayStatus: 'Setze DD als ersten Wochentag', dateStatus: 'Wähle D, M d',
+		dateFormat: 'dd.mm.yy', firstDay: 1, 
+		initStatus: 'Wähle ein Datum', isRTL: false};
+	$.datepicker.setDefaults($.datepicker.regional['de']);
+});
Index: /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-es.js
===================================================================
--- /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-es.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-es.js	(revision 3278)
@@ -0,0 +1,22 @@
+/* Inicialización en español para la extensión 'UI date picker' para jQuery. */
+/* Traducido por Vester (xvester@gmail.com). */
+jQuery(function($){
+	$.datepicker.regional['es'] = {clearText: 'Limpiar', clearStatus: '',
+		closeText: 'Cerrar', closeStatus: '',
+		prevText: '&lt;Ant', prevStatus: '',
+		nextText: 'Sig&gt;', nextStatus: '',
+		currentText: 'Hoy', currentStatus: '',
+		monthNames: ['Enero','Febrero','Marzo','Abril','Mayo','Junio',
+		'Julio','Agosto','Septiembre','Octubre','Noviembre','Diciembre'],
+		monthNamesShort: ['Ene','Feb','Mar','Abr','May','Jun',
+		'Jul','Ago','Sep','Oct','Nov','Dic'],
+		monthStatus: '', yearStatus: '',
+		weekHeader: 'Sm', weekStatus: '',
+		dayNames: ['Domingo','Lunes','Martes','Mi&eacute;rcoles','Jueves','Viernes','S&aacute;dabo'],
+		dayNamesShort: ['Dom','Lun','Mar','Mi&eacute;','Juv','Vie','S&aacute;b'],
+		dayNamesMin: ['Do','Lu','Ma','Mi','Ju','Vi','S&aacute;'],
+		dayStatus: 'DD', dateStatus: 'D, M d',
+		dateFormat: 'dd/mm/yy', firstDay: 0, 
+		initStatus: '', isRTL: false};
+	$.datepicker.setDefaults($.datepicker.regional['es']);
+});
Index: /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-fi.js
===================================================================
--- /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-fi.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-fi.js	(revision 3278)
@@ -0,0 +1,24 @@
+/* Finnish initialisation for the jQuery UI date picker plugin. */
+/* Written by Harri Kilpiö (harrikilpio@gmail.com). */
+
+$(document).ready(function(){
+    $.datepicker.regional['fi'] = {
+		clearText: 'Tyhjenn&auml;', clearStatus: '',
+		closeText: 'Sulje', closeStatus: '',
+		prevText: '&laquo;Edellinen', prevStatus: '',
+		nextText: 'Seuraava&raquo;', nextStatus: '',
+		currentText: 'T&auml;n&auml;&auml;n', currentStatus: '',
+        monthNames: ['Tammikuu','Helmikuu','Maaliskuu','Huhtikuu','Toukokuu','Kes&auml;kuu',
+        'Hein&auml;kuu','Elokuu','Syyskuu','Lokakuu','Marraskuu','Joulukuu'],
+        monthNamesShort: ['Tammi','Helmi','Maalis','Huhti','Touko','Kes&auml;',
+        'Hein&auml;','Elo','Syys','Loka','Marras','Joulu'],
+		monthStatus: '', yearStatus: '',
+		weekHeader: 'Vk', weekStatus: '',
+		dayNamesShort: ['Su','Ma','Ti','Ke','To','Pe','Su'],
+		dayNames: ['Sunnuntai','Maanantai','Tiistai','Keskiviikko','Torstai','Perjantai','Lauantai'],
+		dayNamesMin: ['Su','Ma','Ti','Ke','To','Pe','La'],
+		dayStatus: 'DD', dateStatus: 'D, M d',
+        dateFormat: 'dd.mm.yy', firstDay: 1,
+		initStatus: '', isRTL: false};
+    $.datepicker.setDefaults($.datepicker.regional['fi']);
+});
Index: /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-fr.js
===================================================================
--- /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-fr.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-fr.js	(revision 3278)
@@ -0,0 +1,22 @@
+﻿/* French initialisation for the jQuery UI date picker plugin. */
+/* Written by Keith Wood (kbwood@virginbroadband.com.au) and Stéphane Nahmani (sholby@sholby.net). */
+jQuery(function($){
+	$.datepicker.regional['fr'] = {clearText: 'Effacer', clearStatus: '',
+		closeText: 'Fermer', closeStatus: 'Fermer sans modifier',
+		prevText: '&lt;Préc', prevStatus: 'Voir le mois précédent',
+		nextText: 'Suiv&gt;', nextStatus: 'Voir le mois suivant',
+		currentText: 'Courant', currentStatus: 'Voir le mois courant',
+		monthNames: ['Janvier','Février','Mars','Avril','Mai','Juin',
+		'Juillet','Août','Septembre','Octobre','Novembre','Décembre'],
+		monthNamesShort: ['Jan','Fév','Mar','Avr','Mai','Jun',
+		'Jul','Aoû','Sep','Oct','Nov','Déc'],
+		monthStatus: 'Voir un autre mois', yearStatus: 'Voir un autre année',
+		weekHeader: 'Sm', weekStatus: '',
+		dayNames: ['Dimanche','Lundi','Mardi','Mercredi','Jeudi','Vendredi','Samedi'],
+		dayNamesShort: ['Dim','Lun','Mar','Mer','Jeu','Ven','Sam'],
+		dayNamesMin: ['Di','Lu','Ma','Me','Je','Ve','Sa'],
+		dayStatus: 'Utiliser DD comme premier jour de la semaine', dateStatus: 'Choisir le DD, MM d',
+		dateFormat: 'dd/mm/yy', firstDay: 0, 
+		initStatus: 'Choisir la date', isRTL: false};
+	$.datepicker.setDefaults($.datepicker.regional['fr']);
+});
Index: /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-he.js
===================================================================
--- /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-he.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-he.js	(revision 3278)
@@ -0,0 +1,22 @@
+﻿/* Hebrew initialisation for the UI Datepicker extension. */
+/* Written by Amir Hardon (ahardon at gmail dot com). */
+jQuery(document).ready(function(){
+	jQuery.datepicker.regional['he'] = {clearText: 'נקה', clearStatus: '',
+		closeText: 'סגור', closeStatus: '',
+		prevText: '&#x3c;הקודם', prevStatus: '',
+		nextText: 'הבא&#x3e;', nextStatus: '',
+		currentText: 'היום', currentStatus: '',
+		monthNames: ['ינואר','פברואר','מרץ','אפריל','מאי','יוני',
+		'יולי','אוגוסט','ספטמבר','אוקטובר','נובמבר','דצמבר'],
+		monthNamesShort: ['1','2','3','4','5','6',
+		'7','8','9','10','11','12'],
+		monthStatus: '', yearStatus: '',
+		weekHeader: 'Sm', weekStatus: '',
+		dayNames: ['ראשון','שני','שלישי','רביעי','חמישי','שישי','שבת'],
+		dayNamesShort: ['א\'','ב\'','ג\'','ד\'','ה\'','ו\'','שבת'],
+		dayNamesMin: ['א\'','ב\'','ג\'','ד\'','ה\'','ו\'','שבת'],
+		dayStatus: 'DD', dateStatus: 'DD, M d',
+		dateFormat: 'dd/mm/yy', firstDay: 0, 
+		initStatus: '', isRTL: true};
+	jQuery.datepicker.setDefaults($.datepicker.regional['he']);
+});
Index: /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-hu.js
===================================================================
--- /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-hu.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-hu.js	(revision 3278)
@@ -0,0 +1,22 @@
+/* Hungarian initialisation for the jQuery UI date picker plugin. */
+/* Written by Istvan Karaszi (jquerycalendar@spam.raszi.hu). */
+jQuery(function($){
+	$.datepicker.regional['hu'] = {clearText: 'törlés', clearStatus: '',
+		closeText: 'bezárás', closeStatus: '',
+		prevText: '&laquo;&nbsp;vissza', prevStatus: '',
+		nextText: 'előre&nbsp;&raquo;', nextStatus: '',
+		currentText: 'ma', currentStatus: '',
+		monthNames: ['Január', 'Február', 'Március', 'Április', 'Május', 'Június',
+		'Július', 'Augusztus', 'Szeptember', 'Október', 'November', 'December'],
+		monthNamesShort: ['Jan', 'Feb', 'Már', 'Ápr', 'Máj', 'Jún',
+		'Júl', 'Aug', 'Szep', 'Okt', 'Nov', 'Dec'],
+		monthStatus: '', yearStatus: '',
+		weekHeader: 'Hé', weekStatus: '',
+		dayNames: ['Vasámap', 'Hétfö', 'Kedd', 'Szerda', 'Csütörtök', 'Péntek', 'Szombat'],
+		dayNamesShort: ['Vas', 'Hét', 'Ked', 'Sze', 'Csü', 'Pén', 'Szo'],
+		dayNamesMin: ['V', 'H', 'K', 'Sze', 'Cs', 'P', 'Szo'],
+		dayStatus: 'DD', dateStatus: 'D, M d',
+		dateFormat: 'yy-mm-dd', firstDay: 1, 
+		initStatus: '', isRTL: false};
+	$.datepicker.setDefaults($.datepicker.regional['hu']);
+});
Index: /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-hy.js
===================================================================
--- /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-hy.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-hy.js	(revision 3278)
@@ -0,0 +1,22 @@
+/* Armenian(UTF-8) initialisation for the jQuery UI date picker plugin. */
+/* Written by Levon Zakaryan (levon.zakaryan@gmail.com)*/
+jQuery(function($){
+	$.datepicker.regional['hy'] = {clearText: 'Մաքրել', clearStatus: '',
+		closeText: 'Փակել', closeStatus: '',
+		prevText: '&lt;Նախ.',  prevStatus: '',
+		nextText: 'Հաջ.&gt;', nextStatus: '',
+		currentText: 'Այսօր', currentStatus: '',
+		monthNames: ['Հունվար','Փետրվար','Մարտ','Ապրիլ','Մայիս','Հունիս',
+		'Հուլիս','Օգոստոս','Սեպտեմբեր','Հոկտեմբեր','Նոյեմբեր','Դեկտեմբեր'],
+		monthNamesShort: ['Հունվ','Փետր','Մարտ','Ապր','Մայիս','Հունիս',
+		'Հուլ','Օգս','Սեպ','Հոկ','Նոյ','Դեկ'],
+		monthStatus: '', yearStatus: '',
+		weekHeader: 'ՇԲՏ', weekStatus: '',
+		dayNames: ['կիրակի','եկուշաբթի','երեքշաբթի','չորեքշաբթի','հինգշաբթի','ուրբաթ','շաբաթ'],
+		dayNamesShort: ['կիր','երկ','երք','չրք','հնգ','ուրբ','շբթ'],
+		dayNamesMin: ['կիր','երկ','երք','չրք','հնգ','ուրբ','շբթ'],
+		dayStatus: 'DD', dateStatus: 'D, M d',
+		dateFormat: 'dd.mm.yy', firstDay: 1, 
+		initStatus: '', isRTL: false};
+	$.datepicker.setDefaults($.datepicker.regional['hy']);
+});
Index: /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-id.js
===================================================================
--- /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-id.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-id.js	(revision 3278)
@@ -0,0 +1,22 @@
+/* Indonesian initialisation for the jQuery UI date picker plugin. */
+/* Written by Deden Fathurahman (dedenf@gmail.com). */
+jQuery(function($){
+	$.datepicker.regional['id'] = {clearText: 'kosongkan', clearStatus: 'bersihkan tanggal yang sekarang',
+		closeText: 'Tutup', closeStatus: 'Tutup tanpa mengubah',
+		prevText: '&lt;mundur', prevStatus: 'Tampilkan bulan sebelumnya',
+		nextText: 'maju&gt;', nextStatus: 'Tampilkan bulan berikutnya',
+		currentText: 'hari ini', currentStatus: 'Tampilkan bulan sekarang',
+		monthNames: ['Januari','Februari','Maret','April','Mei','Juni',
+		'Juli','Agustus','September','Oktober','Nopember','Desember'],
+		monthNamesShort: ['Jan','Feb','Mar','Apr','Mei','Jun',
+		'Jul','Agus','Sep','Okt','Nop','Des'],
+		monthStatus: 'Tampilkan bulan yang berbeda', yearStatus: 'Tampilkan tahun yang berbeda',
+		weekHeader: 'Mg', weekStatus: 'Minggu dalam tahun',
+		dayNames: ['Minggu','Senin','Selasa','Rabu','Kamis','Jumat','Sabtu'],
+		dayNamesShort: ['Min','Sen','Sel','Rab','kam','Jum','Sab'],
+		dayNamesMin: ['Mg','Sn','Sl','Rb','Km','jm','Sb'],
+		dayStatus: 'gunakan DD sebagai awal hari dalam minggu', dateStatus: 'pilih le DD, MM d',
+		dateFormat: 'dd/mm/yy', firstDay: 0, 
+		initStatus: 'Pilih Tanggal', isRTL: false};
+	$.datepicker.setDefaults($.datepicker.regional['id']);
+});
Index: /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-is.js
===================================================================
--- /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-is.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-is.js	(revision 3278)
@@ -0,0 +1,22 @@
+/* Icelandic initialisation for the jQuery UI date picker plugin. */
+/* Written by Haukur H. Thorsson (haukur@eskill.is). */
+jQuery(function($){
+	$.datepicker.regional['is'] = {clearText: 'Hreinsa', clearStatus: '',
+		closeText: 'Loka', closeStatus: '',
+		prevText: '< Fyrri', prevStatus: '',
+		nextText: 'N&aelig;sti >', nextStatus: '',
+		currentText: '&Iacute; dag', currentStatus: '',
+		monthNames: ['Jan&uacute;ar','Febr&uacute;ar','Mars','Apr&iacute;l','Ma&iacute','J&uacute;n&iacute;',
+		'J&uacute;l&iacute;','&Aacute;g&uacute;st','September','Okt&oacute;ber','N&oacute;vember','Desember'],
+		monthNamesShort: ['Jan','Feb','Mar','Apr','Ma&iacute;','J&uacute;n',
+		'J&uacute;l','&Aacute;g&uacute;','Sep','Okt','N&oacute;v','Des'],
+		monthStatus: '', yearStatus: '',
+		weekHeader: 'Vika', weekStatus: '',
+		dayNames: ['Sunnudagur','M&aacute;nudagur','&THORN;ri&eth;judagur','Mi&eth;vikudagur','Fimmtudagur','F&ouml;studagur','Laugardagur'],
+		dayNamesShort: ['Sun','M&aacute;n','&THORN;ri','Mi&eth;','Fim','F&ouml;s','Lau'],
+		dayNamesMin: ['Su','M&aacute;','&THORN;r','Mi','Fi','F&ouml;','La'],
+		dayStatus: 'DD', dateStatus: 'D, M d',
+		dateFormat: 'dd/mm/yy', firstDay: 0, 
+		initStatus: '', isRTL: false};
+	$.datepicker.setDefaults($.datepicker.regional['is']);
+});
Index: /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-it.js
===================================================================
--- /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-it.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-it.js	(revision 3278)
@@ -0,0 +1,22 @@
+/* Italian initialisation for the jQuery UI date picker plugin. */
+/* Written by Apaella (apaella@gmail.com). */
+jQuery(function($){
+	$.datepicker.regional['it'] = {clearText: 'Svuota', clearStatus: '',
+		closeText: 'Chiudi', closeStatus: '',
+		prevText: '&lt;Prec', prevStatus: '',
+		nextText: 'Succ&gt;', nextStatus: '',
+		currentText: 'Oggi', currentStatus: '',
+		monthNames: ['Gennaio','Febbraio','Marzo','Aprile','Maggio','Giugno',
+		'Luglio','Agosto','Settembre','Ottobre','Novembre','Dicembre'],
+		monthNamesShort: ['Gen','Feb','Mar','Apr','Mag','Giu',
+		'Lug','Ago','Set','Ott','Nov','Dic'],
+		monthStatus: '', yearStatus: '',
+		weekHeader: 'Sm', weekStatus: '',
+		dayNames: ['Domenica','Luned&#236','Marted&#236','Mercoled&#236','Gioved&#236','Venerd&#236','Sabato'],
+		dayNamesShort: ['Dom','Lun','Mar','Mer','Gio','Ven','Sab'],
+		dayNamesMin: ['Do','Lu','Ma','Me','Gio','Ve','Sa'],
+		dayStatus: 'DD', dateStatus: 'D, M d',
+		dateFormat: 'dd/mm/yy', firstDay: 1, 
+		initStatus: '', isRTL: false};
+	$.datepicker.setDefaults($.datepicker.regional['it']);
+});
Index: /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-ja.js
===================================================================
--- /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-ja.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-ja.js	(revision 3278)
@@ -0,0 +1,22 @@
+/* Japanese (UTF-8) initialisation for the jQuery UI date picker plugin. */
+/* Written by Milly. */
+jQuery(function($){
+	$.datepicker.regional['ja'] = {clearText: '&#21066;&#38500;', clearStatus: '',
+		closeText: '&#38281;&#12376;&#12427;', closeStatus: '',
+		prevText: '&lt;&#21069;&#26376;', prevStatus: '',
+		nextText: '&#27425;&#26376;&gt;', nextStatus: '',
+		currentText: '&#20170;&#26085;', currentStatus: '',
+		monthNames: ['1&#26376;','2&#26376;','3&#26376;','4&#26376;','5&#26376;','6&#26376;',
+		'7&#26376;','8&#26376;','9&#26376;','10&#26376;','11&#26376;','12&#26376;'],
+		monthNamesShort: ['1&#26376;','2&#26376;','3&#26376;','4&#26376;','5&#26376;','6&#26376;',
+		'7&#26376;','8&#26376;','9&#26376;','10&#26376;','11&#26376;','12&#26376;'],
+		monthStatus: '', yearStatus: '',
+		weekHeader: 'Wk', weekStatus: '',
+		dayNames: ['&#26085;','&#26376;','&#28779;','&#27700;','&#26408;','&#37329;','&#22303;'],
+		dayNamesShort: ['&#26085;','&#26376;','&#28779;','&#27700;','&#26408;','&#37329;','&#22303;'],
+		dayNamesMin: ['&#26085;','&#26376;','&#28779;','&#27700;','&#26408;','&#37329;','&#22303;'],
+		dayStatus: 'DD', dateStatus: 'D, M d',
+		dateFormat: 'yy/mm/dd', firstDay: 0, 
+		initStatus: '', isRTL: false};
+	$.datepicker.setDefaults($.datepicker.regional['ja']);
+});
Index: /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-ko.js
===================================================================
--- /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-ko.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-ko.js	(revision 3278)
@@ -0,0 +1,22 @@
+/* Korean initialisation for the jQuery calendar extension. */
+/* Written by DaeKwon Kang (ncrash.dk@gmail.com). */
+jQuery(function($){
+	$.datepicker.regional['ko'] = {clearText: '지우기', clearStatus: '',
+		closeText: '닫기', closeStatus: '',
+		prevText: '이전달', prevStatus: '',
+		nextText: '다음달', nextStatus: '',
+		currentText: '오늘', currentStatus: '',
+		monthNames: ['1월(JAN)','2월(FEB)','3월(MAR)','4월(APR)','5월(MAY)','6월(JUN)',
+			'7월(JUL)','8월(AUG)','9월(SEP)','10월(OCT)','11월(NOV)','12월(DEC)'],
+		monthNamesShort: ['1월(JAN)','2월(FEB)','3월(MAR)','4월(APR)','5월(MAY)','6월(JUN)',
+			'7월(JUL)','8월(AUG)','9월(SEP)','10월(OCT)','11월(NOV)','12월(DEC)'],
+		monthStatus: '', yearStatus: '',
+		weekHeader: 'Wk', weekStatus: '',
+		dayNames: ['일','월','화','수','목','금','토'],
+		dayNamesShort: ['일','월','화','수','목','금','토'],
+		dayNamesMin: ['일','월','화','수','목','금','토'],
+		dayStatus: 'DD', dateStatus: 'D, M d',
+		dateFormat: 'yy-mm-dd', firstDay: 0, 
+		initStatus: '', isRTL: false};
+	$.datepicker.setDefaults($.datepicker.regional['ko']);
+});
Index: /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-lt.js
===================================================================
--- /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-lt.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-lt.js	(revision 3278)
@@ -0,0 +1,25 @@
+/**
+ * Lithuanian (UTF-8) initialisation for the jQuery UI date picker plugin.
+ *
+ * @author Arturas Paleicikas <arturas@avalon.lt>
+ */
+jQuery(function($){
+	$.datepicker.regional['lt'] = {clearText: 'Išvalyti', clearStatus: '',
+		closeText: 'Uždaryti', closeStatus: '',
+		prevText: '&lt;Atgal',  prevStatus: '',
+		nextText: 'Pirmyn&gt;', nextStatus: '',
+		currentText: 'Šiandien', currentStatus: '',
+		monthNames: ['Sausis','Vasaris','Kovas','Balandis','Gegužė','Birželis',
+		'Liepa','Rugpjūtis','Rugsėjis','Spalis','Lapkritis','Gruodis'],
+		monthNamesShort: ['Sau','Vas','Kov','Bal','Geg','Bir',
+		'Lie','Rugp','Rugs','Spa','Lap','Gru'],
+		monthStatus: '', yearStatus: '',
+		weekHeader: '', weekStatus: '',
+		dayNames: ['sekmadienis','pirmadienis','antradienis','trečiadienis','ketvirtadienis','penktadienis','šeštadienis'],
+		dayNamesShort: ['sek','pir','ant','tre','ket','pen','šeš'],
+		dayNamesMin: ['Se','Pr','An','Tr','Ke','Pe','Še'],
+		dayStatus: 'DD', dateStatus: 'D, M d',
+		dateFormat: 'yy-mm-dd', firstDay: 1, 
+		initStatus: '', isRTL: false};
+	$.datepicker.setDefaults($.datepicker.regional['lt']);
+});
Index: /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-lv.js
===================================================================
--- /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-lv.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-lv.js	(revision 3278)
@@ -0,0 +1,25 @@
+/**
+ * Latvian (UTF-8) initialisation for the jQuery UI date picker plugin.
+ * @author Arturas Paleicikas <arturas.paleicikas@metasite.net>
+ */
+jQuery(function($){
+	$.datepicker.regional['lv'] = {
+		clearText: 'Notīrīt', clearStatus: '',
+		closeText: 'Aizvērt', closeStatus: '',
+		prevText: 'Iepr',  prevStatus: '',
+		nextText: 'Nāka', nextStatus: '',
+		currentText: 'Šodien', currentStatus: '',
+		monthNames: ['Janvāris','Februāris','Marts','Aprīlis','Maijs','Jūnijs',
+		'Jūlijs','Augusts','Septembris','Oktobris','Novembris','Decembris'],
+		monthNamesShort: ['Jan','Feb','Mar','Apr','Mai','Jūn',
+		'Jūl','Aug','Sep','Okt','Nov','Dec'],
+		monthStatus: '', yearStatus: '',
+		weekHeader: 'Nav', weekStatus: '',
+		dayNames: ['svētdiena','pirmdiena','otrdiena','trešdiena','ceturtdiena','piektdiena','sestdiena'],
+		dayNamesShort: ['svt','prm','otr','tre','ctr','pkt','sst'],
+		dayNamesMin: ['Sv','Pr','Ot','Tr','Ct','Pk','Ss'],
+		dayStatus: 'DD', dateStatus: 'D, M d',
+		dateFormat: 'dd-mm-yy', firstDay: 1, 
+		initStatus: '', isRTL: false};
+	$.datepicker.setDefaults($.datepicker.regional['lv']);
+});
Index: /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-nl.js
===================================================================
--- /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-nl.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-nl.js	(revision 3278)
@@ -0,0 +1,21 @@
+/* Dutch (UTF-8) initialisation for the jQuery UI date picker plugin. */
+jQuery(function($){
+	$.datepicker.regional['nl'] = {clearText: 'Wissen', clearStatus: 'Wis de huidige datum',
+		closeText: 'Sluiten', closeStatus: 'Sluit zonder verandering',
+		prevText: '&lt;Terug', prevStatus: 'Laat de voorgaande maand zien',
+		nextText: 'Volgende&gt;', nextStatus: 'Laat de volgende maand zien',
+		currentText: 'Vandaag', currentStatus: 'Laat de huidige maand zien',
+		monthNames: ['Januari','Februari','Maart','April','Mei','Juni',
+		'Juli','Augustus','September','Oktober','November','December'],
+		monthNamesShort: ['Jan','Feb','Mrt','Apr','Mei','Jun',
+		'Jul','Aug','Sep','Okt','Nov','Dec'],
+		monthStatus: 'Laat een andere maand zien', yearStatus: 'Laat een ander jaar zien',
+		weekHeader: 'Wk', weekStatus: 'Week van het jaar',
+		dayNames: ['Zondag','Maandag','Dinsdag','Woensdag','Donderdag','Vrijdag','Zaterdag'],
+		dayNamesShort: ['Zon','Maa','Din','Woe','Don','Vri','Zat'],
+		dayNamesMin: ['Zo','Ma','Di','Wo','Do','Vr','Za'],
+		dayStatus: 'DD', dateStatus: 'D, M d',
+		dateFormat: 'dd.mm.yy', firstDay: 1, 
+		initStatus: 'Kies een datum', isRTL: false};
+	$.datepicker.setDefaults($.datepicker.regional['nl']);
+});
Index: /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-no.js
===================================================================
--- /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-no.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-no.js	(revision 3278)
@@ -0,0 +1,23 @@
+/* Norwegian initialisation for the jQuery UI date picker plugin. */
+/* Written by Naimdjon Takhirov (naimdjon@gmail.com). */
+
+$(document).ready(function(){
+    $.datepicker.regional['no'] = {clearText: 'Tøm', clearStatus: '',
+		closeText: 'Lukk', closeStatus: '',
+        prevText: '&laquo;Forrige',  prevStatus: '',
+		nextText: 'Neste&raquo;', nextStatus: '',
+		currentText: 'I dag', currentStatus: '',
+        monthNames: ['Januar','Februar','Mars','April','Mai','Juni', 
+        'Juli','August','September','Oktober','November','Desember'],
+        monthNamesShort: ['Jan','Feb','Mar','Apr','Mai','Jun', 
+        'Jul','Aug','Sep','Okt','Nov','Des'],
+		monthStatus: '', yearStatus: '',
+		weekHeader: 'Uke', weekStatus: '',
+		dayNamesShort: ['Søn','Man','Tir','Ons','Tor','Fre','Lør'],
+		dayNames: ['Søndag','Mandag','Tirsdag','Onsdag','Torsdag','Fredag','Lørdag'],
+		dayNamesMin: ['Sø','Ma','Ti','On','To','Fr','Lø'],
+		dayStatus: 'DD', dateStatus: 'D, M d',
+        dateFormat: 'yy-mm-dd', firstDay: 0, 
+		initStatus: '', isRTL: false};
+    $.datepicker.setDefaults($.datepicker.regional['no']); 
+});
Index: /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-pl.js
===================================================================
--- /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-pl.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-pl.js	(revision 3278)
@@ -0,0 +1,22 @@
+/* Polish initialisation for the jQuery UI date picker plugin. */
+/* Written by Jacek Wysocki (jacek.wysocki@gmail.com). */
+jQuery(function($){
+	$.datepicker.regional['pl'] = {clearText: 'Wyczyść', clearStatus: 'Wyczyść obecną datę',
+		closeText: 'Zamknij', closeStatus: 'Zamknij bez zapisywania',
+		prevText: '&#x3c;Poprzedni', prevStatus: 'Pokaż poprzedni miesiąc',
+		nextText: 'Następny&#x3e;', nextStatus: 'Pokaż następny miesiąc',
+		currentText: 'Dziś', currentStatus: 'Pokaż aktualny miesiąc',
+		monthNames: ['Styczeń','Luty','Marzec','Kwiecień','Maj','Czerwiec',
+		'Lipiec','Sierpień','Wrzesień','Październik','Listopad','Grudzień'],
+		monthNamesShort: ['Sty','Lu','Mar','Kw','Maj','Cze',
+		'Lip','Sie','Wrz','Pa','Lis','Gru'],
+		monthStatus: 'Pokaż inny miesiąc', yearStatus: 'Pokaż inny rok',
+		weekHeader: 'Tydz', weekStatus: 'Tydzień roku',
+		dayNames: ['Niedziela','Poniedzialek','Wtorek','Środa','Czwartek','Piątek','Sobota'],
+		dayNamesShort: ['Nie','Pn','Wt','Śr','Czw','Pt','So'],
+		dayNamesMin: ['N','Pn','Wt','Śr','Cz','Pt','So'],
+		dayStatus: 'Ustaw DD jako pierwszy dzień tygodnia', dateStatus: 'Wybierz D, M d',
+		dateFormat: 'yy-mm-dd', firstDay: 1, 
+		initStatus: 'Wybierz datę', isRTL: false};
+	$.datepicker.setDefaults($.datepicker.regional['pl']);
+});
Index: /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-pt-BR.js
===================================================================
--- /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-pt-BR.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-pt-BR.js	(revision 3278)
@@ -0,0 +1,22 @@
+/* Brazilian initialisation for the jQuery UI date picker plugin. */
+/* Written by Leonildo Costa Silva (leocsilva@gmail.com). */
+jQuery(function($){
+	$.datepicker.regional['pt-BR'] = {clearText: 'Limpar', clearStatus: '',
+		closeText: 'Fechar', closeStatus: '',
+		prevText: '&lt;Anterior', prevStatus: '',
+		nextText: 'Pr&oacute;ximo&gt;', nextStatus: '',
+		currentText: 'Hoje', currentStatus: '',
+		monthNames: ['Janeiro','Fevereiro','Mar&ccedil;o','Abril','Maio','Junho',
+		'Julho','Agosto','Setembro','Outubro','Novembro','Dezembro'],
+		monthNamesShort: ['Jan','Fev','Mar','Abr','Mai','Jun',
+		'Jul','Ago','Set','Out','Nov','Dez'],
+		monthStatus: '', yearStatus: '',
+		weekHeader: 'Sm', weekStatus: '',
+		dayNames: ['Domingo','Segunda-feira','Ter&ccedil;a-feira','Quarta-feira','Quinta-feira','Sexta-feira','Sabado'],
+		dayNamesShort: ['Dom','Seg','Ter','Qua','Qui','Sex','Sab'],
+		dayNamesMin: ['Dom','Seg','Ter','Qua','Qui','Sex','Sab'],
+		dayStatus: 'DD', dateStatus: 'D, M d',
+		dateFormat: 'dd/mm/yy', firstDay: 0, 
+		initStatus: '', isRTL: false};
+	$.datepicker.setDefaults($.datepicker.regional['pt-BR']);
+});
Index: /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-ro.js
===================================================================
--- /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-ro.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-ro.js	(revision 3278)
@@ -0,0 +1,22 @@
+/* Romanian initialisation for the jQuery UI date picker plugin. */
+/* Written by Edmond L. (ll_edmond@walla.com). */
+jQuery(function($){
+	$.datepicker.regional['ro'] = {clearText: 'Curat', clearStatus: 'Sterge data curenta',
+		closeText: 'Inchide', closeStatus: 'Inchide fara schimbare',
+		prevText: '&#x3c;Anterior', prevStatus: 'Arata luna trecuta',
+		nextText: 'Urmator&#x3e;', nextStatus: 'Arata luna urmatoare',
+		currentText: 'Azi', currentStatus: 'Arata luna curenta',
+		monthNames: ['Ianuarie','Februarie','Martie','Aprilie','Mai','Junie',
+		'Julie','August','Septembrie','Octobrie','Noiembrie','Decembrie'],
+		monthNamesShort: ['Ian', 'Feb', 'Mar', 'Apr', 'Mai', 'Jun',
+		'Jul', 'Aug', 'Sep', 'Oct', 'Noi', 'Dec'],
+		monthStatus: 'Arata o luna diferita', yearStatus: 'Arat un an diferit',
+		weekHeader: 'Sapt', weekStatus: 'Saptamana anului',
+		dayNames: ['Duminica', 'Luni', 'Marti', 'Miercuri', 'Joi', 'Vineri', 'Sambata'],
+		dayNamesShort: ['Dum', 'Lun', 'Mar', 'Mie', 'Joi', 'Vin', 'Sam'],
+		dayNamesMin: ['Du','Lu','Ma','Mi','Jo','Vi','Sa'],
+		dayStatus: 'Seteaza DD ca prima saptamana zi', dateStatus: 'Selecteaza D, M d',
+		dateFormat: 'mm/dd/yy', firstDay: 0, 
+		initStatus: 'Selecteaza o data', isRTL: false};
+	$.datepicker.setDefaults($.datepicker.regional['ro']);
+});
Index: /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-ru.js
===================================================================
--- /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-ru.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-ru.js	(revision 3278)
@@ -0,0 +1,22 @@
+/* Russian (UTF-8) initialisation for the jQuery UI date picker plugin. */
+/* Written by Andrew Stromnov (stromnov@gmail.com). */
+jQuery(function($){
+	$.datepicker.regional['ru'] = {clearText: 'Очистить', clearStatus: '',
+		closeText: 'Закрыть', closeStatus: '',
+		prevText: '&lt;Пред',  prevStatus: '',
+		nextText: 'След&gt;', nextStatus: '',
+		currentText: 'Сегодня', currentStatus: '',
+		monthNames: ['Январь','Февраль','Март','Апрель','Май','Июнь',
+		'Июль','Август','Сентябрь','Октябрь','Ноябрь','Декабрь'],
+		monthNamesShort: ['Янв','Фев','Мар','Апр','Май','Июн',
+		'Июл','Авг','Сен','Окт','Ноя','Дек'],
+		monthStatus: '', yearStatus: '',
+		weekHeader: 'Не', weekStatus: '',
+		dayNames: ['воскресенье','понедельник','вторник','среда','четверг','пятница','суббота'],
+		dayNamesShort: ['вск','пнд','втр','срд','чтв','птн','сбт'],
+		dayNamesMin: ['Вс','Пн','Вт','Ср','Чт','Пт','Сб'],
+		dayStatus: 'DD', dateStatus: 'D, M d',
+		dateFormat: 'dd.mm.yy', firstDay: 1, 
+		initStatus: '', isRTL: false};
+	$.datepicker.setDefaults($.datepicker.regional['ru']);
+});
Index: /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-sk.js
===================================================================
--- /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-sk.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-sk.js	(revision 3278)
@@ -0,0 +1,22 @@
+/* Slovak initialisation for the jQuery UI date picker plugin. */
+/* Written by Vojtech Rinik (vojto@hmm.sk). */
+jQuery(function($){
+	$.datepicker.regional['sk'] = {clearText: 'Zmazať', clearStatus: '',
+		closeText: 'Zavrieť', closeStatus: '',
+		prevText: '&lt;Predchádzajúci',  prevStatus: '',
+		nextText: 'Nasledujúci&gt;', nextStatus: '',
+		currentText: 'Dnes', currentStatus: '',
+		monthNames: ['Január','Február','Marec','Apríl','Máj','Jún',
+		'Júl','August','September','Október','November','December'],
+		monthNamesShort: ['Jan','Feb','Mar','Apr','Máj','Jún',
+		'Júl','Aug','Sep','Okt','Nov','Dec'],
+		monthStatus: '', yearStatus: '',
+		weekHeader: 'Ty', weekStatus: '',
+		dayNames: ['Nedel\'a','Pondelok','Utorok','Streda','Štvrtok','Piatok','Sobota'],
+		dayNamesShort: ['Ned','Pon','Uto','Str','Štv','Pia','Sob'],
+		dayNamesMin: ['Ne','Po','Ut','St','Št','Pia','So'],
+		dayStatus: 'DD', dateStatus: 'D, M d',
+		dateFormat: 'dd.mm.yy', firstDay: 0, 
+		initStatus: '', isRTL: false};
+	$.datepicker.setDefaults($.datepicker.regional['sk']);
+});
Index: /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-sv.js
===================================================================
--- /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-sv.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-sv.js	(revision 3278)
@@ -0,0 +1,22 @@
+﻿/* Swedish initialisation for the jQuery UI date picker plugin. */
+/* Written by Anders Ekdahl ( anders@nomadiz.se). */
+jQuery(function($){
+    $.datepicker.regional['sv'] = {clearText: 'Rensa', clearStatus: '',
+		closeText: 'Stäng', closeStatus: '',
+        prevText: '&laquo;Förra',  prevStatus: '',
+		nextText: 'Nästa&raquo;', nextStatus: '',
+		currentText: 'Idag', currentStatus: '',
+        monthNames: ['Januari','Februari','Mars','April','Maj','Juni', 
+        'Juli','Augusti','September','Oktober','November','December'],
+        monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun', 
+        'Jul','Aug','Sep','Okt','Nov','Dec'],
+		monthStatus: '', yearStatus: '',
+		weekHeader: 'Ve', weekStatus: '',
+		dayNamesShort: ['Sön','Mån','Tis','Ons','Tor','Fre','Lör'],
+		dayNames: ['Söndag','Måndag','Tisdag','Onsdag','Torsdag','Fredag','Lördag'],
+		dayNamesMin: ['Sö','Må','Ti','On','To','Fr','Lö'],
+		dayStatus: 'DD', dateStatus: 'D, M d',
+        dateFormat: 'yy-mm-dd', firstDay: 1, 
+		initStatus: '', isRTL: false};
+    $.datepicker.setDefaults($.datepicker.regional['sv']); 
+});
Index: /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-th.js
===================================================================
--- /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-th.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-th.js	(revision 3278)
@@ -0,0 +1,22 @@
+﻿/* Thai initialisation for the jQuery UI date picker plugin. */
+/* Written by pipo (pipo@sixhead.com). */
+jQuery(function($){
+	$.datepicker.regional['th'] = {clearText: 'ลบ', clearStatus: '',
+		closeText: 'ปิด', closeStatus: '',
+		prevText: '&laquo;&nbsp;ย้อน', prevStatus: '',
+		nextText: 'ถัดไป&nbsp;&raquo;', nextStatus: '',
+		currentText: 'วันนี้', currentStatus: '',
+		monthNames: ['มกราคม','กุมภาพันธ์','มีนาคม','เมษายน','พฤษภาคม','มิถุนายน',
+		'กรกฏาคม','สิงหาคม','กันยายน','ตุลาคม','พฤศจิกายน','ธันวาคม'],
+		monthNamesShort: ['ม.ค.','ก.พ.','มี.ค.','เม.ย.','พ.ค.','มิ.ย.',
+		'ก.ค.','ส.ค.','ก.ย.','ต.ค.','พ.ย.','ธ.ค.'],
+		monthStatus: '', yearStatus: '',
+		weekHeader: 'Sm', weekStatus: '',
+		dayNames: ['อาทิตย์','จันทร์','อังคาร','พุธ','พฤหัสบดี','ศุกร์','เสาร์'],
+		dayNamesShort: ['อา.','จ.','อ.','พ.','พฤ.','ศ.','ส.'],
+		dayNamesMin: ['อา.','จ.','อ.','พ.','พฤ.','ศ.','ส.'],
+		dayStatus: 'DD', dateStatus: 'D, M d',
+		dateFormat: 'dd/mm/yy', firstDay: 0, 
+		initStatus: '', isRTL: false};
+	$.datepicker.setDefaults($.datepicker.regional['th']);
+});
Index: /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-tr.js
===================================================================
--- /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-tr.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-tr.js	(revision 3278)
@@ -0,0 +1,22 @@
+/* Turkish initialisation for the jQuery UI date picker plugin. */
+/* Written by Izzet Emre Erkan (kara@karalamalar.net). */
+jQuery(function($){
+	$.datepicker.regional['tr'] = {clearText: 'temizle', clearStatus: 'geçerli tarihi temizler',
+		closeText: 'kapat', closeStatus: 'sadece göstergeyi kapat',
+		prevText: '&#x3c;geri', prevStatus: 'önceki ayı göster',
+		nextText: 'ileri&#x3e', nextStatus: 'sonraki ayı göster',
+		currentText: 'bugün', currentStatus: '',
+		monthNames: ['Ocak','Şubat','Mart','Nisan','Mayıs','Haziran',
+		'Temmuz','Ağustos','Eylül','Ekim','Kasım','Aralık'],
+		monthNamesShort: ['Oca','Şub','Mar','Nis','May','Haz',
+		'Tem','Ağu','Eyl','Eki','Kas','Ara'],
+		monthStatus: 'başka ay', yearStatus: 'başka yıl',
+		weekHeader: 'Hf', weekStatus: 'Ayın haftaları',
+		dayNames: ['Pazar','Pazartesi','Salı','Çarşamba','Perşembe','Cuma','Cumartesi'],
+		dayNamesShort: ['Pz','Pt','Sa','Ça','Pe','Cu','Ct'],
+		dayNamesMin: ['Pz','Pt','Sa','Ça','Pe','Cu','Ct'],
+		dayStatus: 'Haftanın ilk gününü belirleyin', dateStatus: 'D, M d seçiniz',
+		dateFormat: 'dd.mm.yy', firstDay: 1, 
+		initStatus: 'Bir tarih seçiniz', isRTL: false};
+	$.datepicker.setDefaults($.datepicker.regional['tr']);
+});
Index: /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-uk.js
===================================================================
--- /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-uk.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-uk.js	(revision 3278)
@@ -0,0 +1,22 @@
+/* Ukrainian (UTF-8) initialisation for the jQuery UI date picker plugin. */
+/* Written by Maxim Drogobitskiy (maxdao@gmail.com). */
+jQuery(function($){
+	$.datepicker.regional['uk'] = {clearText: 'Очистити', clearStatus: '',
+		closeText: 'Закрити', closeStatus: '',
+		prevText: '&lt;&lt;',  prevStatus: '',
+		nextText: '&gt;&gt;', nextStatus: '',
+		currentText: 'Сьогодні', currentStatus: '',
+		monthNames: ['Січень','Лютий','Березень','Квітень','Травень','Червень',
+		'Липень','Серпень','Вересень','Жовтень','Листопад','Грудень'],
+		monthNamesShort: ['Січ','Лют','Бер','Кві','Тра','Чер',
+		'Лип','Сер','Вер','Жов','Лис','Гру'],
+		monthStatus: '', yearStatus: '',
+		weekHeader: 'Не', weekStatus: '',
+		dayNames: ['неділя','понеділок','вівторок','середа','четвер','пятниця','суббота'],
+		dayNamesShort: ['нед','пнд','вів','срд','чтв','птн','сбт'],
+		dayNamesMin: ['Нд','Пн','Вт','Ср','Чт','Пт','Сб'],
+		dayStatus: 'DD', dateStatus: 'D, M d',
+		dateFormat: 'dd.mm.yy', firstDay: 1, 
+		initStatus: '', isRTL: false};
+	$.datepicker.setDefaults($.datepicker.regional['uk']);
+});
Index: /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-zh-CN.js
===================================================================
--- /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-zh-CN.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-zh-CN.js	(revision 3278)
@@ -0,0 +1,22 @@
+/* Chinese initialisation for the jQuery UI date picker plugin. */
+/* Written by Cloudream (cloudream@gmail.com). */
+jQuery(function($){
+	$.datepicker.regional['zh-CN'] = {clearText: '清除', clearStatus: '清除已选日期',
+		closeText: '关闭', closeStatus: '不改变当前选择',
+		prevText: '&lt;上月', prevStatus: '显示上月',
+		nextText: '下月&gt;', nextStatus: '显示下月',
+		currentText: '今天', currentStatus: '显示本月',
+		monthNames: ['一月','二月','三月','四月','五月','六月',
+		'七月','八月','九月','十月','十一月','十二月'],
+		monthNamesShort: ['一','二','三','四','五','六',
+		'七','八','九','十','十一','十二'],
+		monthStatus: '选择月份', yearStatus: '选择年份',
+		weekHeader: '周', weekStatus: '年内周次',
+		dayNames: ['星期日','星期一','星期二','星期三','星期四','星期五','星期六'],
+		dayNamesShort: ['周日','周一','周二','周三','周四','周五','周六'],
+		dayNamesMin: ['日','一','二','三','四','五','六'],
+		dayStatus: '设置 DD 为一周起始', dateStatus: '选择 m月 d日, DD',
+		dateFormat: 'yy-mm-dd', firstDay: 1, 
+		initStatus: '请选择日期', isRTL: false};
+	$.datepicker.setDefaults($.datepicker.regional['zh-CN']);
+});
Index: /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-zh-TW.js
===================================================================
--- /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-zh-TW.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/i18n/ui.datepicker-zh-TW.js	(revision 3278)
@@ -0,0 +1,23 @@
+﻿/* Chinese initialisation for the jQuery UI date picker plugin. */
+/* Written by Ressol (ressol@gmail.com). */
+jQuery(function($){
+	$.datepicker.regional['zh-TW'] = {
+		clearText: '清除', clearStatus: '清除已選日期',
+		closeText: '關閉', closeStatus: '不改變目前的選擇',
+		prevText: '&lt;上月', prevStatus: '顯示上月',
+		nextText: '下月&gt;', nextStatus: '顯示下月',
+		currentText: '今天', currentStatus: '顯示本月',
+		monthNames: ['一月','二月','三月','四月','五月','六月',
+		'七月','八月','九月','十月','十一月','十二月'],
+		monthNamesShort: ['一','二','三','四','五','六',
+		'七','八','九','十','十一','十二'],
+		monthStatus: '選擇月份', yearStatus: '選擇年份',
+		weekHeader: '周', weekStatus: '年內周次',
+		dayNames: ['星期日','星期一','星期二','星期三','星期四','星期五','星期六'],
+		dayNamesShort: ['周日','周一','周二','周三','周四','周五','周六'],
+		dayNamesMin: ['日','一','二','三','四','五','六'],
+		dayStatus: '設定 DD 為一周起始', dateStatus: '選擇 m月 d日, DD',
+		dateFormat: 'yy/mm/dd', firstDay: 1, 
+		initStatus: '請選擇日期', isRTL: false};
+	$.datepicker.setDefaults($.datepicker.regional['zh-TW']);
+});
Index: /tags/2.0.2/template-common/lib/ui/ui.accordion.js
===================================================================
--- /tags/2.0.2/template-common/lib/ui/ui.accordion.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/ui.accordion.js	(revision 3278)
@@ -0,0 +1,295 @@
+/*
+ * jQuery UI Accordion
+ * 
+ * Copyright (c) 2007, 2008 Jörn Zaefferer
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Accordion
+ *
+ * Depends:
+ *	ui.core.js
+ */
+(function($) {
+
+$.widget("ui.accordion", {
+	init: function() {
+		var options = this.options;
+		
+		if ( options.navigation ) {
+			var current = this.element.find("a").filter(options.navigationFilter);
+			if ( current.length ) {
+				if ( current.filter(options.header).length ) {
+					options.active = current;
+				} else {
+					options.active = current.parent().parent().prev();
+					current.addClass("current");
+				}
+			}
+		}
+		
+		// calculate active if not specified, using the first header
+		options.headers = this.element.find(options.header);
+		options.active = findActive(options.headers, options.active);
+		
+		// IE7-/Win - Extra vertical space in Lists fixed
+		if ($.browser.msie) {
+			this.element.find('a').css('zoom', '1');
+		}
+		
+		if (!this.element.hasClass("ui-accordion")) {
+			this.element.addClass("ui-accordion");
+			$("<span class='ui-accordion-left'/>").insertBefore(options.headers);
+			$("<span class='ui-accordion-right'/>").appendTo(options.headers);
+			options.headers.addClass("ui-accordion-header").attr("tabindex", "0");
+		}
+		
+		var maxHeight;
+		if ( options.fillSpace ) {
+			maxHeight = this.element.parent().height();
+			options.headers.each(function() {
+				maxHeight -= $(this).outerHeight();
+			});
+			var maxPadding = 0;
+			options.headers.next().each(function() {
+				maxPadding = Math.max(maxPadding, $(this).innerHeight() - $(this).height());
+			}).height(maxHeight - maxPadding);
+		} else if ( options.autoHeight ) {
+			maxHeight = 0;
+			options.headers.next().each(function() {
+				maxHeight = Math.max(maxHeight, $(this).outerHeight());
+			}).height(maxHeight);
+		}
+	
+		options.headers
+			.not(options.active || "")
+			.next()
+			.hide();
+		options.active.parent().andSelf().addClass(options.selectedClass);
+		
+		if (options.event) {
+			this.element.bind((options.event) + ".accordion", clickHandler);
+		}
+	},
+	activate: function(index) {
+		// call clickHandler with custom event
+		clickHandler.call(this.element[0], {
+			target: findActive( this.options.headers, index )[0]
+		});
+	},
+	destroy: function() {
+		this.options.headers.next().css("display", "");
+		if ( this.options.fillSpace || this.options.autoHeight ) {
+			this.options.headers.next().css("height", "");
+		}
+		$.removeData(this.element[0], "accordion");
+		this.element.removeClass("ui-accordion").unbind(".accordion");
+	}
+});
+
+function scopeCallback(callback, scope) {
+	return function() {
+		return callback.apply(scope, arguments);
+	};
+};
+
+function completed(cancel) {
+	// if removed while animated data can be empty
+	if (!$.data(this, "accordion")) {
+		return;
+	}
+	
+	var instance = $.data(this, "accordion");
+	var options = instance.options;
+	options.running = cancel ? 0 : --options.running;
+	if ( options.running ) {
+		return;
+	}
+	if ( options.clearStyle ) {
+		options.toShow.add(options.toHide).css({
+			height: "",
+			overflow: ""
+		});
+	}
+	$(this).triggerHandler("accordionchange", [$.event.fix({type: 'accordionchange', target: instance.element[0]}), options.data], options.change);
+}
+
+function toggle(toShow, toHide, data, clickedActive, down) {
+	var options = $.data(this, "accordion").options;
+	options.toShow = toShow;
+	options.toHide = toHide;
+	options.data = data;
+	var complete = scopeCallback(completed, this);
+	
+	// count elements to animate
+	options.running = toHide.size() === 0 ? toShow.size() : toHide.size();
+	
+	if ( options.animated ) {
+		if ( !options.alwaysOpen && clickedActive ) {
+			$.ui.accordion.animations[options.animated]({
+				toShow: jQuery([]),
+				toHide: toHide,
+				complete: complete,
+				down: down,
+				autoHeight: options.autoHeight
+			});
+		} else {
+			$.ui.accordion.animations[options.animated]({
+				toShow: toShow,
+				toHide: toHide,
+				complete: complete,
+				down: down,
+				autoHeight: options.autoHeight
+			});
+		}
+	} else {
+		if ( !options.alwaysOpen && clickedActive ) {
+			toShow.toggle();
+		} else {
+			toHide.hide();
+			toShow.show();
+		}
+		complete(true);
+	}
+}
+
+function clickHandler(event) {
+	var options = $.data(this, "accordion").options;
+	if (options.disabled) {
+		return false;
+	}
+	
+	// called only when using activate(false) to close all parts programmatically
+	if ( !event.target && !options.alwaysOpen ) {
+		options.active.parent().andSelf().toggleClass(options.selectedClass);
+		var toHide = options.active.next(),
+			data = {
+				options: options,
+				newHeader: jQuery([]),
+				oldHeader: options.active,
+				newContent: jQuery([]),
+				oldContent: toHide
+			},
+			toShow = (options.active = $([]));
+		toggle.call(this, toShow, toHide, data );
+		return false;
+	}
+	// get the click target
+	var clicked = $(event.target);
+	
+	// due to the event delegation model, we have to check if one
+	// of the parent elements is our actual header, and find that
+	// otherwise stick with the initial target
+	clicked = $( clicked.parents(options.header)[0] || clicked );
+	
+	var clickedActive = clicked[0] == options.active[0];
+	
+	// if animations are still active, or the active header is the target, ignore click
+	if (options.running || (options.alwaysOpen && clickedActive)) {
+		return false;
+	}
+	if (!clicked.is(options.header)) {
+		return;
+	}
+	
+	// switch classes
+	options.active.parent().andSelf().toggleClass(options.selectedClass);
+	if ( !clickedActive ) {
+		clicked.parent().andSelf().addClass(options.selectedClass);
+	}
+	
+	// find elements to show and hide
+	var toShow = clicked.next(),
+		toHide = options.active.next(),
+		//data = [clicked, options.active, toShow, toHide],
+		data = {
+			options: options,
+			newHeader: clicked,
+			oldHeader: options.active,
+			newContent: toShow,
+			oldContent: toHide
+		},
+		down = options.headers.index( options.active[0] ) > options.headers.index( clicked[0] );
+	
+	options.active = clickedActive ? $([]) : clicked;
+	toggle.call(this, toShow, toHide, data, clickedActive, down );
+
+	return false;
+};
+
+function findActive(headers, selector) {
+	return selector != undefined
+		? typeof selector == "number"
+			? headers.filter(":eq(" + selector + ")")
+			: headers.not(headers.not(selector))
+		: selector === false
+			? $([])
+			: headers.filter(":eq(0)");
+}
+
+$.extend($.ui.accordion, {
+	defaults: {
+		selectedClass: "selected",
+		alwaysOpen: true,
+		animated: 'slide',
+		event: "click",
+		header: "a",
+		autoHeight: true,
+		running: 0,
+		navigationFilter: function() {
+			return this.href.toLowerCase() == location.href.toLowerCase();
+		}
+	},
+	animations: {
+		slide: function(options, additions) {
+			options = $.extend({
+				easing: "swing",
+				duration: 300
+			}, options, additions);
+			if ( !options.toHide.size() ) {
+				options.toShow.animate({height: "show"}, options);
+				return;
+			}
+			var hideHeight = options.toHide.height(),
+				showHeight = options.toShow.height(),
+				difference = showHeight / hideHeight;
+			options.toShow.css({ height: 0, overflow: 'hidden' }).show();
+			options.toHide.filter(":hidden").each(options.complete).end().filter(":visible").animate({height:"hide"},{
+				step: function(now) {
+					var current = (hideHeight - now) * difference;
+					if ($.browser.msie || $.browser.opera) {
+						current = Math.ceil(current);
+					}
+					options.toShow.height( current );
+				},
+				duration: options.duration,
+				easing: options.easing,
+				complete: function() {
+					if ( !options.autoHeight ) {
+						options.toShow.css("height", "auto");
+					}
+					options.complete();
+				}
+			});
+		},
+		bounceslide: function(options) {
+			this.slide(options, {
+				easing: options.down ? "bounceout" : "swing",
+				duration: options.down ? 1000 : 200
+			});
+		},
+		easeslide: function(options) {
+			this.slide(options, {
+				easing: "easeinout",
+				duration: 700
+			});
+		}
+	}
+});
+
+// deprecated, use accordion("activate", index) instead
+$.fn.activate = function(index) {
+	return this.accordion("activate", index);
+};
+
+})(jQuery);
Index: /tags/2.0.2/template-common/lib/ui/ui.accordion.packed.js
===================================================================
--- /tags/2.0.2/template-common/lib/ui/ui.accordion.packed.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/ui.accordion.packed.js	(revision 3278)
@@ -0,0 +1,2 @@
+eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)d[e(c)]=k[c]||e(c);k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(4(E){E.2i("e.5",{2h:4(){7 G=2.c;3(G.2g){7 J=2.d.13("a").l(G.1c);3(J.1q){3(J.l(G.n).1q){G.6=J}w{G.6=J.j().j().2f();J.v("2e")}}}G.8=2.d.13(G.n);G.6=C(G.8,G.6);3(E.W.15){2.d.13("a").k("2d","1")}3(!2.d.2c("e-5")){2.d.v("e-5");E("<1p 1o=\'e-5-2b\'/>").2a(G.8);E("<1p 1o=\'e-5-29\'/>").28(G.8);G.8.v("e-5-n").27("26","0")}7 I;3(G.1l){I=2.d.j().b();G.8.O(4(){I-=E(2).1m()});7 H=0;G.8.h().O(4(){H=V.1n(H,E(2).25()-E(2).b())}).b(I-H)}w{3(G.g){I=0;G.8.h().O(4(){I=V.1n(I,E(2).1m())}).b(I)}}G.8.11(G.6||"").h().X();G.6.j().S().v(G.t);3(G.Q){2.d.24((G.Q)+".5",F)}},U:4(G){F.12(2.d[0],{T:C(2.c.8,G)[0]})},23:4(){2.c.8.h().k("22","");3(2.c.1l||2.c.g){2.c.8.h().k("b","")}E.21(2.d[0],"5");2.d.20("e-5").1Z(".5")}});4 B(H,G){9 4(){9 H.1Y(G,1X)}}4 D(I){3(!E.o(2,"5")){9}7 G=E.o(2,"5");7 H=G.c;H.m=I?0:--H.m;3(H.m){9}3(H.1W){H.f.1V(H.i).k({b:"",18:""})}E(2).1U("1k",[E.Q.1T({1S:"1k",T:G.d[0]}),H.o],H.1R)}4 A(G,K,L,J,M){7 I=E.o(2,"5").c;I.f=G;I.i=K;I.o=L;7 H=B(D,2);I.m=K.P()===0?G.P():K.P();3(I.R){3(!I.s&&J){E.e.5.Z[I.R]({f:x([]),i:K,r:H,z:M,g:I.g})}w{E.e.5.Z[I.R]({f:G,i:K,r:H,z:M,g:I.g})}}w{3(!I.s&&J){G.1Q()}w{K.X();G.Y()}H(10)}}4 F(L){7 J=E.o(2,"5").c;3(J.1P){9 u}3(!L.T&&!J.s){J.6.j().S().1j(J.t);7 I=J.6.h(),M={c:J,1i:x([]),1h:J.6,1g:x([]),1f:I},G=(J.6=E([]));A.12(2,G,I,M);9 u}7 K=E(L.T);K=E(K.1O(J.n)[0]||K);7 H=K[0]==J.6[0];3(J.m||(J.s&&H)){9 u}3(!K.1N(J.n)){9}J.6.j().S().1j(J.t);3(!H){K.j().S().v(J.t)}7 G=K.h(),I=J.6.h(),M={c:J,1i:K,1h:J.6,1g:G,1f:I},N=J.8.1e(J.6[0])>J.8.1e(K[0]);J.6=H?E([]):K;A.12(2,G,I,M,H,N);9 u}4 C(H,G){9 G!=1M?1L G=="1K"?H.l(":1d("+G+")"):H.11(H.11(G)):G===u?E([]):H.l(":1d(0)")}E.19(E.e.5,{1J:{t:"1I",s:10,R:"y",Q:"1H",n:"a",g:10,m:0,1c:4(){9 2.1b.1a()==1G.1b.1a()}},Z:{y:4(G,I){G=E.19({q:"14",p:1F},G,I);3(!G.i.P()){G.f.16({b:"Y"},G);9}7 H=G.i.b(),J=G.f.b(),K=J/H;G.f.k({b:0,18:"17"}).Y();G.i.l(":17").O(G.r).1E().l(":1D").16({b:"X"},{1C:4(L){7 M=(H-L)*K;3(E.W.15||E.W.1B){M=V.1A(M)}G.f.b(M)},p:G.p,q:G.q,r:4(){3(!G.g){G.f.k("b","1z")}G.r()}})},1y:4(G){2.y(G,{q:G.z?"1x":"14",p:G.z?1w:1v})},1u:4(G){2.y(G,{q:"1t",p:1s})}}});E.1r.U=4(G){9 2.5("U",G)}})(x)',62,143,'||this|if|function|accordion|active|var|headers|return||height|options|element|ui|toShow|autoHeight|next|toHide|parent|css|filter|running|header|data|duration|easing|complete|alwaysOpen|selectedClass|false|addClass|else|jQuery|slide|down|||||||||||||||each|size|event|animated|andSelf|target|activate|Math|browser|hide|show|animations|true|not|call|find|swing|msie|animate|hidden|overflow|extend|toLowerCase|href|navigationFilter|eq|index|oldContent|newContent|oldHeader|newHeader|toggleClass|accordionchange|fillSpace|outerHeight|max|class|span|length|fn|700|easeinout|easeslide|200|1000|bounceout|bounceslide|auto|ceil|opera|step|visible|end|300|location|click|selected|defaults|number|typeof|undefined|is|parents|disabled|toggle|change|type|fix|triggerHandler|add|clearStyle|arguments|apply|unbind|removeClass|removeData|display|destroy|bind|innerHeight|tabindex|attr|appendTo|right|insertBefore|left|hasClass|zoom|current|prev|navigation|init|widget'.split('|'),0,{}))
+
Index: /tags/2.0.2/template-common/lib/ui/ui.core.js
===================================================================
--- /tags/2.0.2/template-common/lib/ui/ui.core.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/ui.core.js	(revision 3278)
@@ -0,0 +1,291 @@
+/*
+ * jQuery UI 1.5.2
+ *
+ * Copyright (c) 2008 Paul Bakaus (ui.jquery.com)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI
+ */
+;(function($) {
+
+$.ui = {
+	plugin: {
+		add: function(module, option, set) {
+			var proto = $.ui[module].prototype;
+			for(var i in set) {
+				proto.plugins[i] = proto.plugins[i] || [];
+				proto.plugins[i].push([option, set[i]]);
+			}
+		},
+		call: function(instance, name, args) {
+			var set = instance.plugins[name];
+			if(!set) { return; }
+			
+			for (var i = 0; i < set.length; i++) {
+				if (instance.options[set[i][0]]) {
+					set[i][1].apply(instance.element, args);
+				}
+			}
+		}	
+	},
+	cssCache: {},
+	css: function(name) {
+		if ($.ui.cssCache[name]) { return $.ui.cssCache[name]; }
+		var tmp = $('<div class="ui-gen">').addClass(name).css({position:'absolute', top:'-5000px', left:'-5000px', display:'block'}).appendTo('body');
+		
+		//if (!$.browser.safari)
+			//tmp.appendTo('body'); 
+		
+		//Opera and Safari set width and height to 0px instead of auto
+		//Safari returns rgba(0,0,0,0) when bgcolor is not set
+		$.ui.cssCache[name] = !!(
+			(!(/auto|default/).test(tmp.css('cursor')) || (/^[1-9]/).test(tmp.css('height')) || (/^[1-9]/).test(tmp.css('width')) || 
+			!(/none/).test(tmp.css('backgroundImage')) || !(/transparent|rgba\(0, 0, 0, 0\)/).test(tmp.css('backgroundColor')))
+		);
+		try { $('body').get(0).removeChild(tmp.get(0));	} catch(e){}
+		return $.ui.cssCache[name];
+	},
+	disableSelection: function(el) {
+		$(el).attr('unselectable', 'on').css('MozUserSelect', 'none');
+	},
+	enableSelection: function(el) {
+		$(el).attr('unselectable', 'off').css('MozUserSelect', '');
+	},
+	hasScroll: function(e, a) {
+		var scroll = /top/.test(a||"top") ? 'scrollTop' : 'scrollLeft', has = false;
+		if (e[scroll] > 0) return true; e[scroll] = 1;
+		has = e[scroll] > 0 ? true : false; e[scroll] = 0;
+		return has;
+	}
+};
+
+
+/** jQuery core modifications and additions **/
+
+var _remove = $.fn.remove;
+$.fn.remove = function() {
+	$("*", this).add(this).triggerHandler("remove");
+	return _remove.apply(this, arguments );
+};
+
+// $.widget is a factory to create jQuery plugins
+// taking some boilerplate code out of the plugin code
+// created by Scott González and Jörn Zaefferer
+function getter(namespace, plugin, method) {
+	var methods = $[namespace][plugin].getter || [];
+	methods = (typeof methods == "string" ? methods.split(/,?\s+/) : methods);
+	return ($.inArray(method, methods) != -1);
+}
+
+$.widget = function(name, prototype) {
+	var namespace = name.split(".")[0];
+	name = name.split(".")[1];
+	
+	// create plugin method
+	$.fn[name] = function(options) {
+		var isMethodCall = (typeof options == 'string'),
+			args = Array.prototype.slice.call(arguments, 1);
+		
+		if (isMethodCall && getter(namespace, name, options)) {
+			var instance = $.data(this[0], name);
+			return (instance ? instance[options].apply(instance, args)
+				: undefined);
+		}
+		
+		return this.each(function() {
+			var instance = $.data(this, name);
+			if (isMethodCall && instance && $.isFunction(instance[options])) {
+				instance[options].apply(instance, args);
+			} else if (!isMethodCall) {
+				$.data(this, name, new $[namespace][name](this, options));
+			}
+		});
+	};
+	
+	// create widget constructor
+	$[namespace][name] = function(element, options) {
+		var self = this;
+		
+		this.widgetName = name;
+		this.widgetBaseClass = namespace + '-' + name;
+		
+		this.options = $.extend({}, $.widget.defaults, $[namespace][name].defaults, options);
+		this.element = $(element)
+			.bind('setData.' + name, function(e, key, value) {
+				return self.setData(key, value);
+			})
+			.bind('getData.' + name, function(e, key) {
+				return self.getData(key);
+			})
+			.bind('remove', function() {
+				return self.destroy();
+			});
+		this.init();
+	};
+	
+	// add widget prototype
+	$[namespace][name].prototype = $.extend({}, $.widget.prototype, prototype);
+};
+
+$.widget.prototype = {
+	init: function() {},
+	destroy: function() {
+		this.element.removeData(this.widgetName);
+	},
+	
+	getData: function(key) {
+		return this.options[key];
+	},
+	setData: function(key, value) {
+		this.options[key] = value;
+		
+		if (key == 'disabled') {
+			this.element[value ? 'addClass' : 'removeClass'](
+				this.widgetBaseClass + '-disabled');
+		}
+	},
+	
+	enable: function() {
+		this.setData('disabled', false);
+	},
+	disable: function() {
+		this.setData('disabled', true);
+	}
+};
+
+$.widget.defaults = {
+	disabled: false
+};
+
+
+/** Mouse Interaction Plugin **/
+
+$.ui.mouse = {
+	mouseInit: function() {
+		var self = this;
+	
+		this.element.bind('mousedown.'+this.widgetName, function(e) {
+			return self.mouseDown(e);
+		});
+		
+		// Prevent text selection in IE
+		if ($.browser.msie) {
+			this._mouseUnselectable = this.element.attr('unselectable');
+			this.element.attr('unselectable', 'on');
+		}
+		
+		this.started = false;
+	},
+	
+	// TODO: make sure destroying one instance of mouse doesn't mess with
+	// other instances of mouse
+	mouseDestroy: function() {
+		this.element.unbind('.'+this.widgetName);
+		
+		// Restore text selection in IE
+		($.browser.msie
+			&& this.element.attr('unselectable', this._mouseUnselectable));
+	},
+	
+	mouseDown: function(e) {
+		// we may have missed mouseup (out of window)
+		(this._mouseStarted && this.mouseUp(e));
+		
+		this._mouseDownEvent = e;
+		
+		var self = this,
+			btnIsLeft = (e.which == 1),
+			elIsCancel = (typeof this.options.cancel == "string" ? $(e.target).parents().add(e.target).filter(this.options.cancel).length : false);
+		if (!btnIsLeft || elIsCancel || !this.mouseCapture(e)) {
+			return true;
+		}
+		
+		this._mouseDelayMet = !this.options.delay;
+		if (!this._mouseDelayMet) {
+			this._mouseDelayTimer = setTimeout(function() {
+				self._mouseDelayMet = true;
+			}, this.options.delay);
+		}
+		
+		if (this.mouseDistanceMet(e) && this.mouseDelayMet(e)) {
+			this._mouseStarted = (this.mouseStart(e) !== false);
+			if (!this._mouseStarted) {
+				e.preventDefault();
+				return true;
+			}
+		}
+		
+		// these delegates are required to keep context
+		this._mouseMoveDelegate = function(e) {
+			return self.mouseMove(e);
+		};
+		this._mouseUpDelegate = function(e) {
+			return self.mouseUp(e);
+		};
+		$(document)
+			.bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
+			.bind('mouseup.'+this.widgetName, this._mouseUpDelegate);
+		
+		return false;
+	},
+	
+	mouseMove: function(e) {
+		// IE mouseup check - mouseup happened when mouse was out of window
+		if ($.browser.msie && !e.button) {
+			return this.mouseUp(e);
+		}
+		
+		if (this._mouseStarted) {
+			this.mouseDrag(e);
+			return false;
+		}
+		
+		if (this.mouseDistanceMet(e) && this.mouseDelayMet(e)) {
+			this._mouseStarted =
+				(this.mouseStart(this._mouseDownEvent, e) !== false);
+			(this._mouseStarted ? this.mouseDrag(e) : this.mouseUp(e));
+		}
+		
+		return !this._mouseStarted;
+	},
+	
+	mouseUp: function(e) {
+		$(document)
+			.unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
+			.unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
+		
+		if (this._mouseStarted) {
+			this._mouseStarted = false;
+			this.mouseStop(e);
+		}
+		
+		return false;
+	},
+	
+	mouseDistanceMet: function(e) {
+		return (Math.max(
+				Math.abs(this._mouseDownEvent.pageX - e.pageX),
+				Math.abs(this._mouseDownEvent.pageY - e.pageY)
+			) >= this.options.distance
+		);
+	},
+	
+	mouseDelayMet: function(e) {
+		return this._mouseDelayMet;
+	},
+	
+	// These are placeholder methods, to be overriden by extending plugin
+	mouseStart: function(e) {},
+	mouseDrag: function(e) {},
+	mouseStop: function(e) {},
+	mouseCapture: function(e) { return true; }
+};
+
+$.ui.mouse.defaults = {
+	cancel: null,
+	distance: 1,
+	delay: 0
+};
+
+})(jQuery);
Index: /tags/2.0.2/template-common/lib/ui/ui.core.packed.js
===================================================================
--- /tags/2.0.2/template-common/lib/ui/ui.core.packed.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/ui.core.packed.js	(revision 3278)
@@ -0,0 +1,2 @@
+eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)d[e(c)]=k[c]||e(c);k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(3(C){C.8={2r:{V:3(E,F,H){6 G=C.8[E].o;1v(6 D 2q H){G.w[D]=G.w[D]||[];G.w[D].2p([F,H[D]])}},1p:3(D,F,E){6 H=D.w[F];5(!H){4}1v(6 G=0;G<H.1e;G++){5(D.a[H[G][0]]){H[G][1].v(D.c,E)}}}},p:{},d:3(D){5(C.8.p[D]){4 C.8.p[D]}6 E=C(\'<2o 2n="8-2m">\').1k(D).d({2l:"2k",12:"-1u",2j:"-1u",2i:"2h"}).2g("1t");C.8.p[D]=!!((!(/2f|2e/).h(E.d("2d"))||(/^[1-9]/).h(E.d("2c"))||(/^[1-9]/).h(E.d("2b"))||!(/1r/).h(E.d("2a"))||!(/29|28\\(0, 0, 0, 0\\)/).h(E.d("27"))));26{C("1t").1s(0).25(E.1s(0))}24(F){}4 C.8.p[D]},23:3(D){C(D).k("j","1i").d("1q","1r")},22:3(D){C(D).k("j","21").d("1q","")},20:3(G,E){6 D=/12/.h(E||"12")?"1Z":"1Y",F=7;5(G[D]>0){4 f}G[D]=1;F=G[D]>0?f:7;G[D]=0;4 F}};6 B=C.10.u;C.10.u=3(){C("*",2).V(2).1X("u");4 B.v(2,1o)};3 A(E,F,G){6 D=C[E][F].1W||[];D=(X D=="W"?D.11(/,?\\s+/):D);4(C.1V(G,D)!=-1)}C.m=3(E,D){6 F=E.11(".")[0];E=E.11(".")[1];C.10[E]=3(J){6 H=(X J=="W"),I=1U.o.1T.1p(1o,1);5(H&&A(F,E,J)){6 G=C.Z(2[0],E);4(G?G[J].v(G,I):1S)}4 2.1R(3(){6 K=C.Z(2,E);5(H&&K&&C.1Q(K[J])){K[J].v(K,I)}1P{5(!H){C.Z(2,E,1O C[F][E](2,J))}}})};C[F][E]=3(I,H){6 G=2;2.e=E;2.1j=F+"-"+E;2.a=C.1n({},C.m.q,C[F][E].q,H);2.c=C(I).g("n."+E,3(L,J,K){4 G.n(J,K)}).g("Y."+E,3(K,J){4 G.Y(J)}).g("u",3(){4 G.1l()});2.1m()};C[F][E].o=C.1n({},C.m.o,D)};C.m.o={1m:3(){},1l:3(){2.c.1N(2.e)},Y:3(D){4 2.a[D]},n:3(D,E){2.a[D]=E;5(D=="l"){2.c[E?"1k":"1M"](2.1j+"-l")}},1L:3(){2.n("l",7)},1K:3(){2.n("l",f)}};C.m.q={l:7};C.8.14={1J:3(){6 D=2;2.c.g("1I."+2.e,3(E){4 D.1g(E)});5(C.U.T){2.1h=2.c.k("j");2.c.k("j","1i")}2.1H=7},1G:3(){2.c.R("."+2.e);(C.U.T&&2.c.k("j",2.1h))},1g:3(F){(2.b&&2.i(F));2.t=F;6 E=2,G=(F.1F==1),D=(X 2.a.y=="W"?C(F.1f).1E().V(F.1f).1D(2.a.y).1e:7);5(!G||D||!2.15(F)){4 f}2.r=!2.a.x;5(!2.r){2.1C=1B(3(){E.r=f},2.a.x)}5(2.P(F)&&2.N(F)){2.b=(2.M(F)!==7);5(!2.b){F.1A();4 f}}2.S=3(H){4 E.1d(H)};2.Q=3(H){4 E.i(H)};C(1c).g("1b."+2.e,2.S).g("1a."+2.e,2.Q);4 7},1d:3(D){5(C.U.T&&!D.1z){4 2.i(D)}5(2.b){2.z(D);4 7}5(2.P(D)&&2.N(D)){2.b=(2.M(2.t,D)!==7);(2.b?2.z(D):2.i(D))}4!2.b},i:3(D){C(1c).R("1b."+2.e,2.S).R("1a."+2.e,2.Q);5(2.b){2.b=7;2.16(D)}4 7},P:3(D){4(O.1y(O.18(2.t.19-D.19),O.18(2.t.17-D.17))>=2.a.13)},N:3(D){4 2.r},M:3(D){},z:3(D){},16:3(D){},15:3(D){4 f}};C.8.14.q={y:1x,13:1,x:0}})(1w)',62,152,'||this|function|return|if|var|false|ui||options|_mouseStarted|element|css|widgetName|true|bind|test|mouseUp|unselectable|attr|disabled|widget|setData|prototype|cssCache|defaults|_mouseDelayMet||_mouseDownEvent|remove|apply|plugins|delay|cancel|mouseDrag|||||||||||||mouseStart|mouseDelayMet|Math|mouseDistanceMet|_mouseUpDelegate|unbind|_mouseMoveDelegate|msie|browser|add|string|typeof|getData|data|fn|split|top|distance|mouse|mouseCapture|mouseStop|pageY|abs|pageX|mouseup|mousemove|document|mouseMove|length|target|mouseDown|_mouseUnselectable|on|widgetBaseClass|addClass|destroy|init|extend|arguments|call|MozUserSelect|none|get|body|5000px|for|jQuery|null|max|button|preventDefault|setTimeout|_mouseDelayTimer|filter|parents|which|mouseDestroy|started|mousedown|mouseInit|disable|enable|removeClass|removeData|new|else|isFunction|each|undefined|slice|Array|inArray|getter|triggerHandler|scrollLeft|scrollTop|hasScroll|off|enableSelection|disableSelection|catch|removeChild|try|backgroundColor|rgba|transparent|backgroundImage|width|height|cursor|default|auto|appendTo|block|display|left|absolute|position|gen|class|div|push|in|plugin'.split('|'),0,{}))
+
Index: /tags/2.0.2/template-common/lib/ui/ui.datepicker.css
===================================================================
--- /tags/2.0.2/template-common/lib/ui/ui.datepicker.css	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/ui.datepicker.css	(revision 3278)
@@ -0,0 +1,214 @@
+/* $Id */
+/* Main Style Sheet for jQuery UI date picker */
+#ui-datepicker-div, .ui-datepicker-inline {
+	font-family: Arial, Helvetica, sans-serif;
+	font-size: 14px;
+	padding: 0;
+	margin: 0;
+	background: #ddd;
+	width: 185px;
+}
+#ui-datepicker-div {
+	display: none;
+	border: 1px solid #777;
+	z-index: 100; /*must have*/
+}
+.ui-datepicker-inline {
+	float: left;
+	display: block;
+	border: 0;
+}
+.ui-datepicker-rtl {
+	direction: rtl;
+}
+.ui-datepicker-dialog {
+	padding: 5px !important;
+	border: 4px ridge #ddd !important;
+}
+.ui-datepicker-disabled {
+	position: absolute;
+	z-index: 100;
+	background-color: white;
+	opacity: 0.5;
+}
+button.ui-datepicker-trigger {
+	width: 25px;
+}
+img.ui-datepicker-trigger {
+	margin: 2px;
+	vertical-align: middle;
+}
+.ui-datepicker-prompt {
+	float: left;
+	padding: 2px;
+	background: #ddd;
+	color: #000;
+}
+* html .ui-datepicker-prompt {
+	width: 185px;
+}
+.ui-datepicker-control, .ui-datepicker-links, .ui-datepicker-header, .ui-datepicker {
+	clear: both;
+	float: left;
+	width: 100%;
+	color: #fff;
+}
+.ui-datepicker-control {
+	background: #400;
+	padding: 2px 0px;
+}
+.ui-datepicker-links {
+	background: #000;
+	padding: 2px 0px;
+}
+.ui-datepicker-control, .ui-datepicker-links {
+	font-weight: bold;
+	font-size: 80%;
+}
+.ui-datepicker-links label { /* disabled links */
+	padding: 2px 5px;
+	color: #888;
+}
+.ui-datepicker-clear, .ui-datepicker-prev {
+	float: left;
+	width: 34%;
+}
+.ui-datepicker-rtl .ui-datepicker-clear, .ui-datepicker-rtl .ui-datepicker-prev {
+	float: right;
+	text-align: right;
+}
+.ui-datepicker-current {
+	float: left;
+	width: 30%;
+	text-align: center;
+}
+.ui-datepicker-close, .ui-datepicker-next {
+	float: right;
+	width: 34%;
+	text-align: right;
+}
+.ui-datepicker-rtl .ui-datepicker-close, .ui-datepicker-rtl .ui-datepicker-next {
+	float: left;
+	text-align: left;
+}
+.ui-datepicker-header {
+	padding: 1px 0 3px;
+	background: #333;
+	text-align: center;
+	font-weight: bold;
+	height: 1.3em;
+}
+.ui-datepicker-header select {
+	background: #333;
+	color: #fff;
+	border: 0px;
+	font-weight: bold;
+}
+.ui-datepicker {
+	background: #ccc;
+	text-align: center;
+	font-size: 100%;
+}
+.ui-datepicker a {
+	display: block;
+	width: 100%;
+}
+.ui-datepicker-title-row {
+	background: #777;
+}
+.ui-datepicker-days-row {
+	background: #eee;
+	color: #666;
+}
+.ui-datepicker-week-col {
+	background: #777;
+	color: #fff;
+}
+.ui-datepicker-days-cell {
+	color: #000;
+	border: 1px solid #ddd;
+}
+.ui-datepicker-days-cell a{
+	display: block;
+}
+.ui-datepicker-week-end-cell {
+	background: #ddd;
+}
+.ui-datepicker-title-row .ui-datepicker-week-end-cell {
+	background: #777;
+}
+.ui-datepicker-days-cell-over {
+	background: #fff;
+	border: 1px solid #777;
+}
+.ui-datepicker-unselectable {
+	color: #888;
+}
+.ui-datepicker-today {
+	background: #fcc !important;
+}
+.ui-datepicker-current-day {
+	background: #999 !important;
+}
+.ui-datepicker-status {
+	background: #ddd;
+	width: 100%;
+	font-size: 80%;
+	text-align: center;
+}
+
+/* ________ Datepicker Links _______
+
+** Reset link properties and then override them with !important */
+#ui-datepicker-div a, .ui-datepicker-inline a {
+	cursor: pointer;
+	margin: 0;
+	padding: 0;
+	background: none;
+	color: #000;
+}
+.ui-datepicker-inline .ui-datepicker-links a {
+	padding: 0 5px !important;
+}
+.ui-datepicker-control a, .ui-datepicker-links a {
+	padding: 2px 5px !important;
+	color: #eee !important;
+}
+.ui-datepicker-title-row a {
+	color: #eee !important;
+}
+.ui-datepicker-control a:hover {
+	background: #fdd !important;
+	color: #333 !important;
+}
+.ui-datepicker-links a:hover, .ui-datepicker-title-row a:hover {
+	background: #ddd !important;
+	color: #333 !important;
+}
+
+/* ___________ MULTIPLE MONTHS _________*/
+
+.ui-datepicker-multi .ui-datepicker {
+	border: 1px solid #777;
+}
+.ui-datepicker-one-month {
+	float: left;
+	width: 185px;
+}
+.ui-datepicker-new-row {
+	clear: left;
+}
+
+/* ___________ IE6 IFRAME FIX ________ */
+
+.ui-datepicker-cover {
+    display: none; /*sorry for IE5*/
+    display/**/: block; /*sorry for IE5*/
+    position: absolute; /*must have*/
+    z-index: -1; /*must have*/
+    filter: mask(); /*must have*/
+    top: -4px; /*must have*/
+    left: -4px; /*must have*/
+    width: 200px; /*must have*/
+    height: 200px; /*must have*/
+}
Index: /tags/2.0.2/template-common/lib/ui/ui.datepicker.js
===================================================================
--- /tags/2.0.2/template-common/lib/ui/ui.datepicker.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/ui.datepicker.js	(revision 3278)
@@ -0,0 +1,1533 @@
+/*
+ * jQuery UI Datepicker
+ *
+ * Copyright (c) 2006, 2007, 2008 Marc Grabanski
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ * 
+ * http://docs.jquery.com/UI/Datepicker
+ *
+ * Depends:
+ *	ui.core.js
+ *
+ * Marc Grabanski (m@marcgrabanski.com) and Keith Wood (kbwood@virginbroadband.com.au).
+ */
+   
+(function($) { // hide the namespace
+
+var PROP_NAME = 'datepicker';
+
+/* Date picker manager.
+   Use the singleton instance of this class, $.datepicker, to interact with the date picker.
+   Settings for (groups of) date pickers are maintained in an instance object,
+   allowing multiple different settings on the same page. */
+
+function Datepicker() {
+	this.debug = false; // Change this to true to start debugging
+	this._curInst = null; // The current instance in use
+	this._disabledInputs = []; // List of date picker inputs that have been disabled
+	this._datepickerShowing = false; // True if the popup picker is showing , false if not
+	this._inDialog = false; // True if showing within a "dialog", false if not
+	this._mainDivId = 'ui-datepicker-div'; // The ID of the main datepicker division
+	this._appendClass = 'ui-datepicker-append'; // The name of the append marker class
+	this._triggerClass = 'ui-datepicker-trigger'; // The name of the trigger marker class
+	this._dialogClass = 'ui-datepicker-dialog'; // The name of the dialog marker class
+	this._promptClass = 'ui-datepicker-prompt'; // The name of the dialog prompt marker class
+	this._unselectableClass = 'ui-datepicker-unselectable'; // The name of the unselectable cell marker class
+	this._currentClass = 'ui-datepicker-current-day'; // The name of the current day marker class
+	this.regional = []; // Available regional settings, indexed by language code
+	this.regional[''] = { // Default regional settings
+		clearText: 'Clear', // Display text for clear link
+		clearStatus: 'Erase the current date', // Status text for clear link
+		closeText: 'Close', // Display text for close link
+		closeStatus: 'Close without change', // Status text for close link
+		prevText: '&#x3c;Prev', // Display text for previous month link
+		prevStatus: 'Show the previous month', // Status text for previous month link
+		nextText: 'Next&#x3e;', // Display text for next month link
+		nextStatus: 'Show the next month', // Status text for next month link
+		currentText: 'Today', // Display text for current month link
+		currentStatus: 'Show the current month', // Status text for current month link
+		monthNames: ['January','February','March','April','May','June',
+			'July','August','September','October','November','December'], // Names of months for drop-down and formatting
+		monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], // For formatting
+		monthStatus: 'Show a different month', // Status text for selecting a month
+		yearStatus: 'Show a different year', // Status text for selecting a year
+		weekHeader: 'Wk', // Header for the week of the year column
+		weekStatus: 'Week of the year', // Status text for the week of the year column
+		dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // For formatting
+		dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // For formatting
+		dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], // Column headings for days starting at Sunday
+		dayStatus: 'Set DD as first week day', // Status text for the day of the week selection
+		dateStatus: 'Select DD, M d', // Status text for the date selection
+		dateFormat: 'mm/dd/yy', // See format options on parseDate
+		firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
+		initStatus: 'Select a date', // Initial Status text on opening
+		isRTL: false // True if right-to-left language, false if left-to-right
+	};
+	this._defaults = { // Global defaults for all the date picker instances
+		showOn: 'focus', // 'focus' for popup on focus,
+			// 'button' for trigger button, or 'both' for either
+		showAnim: 'show', // Name of jQuery animation for popup
+		showOptions: {}, // Options for enhanced animations
+		defaultDate: null, // Used when field is blank: actual date,
+			// +/-number for offset from today, null for today
+		appendText: '', // Display text following the input box, e.g. showing the format
+		buttonText: '...', // Text for trigger button
+		buttonImage: '', // URL for trigger button image
+		buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
+		closeAtTop: true, // True to have the clear/close at the top,
+			// false to have them at the bottom
+		mandatory: false, // True to hide the Clear link, false to include it
+		hideIfNoPrevNext: false, // True to hide next/previous month links
+			// if not applicable, false to just disable them
+		navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
+		gotoCurrent: false, // True if today link goes back to current selection instead
+		changeMonth: true, // True if month can be selected directly, false if only prev/next
+		changeYear: true, // True if year can be selected directly, false if only prev/next
+		yearRange: '-10:+10', // Range of years to display in drop-down,
+			// either relative to current year (-nn:+nn) or absolute (nnnn:nnnn)
+		changeFirstDay: true, // True to click on day name to change, false to remain as set
+		highlightWeek: false, // True to highlight the selected week
+		showOtherMonths: false, // True to show dates in other months, false to leave blank
+		showWeeks: false, // True to show week of the year, false to omit
+		calculateWeek: this.iso8601Week, // How to calculate the week of the year,
+			// takes a Date and returns the number of the week for it
+		shortYearCutoff: '+10', // Short year values < this are in the current century,
+			// > this are in the previous century, 
+			// string value starting with '+' for current year + value
+		showStatus: false, // True to show status bar at bottom, false to not show it
+		statusForDate: this.dateStatus, // Function to provide status text for a date -
+			// takes date and instance as parameters, returns display text
+		minDate: null, // The earliest selectable date, or null for no limit
+		maxDate: null, // The latest selectable date, or null for no limit
+		duration: 'normal', // Duration of display/closure
+		beforeShowDay: null, // Function that takes a date and returns an array with
+			// [0] = true if selectable, false if not, [1] = custom CSS class name(s) or '', 
+			// [2] = cell title (optional), e.g. $.datepicker.noWeekends
+		beforeShow: null, // Function that takes an input field and
+			// returns a set of custom settings for the date picker
+		onSelect: null, // Define a callback function when a date is selected
+		onChangeMonthYear: null, // Define a callback function when the month or year is changed
+		onClose: null, // Define a callback function when the datepicker is closed
+		numberOfMonths: 1, // Number of months to show at a time
+		stepMonths: 1, // Number of months to step back/forward
+		rangeSelect: false, // Allows for selecting a date range on one date picker
+		rangeSeparator: ' - ', // Text between two dates in a range
+		altField: '', // Selector for an alternate field to store selected dates into
+		altFormat: '' // The date format to use for the alternate field
+	};
+	$.extend(this._defaults, this.regional['']);
+	this.dpDiv = $('<div id="' + this._mainDivId + '" style="display: none;"></div>');
+}
+
+$.extend(Datepicker.prototype, {
+	/* Class name added to elements to indicate already configured with a date picker. */
+	markerClassName: 'hasDatepicker',
+
+	/* Debug logging (if enabled). */
+	log: function () {
+		if (this.debug)
+			console.log.apply('', arguments);
+	},
+	
+	/* Override the default settings for all instances of the date picker. 
+	   @param  settings  object - the new settings to use as defaults (anonymous object)
+	   @return the manager object */
+	setDefaults: function(settings) {
+		extendRemove(this._defaults, settings || {});
+		return this;
+	},
+
+	/* Attach the date picker to a jQuery selection.
+	   @param  target    element - the target input field or division or span
+	   @param  settings  object - the new settings to use for this date picker instance (anonymous) */
+	_attachDatepicker: function(target, settings) {
+		// check for settings on the control itself - in namespace 'date:'
+		var inlineSettings = null;
+		for (attrName in this._defaults) {
+			var attrValue = target.getAttribute('date:' + attrName);
+			if (attrValue) {
+				inlineSettings = inlineSettings || {};
+				try {
+					inlineSettings[attrName] = eval(attrValue);
+				} catch (err) {
+					inlineSettings[attrName] = attrValue;
+				}
+			}
+		}
+		var nodeName = target.nodeName.toLowerCase();
+		var inline = (nodeName == 'div' || nodeName == 'span');
+		if (!target.id)
+			target.id = 'dp' + new Date().getTime();
+		var inst = this._newInst($(target), inline);
+		inst.settings = $.extend({}, settings || {}, inlineSettings || {}); 
+		if (nodeName == 'input') {
+			this._connectDatepicker(target, inst);
+		} else if (inline) {
+			this._inlineDatepicker(target, inst);
+		}
+	},
+
+	/* Create a new instance object. */
+	_newInst: function(target, inline) {
+		return {id: target[0].id, input: target, // associated target
+			selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
+			drawMonth: 0, drawYear: 0, // month being drawn
+			inline: inline, // is datepicker inline or not
+			dpDiv: (!inline ? this.dpDiv : // presentation div
+			$('<div class="ui-datepicker-inline"></div>'))};
+	},
+
+	/* Attach the date picker to an input field. */
+	_connectDatepicker: function(target, inst) {
+		var input = $(target);
+		if (input.hasClass(this.markerClassName))
+			return;
+		var appendText = this._get(inst, 'appendText');
+		var isRTL = this._get(inst, 'isRTL');
+		if (appendText)
+			input[isRTL ? 'before' : 'after']('<span class="' + this._appendClass + '">' + appendText + '</span>');
+		var showOn = this._get(inst, 'showOn');
+		if (showOn == 'focus' || showOn == 'both') // pop-up date picker when in the marked field
+			input.focus(this._showDatepicker);
+		if (showOn == 'button' || showOn == 'both') { // pop-up date picker when button clicked
+			var buttonText = this._get(inst, 'buttonText');
+			var buttonImage = this._get(inst, 'buttonImage');
+			var trigger = $(this._get(inst, 'buttonImageOnly') ? 
+				$('<img/>').addClass(this._triggerClass).
+					attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
+				$('<button type="button"></button>').addClass(this._triggerClass).
+					html(buttonImage == '' ? buttonText : $('<img/>').attr(
+					{ src:buttonImage, alt:buttonText, title:buttonText })));
+			input[isRTL ? 'before' : 'after'](trigger);
+			trigger.click(function() {
+				if ($.datepicker._datepickerShowing && $.datepicker._lastInput == target)
+					$.datepicker._hideDatepicker();
+				else
+					$.datepicker._showDatepicker(target);
+				return false;
+			});
+		}
+		input.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).
+			bind("setData.datepicker", function(event, key, value) {
+				inst.settings[key] = value;
+			}).bind("getData.datepicker", function(event, key) {
+				return this._get(inst, key);
+			});
+		$.data(target, PROP_NAME, inst);
+	},
+
+	/* Attach an inline date picker to a div. */
+	_inlineDatepicker: function(target, inst) {
+		var input = $(target);
+		if (input.hasClass(this.markerClassName))
+			return;
+		input.addClass(this.markerClassName).append(inst.dpDiv).
+			bind("setData.datepicker", function(event, key, value){
+				inst.settings[key] = value;
+			}).bind("getData.datepicker", function(event, key){
+				return this._get(inst, key);
+			});
+		$.data(target, PROP_NAME, inst);
+		this._setDate(inst, this._getDefaultDate(inst));
+		this._updateDatepicker(inst);
+	},
+
+	/* Tidy up after displaying the date picker. */
+	_inlineShow: function(inst) {
+		var numMonths = this._getNumberOfMonths(inst); // fix width for dynamic number of date pickers
+		inst.dpDiv.width(numMonths[1] * $('.ui-datepicker', inst.dpDiv[0]).width());
+	}, 
+
+	/* Pop-up the date picker in a "dialog" box.
+	   @param  input     element - ignored
+	   @param  dateText  string - the initial date to display (in the current format)
+	   @param  onSelect  function - the function(dateText) to call when a date is selected
+	   @param  settings  object - update the dialog date picker instance's settings (anonymous object)
+	   @param  pos       int[2] - coordinates for the dialog's position within the screen or
+	                     event - with x/y coordinates or
+	                     leave empty for default (screen centre)
+	   @return the manager object */
+	_dialogDatepicker: function(input, dateText, onSelect, settings, pos) {
+		var inst = this._dialogInst; // internal instance
+		if (!inst) {
+			var id = 'dp' + new Date().getTime();
+			this._dialogInput = $('<input type="text" id="' + id +
+				'" size="1" style="position: absolute; top: -100px;"/>');
+			this._dialogInput.keydown(this._doKeyDown);
+			$('body').append(this._dialogInput);
+			inst = this._dialogInst = this._newInst(this._dialogInput, false);
+			inst.settings = {};
+			$.data(this._dialogInput[0], PROP_NAME, inst);
+		}
+		extendRemove(inst.settings, settings || {});
+		this._dialogInput.val(dateText);
+
+		this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
+		if (!this._pos) {
+			var browserWidth = window.innerWidth || document.documentElement.clientWidth ||	document.body.clientWidth;
+			var browserHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
+			var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
+			var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
+			this._pos = // should use actual width/height below
+				[(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
+		}
+
+		// move input on screen for focus, but hidden behind dialog
+		this._dialogInput.css('left', this._pos[0] + 'px').css('top', this._pos[1] + 'px');
+		inst.settings.onSelect = onSelect;
+		this._inDialog = true;
+		this.dpDiv.addClass(this._dialogClass);
+		this._showDatepicker(this._dialogInput[0]);
+		if ($.blockUI)
+			$.blockUI(this.dpDiv);
+		$.data(this._dialogInput[0], PROP_NAME, inst);
+		return this;
+	},
+
+	/* Detach a datepicker from its control.
+	   @param  target    element - the target input field or division or span */
+	_destroyDatepicker: function(target) {
+		var nodeName = target.nodeName.toLowerCase();
+		var $target = $(target);
+		$.removeData(target, PROP_NAME);
+		if (nodeName == 'input') {
+			$target.siblings('.' + this._appendClass).remove().end().
+				siblings('.' + this._triggerClass).remove().end().
+				removeClass(this.markerClassName).
+				unbind('focus', this._showDatepicker).
+				unbind('keydown', this._doKeyDown).
+				unbind('keypress', this._doKeyPress);
+		} else if (nodeName == 'div' || nodeName == 'span')
+			$target.removeClass(this.markerClassName).empty();
+	},
+
+	/* Enable the date picker to a jQuery selection.
+	   @param  target    element - the target input field or division or span */
+	_enableDatepicker: function(target) {
+		target.disabled = false;
+		$(target).siblings('button.' + this._triggerClass).each(function() { this.disabled = false; }).end().
+			siblings('img.' + this._triggerClass).css({opacity: '1.0', cursor: ''});
+		this._disabledInputs = $.map(this._disabledInputs,
+			function(value) { return (value == target ? null : value); }); // delete entry
+	},
+
+	/* Disable the date picker to a jQuery selection.
+	   @param  target    element - the target input field or division or span */
+	_disableDatepicker: function(target) {
+		target.disabled = true;
+		$(target).siblings('button.' + this._triggerClass).each(function() { this.disabled = true; }).end().
+			siblings('img.' + this._triggerClass).css({opacity: '0.5', cursor: 'default'});
+		this._disabledInputs = $.map(this._disabledInputs,
+			function(value) { return (value == target ? null : value); }); // delete entry
+		this._disabledInputs[this._disabledInputs.length] = target;
+	},
+
+	/* Is the first field in a jQuery collection disabled as a datepicker?
+	   @param  target    element - the target input field or division or span
+	   @return boolean - true if disabled, false if enabled */
+	_isDisabledDatepicker: function(target) {
+		if (!target)
+			return false;
+		for (var i = 0; i < this._disabledInputs.length; i++) {
+			if (this._disabledInputs[i] == target)
+				return true;
+		}
+		return false;
+	},
+
+	/* Update the settings for a date picker attached to an input field or division.
+	   @param  target  element - the target input field or division or span
+	   @param  name    object - the new settings to update or
+	                   string - the name of the setting to change or
+	   @param  value   any - the new value for the setting (omit if above is an object) */
+	_changeDatepicker: function(target, name, value) {
+		var settings = name || {};
+		if (typeof name == 'string') {
+			settings = {};
+			settings[name] = value;
+		}
+		if (inst = $.data(target, PROP_NAME)) {
+			extendRemove(inst.settings, settings);
+			this._updateDatepicker(inst);
+		}
+	},
+
+	/* Set the dates for a jQuery selection.
+	   @param  target   element - the target input field or division or span
+	   @param  date     Date - the new date
+	   @param  endDate  Date - the new end date for a range (optional) */
+	_setDateDatepicker: function(target, date, endDate) {
+		var inst = $.data(target, PROP_NAME);
+		if (inst) {
+			this._setDate(inst, date, endDate);
+			this._updateDatepicker(inst);
+		}
+	},
+
+	/* Get the date(s) for the first entry in a jQuery selection.
+	   @param  target  element - the target input field or division or span
+	   @return Date - the current date or
+	           Date[2] - the current dates for a range */
+	_getDateDatepicker: function(target) {
+		var inst = $.data(target, PROP_NAME);
+		if (inst)
+			this._setDateFromField(inst); 
+		return (inst ? this._getDate(inst) : null);
+	},
+
+	/* Handle keystrokes. */
+	_doKeyDown: function(e) {
+		var inst = $.data(e.target, PROP_NAME);
+		var handled = true;
+		if ($.datepicker._datepickerShowing)
+			switch (e.keyCode) {
+				case 9:  $.datepicker._hideDatepicker(null, '');
+						break; // hide on tab out
+				case 13: $.datepicker._selectDay(e.target, inst.selectedMonth, inst.selectedYear,
+							$('td.ui-datepicker-days-cell-over', inst.dpDiv)[0]);
+						return false; // don't submit the form
+						break; // select the value on enter
+				case 27: $.datepicker._hideDatepicker(null, $.datepicker._get(inst, 'duration'));
+						break; // hide on escape
+				case 33: $.datepicker._adjustDate(e.target, (e.ctrlKey ? -1 :
+							-$.datepicker._get(inst, 'stepMonths')), (e.ctrlKey ? 'Y' : 'M'));
+						break; // previous month/year on page up/+ ctrl
+				case 34: $.datepicker._adjustDate(e.target, (e.ctrlKey ? +1 :
+							+$.datepicker._get(inst, 'stepMonths')), (e.ctrlKey ? 'Y' : 'M'));
+						break; // next month/year on page down/+ ctrl
+				case 35: if (e.ctrlKey) $.datepicker._clearDate(e.target);
+						break; // clear on ctrl+end
+				case 36: if (e.ctrlKey) $.datepicker._gotoToday(e.target);
+						break; // current on ctrl+home
+				case 37: if (e.ctrlKey) $.datepicker._adjustDate(e.target, -1, 'D');
+						break; // -1 day on ctrl+left
+				case 38: if (e.ctrlKey) $.datepicker._adjustDate(e.target, -7, 'D');
+						break; // -1 week on ctrl+up
+				case 39: if (e.ctrlKey) $.datepicker._adjustDate(e.target, +1, 'D');
+						break; // +1 day on ctrl+right
+				case 40: if (e.ctrlKey) $.datepicker._adjustDate(e.target, +7, 'D');
+						break; // +1 week on ctrl+down
+				default: handled = false;
+			}
+		else if (e.keyCode == 36 && e.ctrlKey) // display the date picker on ctrl+home
+			$.datepicker._showDatepicker(this);
+		else
+			handled = false;
+		if (handled) {
+			e.preventDefault();
+			e.stopPropagation();
+		}
+	},
+
+	/* Filter entered characters - based on date format. */
+	_doKeyPress: function(e) {
+		var inst = $.data(e.target, PROP_NAME);
+		var chars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat'));
+		var chr = String.fromCharCode(e.charCode == undefined ? e.keyCode : e.charCode);
+		return e.ctrlKey || (chr < ' ' || !chars || chars.indexOf(chr) > -1);
+	},
+
+	/* Pop-up the date picker for a given input field.
+	   @param  input  element - the input field attached to the date picker or
+	                  event - if triggered by focus */
+	_showDatepicker: function(input) {
+		input = input.target || input;
+		if (input.nodeName.toLowerCase() != 'input') // find from button/image trigger
+			input = $('input', input.parentNode)[0];
+		if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput == input) // already here
+			return;
+		var inst = $.data(input, PROP_NAME);
+		var beforeShow = $.datepicker._get(inst, 'beforeShow');
+		extendRemove(inst.settings, (beforeShow ? beforeShow.apply(input, [input, inst]) : {}));
+		$.datepicker._hideDatepicker(null, '');
+		$.datepicker._lastInput = input;
+		$.datepicker._setDateFromField(inst);
+		if ($.datepicker._inDialog) // hide cursor
+			input.value = '';
+		if (!$.datepicker._pos) { // position below input
+			$.datepicker._pos = $.datepicker._findPos(input);
+			$.datepicker._pos[1] += input.offsetHeight; // add the height
+		}
+		var isFixed = false;
+		$(input).parents().each(function() {
+			isFixed |= $(this).css('position') == 'fixed';
+			return !isFixed;
+		});
+		if (isFixed && $.browser.opera) { // correction for Opera when fixed and scrolled
+			$.datepicker._pos[0] -= document.documentElement.scrollLeft;
+			$.datepicker._pos[1] -= document.documentElement.scrollTop;
+		}
+		var offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
+		$.datepicker._pos = null;
+		inst.rangeStart = null;
+		// determine sizing offscreen
+		inst.dpDiv.css({position: 'absolute', display: 'block', top: '-1000px'});
+		$.datepicker._updateDatepicker(inst);
+		// fix width for dynamic number of date pickers
+		inst.dpDiv.width($.datepicker._getNumberOfMonths(inst)[1] *
+			$('.ui-datepicker', inst.dpDiv[0])[0].offsetWidth);
+		// and adjust position before showing
+		offset = $.datepicker._checkOffset(inst, offset, isFixed);
+		inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
+			'static' : (isFixed ? 'fixed' : 'absolute')), display: 'none',
+			left: offset.left + 'px', top: offset.top + 'px'});
+		if (!inst.inline) {
+			var showAnim = $.datepicker._get(inst, 'showAnim') || 'show';
+			var duration = $.datepicker._get(inst, 'duration');
+			var postProcess = function() {
+				$.datepicker._datepickerShowing = true;
+				if ($.browser.msie && parseInt($.browser.version) < 7) // fix IE < 7 select problems
+					$('iframe.ui-datepicker-cover').css({width: inst.dpDiv.width() + 4,
+						height: inst.dpDiv.height() + 4});
+			};
+			if ($.effects && $.effects[showAnim])
+				inst.dpDiv.show(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
+			else
+				inst.dpDiv[showAnim](duration, postProcess);
+			if (duration == '')
+				postProcess();
+			if (inst.input[0].type != 'hidden')
+				inst.input[0].focus();
+			$.datepicker._curInst = inst;
+		}
+	},
+
+	/* Generate the date picker content. */
+	_updateDatepicker: function(inst) {
+		var dims = {width: inst.dpDiv.width() + 4,
+			height: inst.dpDiv.height() + 4};
+		inst.dpDiv.empty().append(this._generateDatepicker(inst)).
+			find('iframe.ui-datepicker-cover').
+			css({width: dims.width, height: dims.height});
+		var numMonths = this._getNumberOfMonths(inst);
+		inst.dpDiv[(numMonths[0] != 1 || numMonths[1] != 1 ? 'add' : 'remove') +
+			'Class']('ui-datepicker-multi');
+		inst.dpDiv[(this._get(inst, 'isRTL') ? 'add' : 'remove') +
+			'Class']('ui-datepicker-rtl');
+		if (inst.input && inst.input[0].type != 'hidden')
+			$(inst.input[0]).focus();
+	},
+
+	/* Check positioning to remain on screen. */
+	_checkOffset: function(inst, offset, isFixed) {
+		var pos = inst.input ? this._findPos(inst.input[0]) : null;
+		var browserWidth = window.innerWidth || document.documentElement.clientWidth;
+		var browserHeight = window.innerHeight || document.documentElement.clientHeight;
+		var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
+		var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
+		// reposition date picker horizontally if outside the browser window
+		if (this._get(inst, 'isRTL') || (offset.left + inst.dpDiv.width() - scrollX) > browserWidth)
+			offset.left = Math.max((isFixed ? 0 : scrollX),
+				pos[0] + (inst.input ? inst.input.width() : 0) - (isFixed ? scrollX : 0) - inst.dpDiv.width() -
+				(isFixed && $.browser.opera ? document.documentElement.scrollLeft : 0));
+		else
+			offset.left -= (isFixed ? scrollX : 0);
+		// reposition date picker vertically if outside the browser window
+		if ((offset.top + inst.dpDiv.height() - scrollY) > browserHeight)
+			offset.top = Math.max((isFixed ? 0 : scrollY),
+				pos[1] - (isFixed ? scrollY : 0) - (this._inDialog ? 0 : inst.dpDiv.height()) -
+				(isFixed && $.browser.opera ? document.documentElement.scrollTop : 0));
+		else
+			offset.top -= (isFixed ? scrollY : 0);
+		return offset;
+	},
+	
+	/* Find an object's position on the screen. */
+	_findPos: function(obj) {
+        while (obj && (obj.type == 'hidden' || obj.nodeType != 1)) {
+            obj = obj.nextSibling;
+        }
+        var position = $(obj).offset();
+	    return [position.left, position.top];
+	},
+
+	/* Hide the date picker from view.
+	   @param  input  element - the input field attached to the date picker
+	   @param  duration  string - the duration over which to close the date picker */
+	_hideDatepicker: function(input, duration) {
+		var inst = this._curInst;
+		if (!inst)
+			return;
+		var rangeSelect = this._get(inst, 'rangeSelect');
+		if (rangeSelect && this._stayOpen)
+			this._selectDate('#' + inst.id, this._formatDate(inst,
+				inst.currentDay, inst.currentMonth, inst.currentYear));
+		this._stayOpen = false;
+		if (this._datepickerShowing) {
+			duration = (duration != null ? duration : this._get(inst, 'duration'));
+			var showAnim = this._get(inst, 'showAnim');
+			var postProcess = function() {
+				$.datepicker._tidyDialog(inst);
+			};
+			if (duration != '' && $.effects && $.effects[showAnim])
+				inst.dpDiv.hide(showAnim, $.datepicker._get(inst, 'showOptions'),
+					duration, postProcess);
+			else
+				inst.dpDiv[(duration == '' ? 'hide' : (showAnim == 'slideDown' ? 'slideUp' :
+					(showAnim == 'fadeIn' ? 'fadeOut' : 'hide')))](duration, postProcess);
+			if (duration == '')
+				this._tidyDialog(inst);
+			var onClose = this._get(inst, 'onClose');
+			if (onClose)
+				onClose.apply((inst.input ? inst.input[0] : null),
+					[this._getDate(inst), inst]);  // trigger custom callback
+			this._datepickerShowing = false;
+			this._lastInput = null;
+			inst.settings.prompt = null;
+			if (this._inDialog) {
+				this._dialogInput.css({ position: 'absolute', left: '0', top: '-100px' });
+				if ($.blockUI) {
+					$.unblockUI();
+					$('body').append(this.dpDiv);
+				}
+			}
+			this._inDialog = false;
+		}
+		this._curInst = null;
+	},
+
+	/* Tidy up after a dialog display. */
+	_tidyDialog: function(inst) {
+		inst.dpDiv.removeClass(this._dialogClass).unbind('.ui-datepicker');
+		$('.' + this._promptClass, inst.dpDiv).remove();
+	},
+
+	/* Close date picker if clicked elsewhere. */
+	_checkExternalClick: function(event) {
+		if (!$.datepicker._curInst)
+			return;
+		var $target = $(event.target);
+		if (($target.parents('#' + $.datepicker._mainDivId).length == 0) &&
+				!$target.hasClass($.datepicker.markerClassName) &&
+				!$target.hasClass($.datepicker._triggerClass) &&
+				$.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI))
+			$.datepicker._hideDatepicker(null, '');
+	},
+
+	/* Adjust one of the date sub-fields. */
+	_adjustDate: function(id, offset, period) {
+		var target = $(id);
+		var inst = $.data(target[0], PROP_NAME);
+		this._adjustInstDate(inst, offset, period);
+		this._updateDatepicker(inst);
+	},
+
+	/* Action for current link. */
+	_gotoToday: function(id) {
+		var target = $(id);
+		var inst = $.data(target[0], PROP_NAME);
+		if (this._get(inst, 'gotoCurrent') && inst.currentDay) {
+			inst.selectedDay = inst.currentDay;
+			inst.drawMonth = inst.selectedMonth = inst.currentMonth;
+			inst.drawYear = inst.selectedYear = inst.currentYear;
+		}
+		else {
+		var date = new Date();
+		inst.selectedDay = date.getDate();
+		inst.drawMonth = inst.selectedMonth = date.getMonth();
+		inst.drawYear = inst.selectedYear = date.getFullYear();
+		}
+		this._adjustDate(target);
+		this._notifyChange(inst);
+	},
+
+	/* Action for selecting a new month/year. */
+	_selectMonthYear: function(id, select, period) {
+		var target = $(id);
+		var inst = $.data(target[0], PROP_NAME);
+		inst._selectingMonthYear = false;
+		inst[period == 'M' ? 'drawMonth' : 'drawYear'] =
+			select.options[select.selectedIndex].value - 0;
+		this._adjustDate(target);
+		this._notifyChange(inst);
+	},
+
+	/* Restore input focus after not changing month/year. */
+	_clickMonthYear: function(id) {
+		var target = $(id);
+		var inst = $.data(target[0], PROP_NAME);
+		if (inst.input && inst._selectingMonthYear && !$.browser.msie)
+			inst.input[0].focus();
+		inst._selectingMonthYear = !inst._selectingMonthYear;
+	},
+
+	/* Action for changing the first week day. */
+	_changeFirstDay: function(id, day) {
+		var target = $(id);
+		var inst = $.data(target[0], PROP_NAME);
+		inst.settings.firstDay = day;
+		this._updateDatepicker(inst);
+	},
+
+	/* Action for selecting a day. */
+	_selectDay: function(id, month, year, td) {
+		if ($(td).hasClass(this._unselectableClass))
+			return;
+		var target = $(id);
+		var inst = $.data(target[0], PROP_NAME);
+		var rangeSelect = this._get(inst, 'rangeSelect');
+		if (rangeSelect) {
+			this._stayOpen = !this._stayOpen;
+			if (this._stayOpen) {
+				$('.ui-datepicker td').removeClass(this._currentClass);
+				$(td).addClass(this._currentClass);
+			} 
+		}
+		inst.selectedDay = inst.currentDay = $('a', td).html();
+		inst.selectedMonth = inst.currentMonth = month;
+		inst.selectedYear = inst.currentYear = year;
+		if (this._stayOpen) {
+			inst.endDay = inst.endMonth = inst.endYear = null;
+		}
+		else if (rangeSelect) {
+			inst.endDay = inst.currentDay;
+			inst.endMonth = inst.currentMonth;
+			inst.endYear = inst.currentYear;
+		}
+		this._selectDate(id, this._formatDate(inst,
+			inst.currentDay, inst.currentMonth, inst.currentYear));
+		if (this._stayOpen) {
+			inst.rangeStart = new Date(inst.currentYear, inst.currentMonth, inst.currentDay);
+			this._updateDatepicker(inst);
+		}
+		else if (rangeSelect) {
+			inst.selectedDay = inst.currentDay = inst.rangeStart.getDate();
+			inst.selectedMonth = inst.currentMonth = inst.rangeStart.getMonth();
+			inst.selectedYear = inst.currentYear = inst.rangeStart.getFullYear();
+			inst.rangeStart = null;
+			if (inst.inline)
+				this._updateDatepicker(inst);
+		}
+	},
+
+	/* Erase the input field and hide the date picker. */
+	_clearDate: function(id) {
+		var target = $(id);
+		var inst = $.data(target[0], PROP_NAME);
+		if (this._get(inst, 'mandatory'))
+			return;
+		this._stayOpen = false;
+		inst.endDay = inst.endMonth = inst.endYear = inst.rangeStart = null;
+		this._selectDate(target, '');
+	},
+
+	/* Update the input field with the selected date. */
+	_selectDate: function(id, dateStr) {
+		var target = $(id);
+		var inst = $.data(target[0], PROP_NAME);
+		dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
+		if (this._get(inst, 'rangeSelect') && dateStr)
+			dateStr = (inst.rangeStart ? this._formatDate(inst, inst.rangeStart) :
+				dateStr) + this._get(inst, 'rangeSeparator') + dateStr;
+		if (inst.input)
+			inst.input.val(dateStr);
+		this._updateAlternate(inst);
+		var onSelect = this._get(inst, 'onSelect');
+		if (onSelect)
+			onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback
+		else if (inst.input)
+			inst.input.trigger('change'); // fire the change event
+		if (inst.inline)
+			this._updateDatepicker(inst);
+		else if (!this._stayOpen) {
+			this._hideDatepicker(null, this._get(inst, 'duration'));
+			this._lastInput = inst.input[0];
+			if (typeof(inst.input[0]) != 'object')
+				inst.input[0].focus(); // restore focus
+			this._lastInput = null;
+		}
+	},
+	
+	/* Update any alternate field to synchronise with the main field. */
+	_updateAlternate: function(inst) {
+		var altField = this._get(inst, 'altField');
+		if (altField) { // update alternate field too
+			var altFormat = this._get(inst, 'altFormat');
+			var date = this._getDate(inst);
+			dateStr = (isArray(date) ? (!date[0] && !date[1] ? '' :
+				this.formatDate(altFormat, date[0], this._getFormatConfig(inst)) +
+				this._get(inst, 'rangeSeparator') + this.formatDate(
+				altFormat, date[1] || date[0], this._getFormatConfig(inst))) :
+				this.formatDate(altFormat, date, this._getFormatConfig(inst)));
+			$(altField).each(function() { $(this).val(dateStr); });
+		}
+	},
+
+	/* Set as beforeShowDay function to prevent selection of weekends.
+	   @param  date  Date - the date to customise
+	   @return [boolean, string] - is this date selectable?, what is its CSS class? */
+	noWeekends: function(date) {
+		var day = date.getDay();
+		return [(day > 0 && day < 6), ''];
+	},
+	
+	/* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
+	   @param  date  Date - the date to get the week for
+	   @return  number - the number of the week within the year that contains this date */
+	iso8601Week: function(date) {
+		var checkDate = new Date(date.getFullYear(), date.getMonth(), date.getDate(), (date.getTimezoneOffset() / -60));
+		var firstMon = new Date(checkDate.getFullYear(), 1 - 1, 4); // First week always contains 4 Jan
+		var firstDay = firstMon.getDay() || 7; // Day of week: Mon = 1, ..., Sun = 7
+		firstMon.setDate(firstMon.getDate() + 1 - firstDay); // Preceding Monday
+		if (firstDay < 4 && checkDate < firstMon) { // Adjust first three days in year if necessary
+			checkDate.setDate(checkDate.getDate() - 3); // Generate for previous year
+			return $.datepicker.iso8601Week(checkDate);
+		} else if (checkDate > new Date(checkDate.getFullYear(), 12 - 1, 28)) { // Check last three days in year
+			firstDay = new Date(checkDate.getFullYear() + 1, 1 - 1, 4).getDay() || 7;
+			if (firstDay > 4 && (checkDate.getDay() || 7) < firstDay - 3) { // Adjust if necessary
+				checkDate.setDate(checkDate.getDate() + 3); // Generate for next year
+				return $.datepicker.iso8601Week(checkDate);
+			}
+		}
+		return Math.floor(((checkDate - firstMon) / 86400000) / 7) + 1; // Weeks to given date
+	},
+	
+	/* Provide status text for a particular date.
+	   @param  date  the date to get the status for
+	   @param  inst  the current datepicker instance
+	   @return  the status display text for this date */
+	dateStatus: function(date, inst) {
+		return $.datepicker.formatDate($.datepicker._get(inst, 'dateStatus'),
+			date, $.datepicker._getFormatConfig(inst));
+	},
+
+	/* Parse a string value into a date object.
+	   See formatDate below for the possible formats.
+
+	   @param  format    string - the expected format of the date
+	   @param  value     string - the date in the above format
+	   @param  settings  Object - attributes include:
+	                     shortYearCutoff  number - the cutoff year for determining the century (optional)
+	                     dayNamesShort    string[7] - abbreviated names of the days from Sunday (optional)
+	                     dayNames         string[7] - names of the days from Sunday (optional)
+	                     monthNamesShort  string[12] - abbreviated names of the months (optional)
+	                     monthNames       string[12] - names of the months (optional)
+	   @return  Date - the extracted date value or null if value is blank */
+	parseDate: function (format, value, settings) {
+		if (format == null || value == null)
+			throw 'Invalid arguments';
+		value = (typeof value == 'object' ? value.toString() : value + '');
+		if (value == '')
+			return null;
+		var shortYearCutoff = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff;
+		var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
+		var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
+		var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
+		var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
+		var year = -1;
+		var month = -1;
+		var day = -1;
+		var literal = false;
+		// Check whether a format character is doubled
+		var lookAhead = function(match) {
+			var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
+			if (matches)
+				iFormat++;
+			return matches;	
+		};
+		// Extract a number from the string value
+		var getNumber = function(match) {
+			lookAhead(match);
+			var origSize = (match == '@' ? 14 : (match == 'y' ? 4 : 2));
+			var size = origSize;
+			var num = 0;
+			while (size > 0 && iValue < value.length &&
+					value.charAt(iValue) >= '0' && value.charAt(iValue) <= '9') {
+				num = num * 10 + (value.charAt(iValue++) - 0);
+				size--;
+			}
+			if (size == origSize)
+				throw 'Missing number at position ' + iValue;
+			return num;
+		};
+		// Extract a name from the string value and convert to an index
+		var getName = function(match, shortNames, longNames) {
+			var names = (lookAhead(match) ? longNames : shortNames);
+			var size = 0;
+			for (var j = 0; j < names.length; j++)
+				size = Math.max(size, names[j].length);
+			var name = '';
+			var iInit = iValue;
+			while (size > 0 && iValue < value.length) {
+				name += value.charAt(iValue++);
+				for (var i = 0; i < names.length; i++)
+					if (name == names[i])
+						return i + 1;
+				size--;
+			}
+			throw 'Unknown name at position ' + iInit;
+		};
+		// Confirm that a literal character matches the string value
+		var checkLiteral = function() {
+			if (value.charAt(iValue) != format.charAt(iFormat))
+				throw 'Unexpected literal at position ' + iValue;
+			iValue++;
+		};
+		var iValue = 0;
+		for (var iFormat = 0; iFormat < format.length; iFormat++) {
+			if (literal)
+				if (format.charAt(iFormat) == "'" && !lookAhead("'"))
+					literal = false;
+				else
+					checkLiteral();
+			else
+				switch (format.charAt(iFormat)) {
+					case 'd':
+						day = getNumber('d');
+						break;
+					case 'D': 
+						getName('D', dayNamesShort, dayNames);
+						break;
+					case 'm': 
+						month = getNumber('m');
+						break;
+					case 'M':
+						month = getName('M', monthNamesShort, monthNames); 
+						break;
+					case 'y':
+						year = getNumber('y');
+						break;
+					case '@':
+						var date = new Date(getNumber('@'));
+						year = date.getFullYear();
+						month = date.getMonth() + 1;
+						day = date.getDate();
+						break;
+					case "'":
+						if (lookAhead("'"))
+							checkLiteral();
+						else
+							literal = true;
+						break;
+					default:
+						checkLiteral();
+				}
+		}
+		if (year < 100)
+			year += new Date().getFullYear() - new Date().getFullYear() % 100 +
+				(year <= shortYearCutoff ? 0 : -100);
+		var date = new Date(year, month - 1, day);
+		if (date.getFullYear() != year || date.getMonth() + 1 != month || date.getDate() != day)
+			throw 'Invalid date'; // E.g. 31/02/*
+		return date;
+	},
+
+	/* Standard date formats. */
+	ATOM: 'yy-mm-dd', // RFC 3339 (ISO 8601)
+	COOKIE: 'D, dd M yy',
+	ISO_8601: 'yy-mm-dd',
+	RFC_822: 'D, d M y',
+	RFC_850: 'DD, dd-M-y',
+	RFC_1036: 'D, d M y',
+	RFC_1123: 'D, d M yy',
+	RFC_2822: 'D, d M yy',
+	RSS: 'D, d M y', // RFC 822
+	TIMESTAMP: '@',
+	W3C: 'yy-mm-dd', // ISO 8601
+
+	/* Format a date object into a string value.
+	   The format can be combinations of the following:
+	   d  - day of month (no leading zero)
+	   dd - day of month (two digit)
+	   D  - day name short
+	   DD - day name long
+	   m  - month of year (no leading zero)
+	   mm - month of year (two digit)
+	   M  - month name short
+	   MM - month name long
+	   y  - year (two digit)
+	   yy - year (four digit)
+	   @ - Unix timestamp (ms since 01/01/1970)
+	   '...' - literal text
+	   '' - single quote
+
+	   @param  format    string - the desired format of the date
+	   @param  date      Date - the date value to format
+	   @param  settings  Object - attributes include:
+	                     dayNamesShort    string[7] - abbreviated names of the days from Sunday (optional)
+	                     dayNames         string[7] - names of the days from Sunday (optional)
+	                     monthNamesShort  string[12] - abbreviated names of the months (optional)
+	                     monthNames       string[12] - names of the months (optional)
+	   @return  string - the date in the above format */
+	formatDate: function (format, date, settings) {
+		if (!date)
+			return '';
+		var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
+		var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
+		var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
+		var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
+		// Check whether a format character is doubled
+		var lookAhead = function(match) {
+			var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
+			if (matches)
+				iFormat++;
+			return matches;	
+		};
+		// Format a number, with leading zero if necessary
+		var formatNumber = function(match, value) {
+			return (lookAhead(match) && value < 10 ? '0' : '') + value;
+		};
+		// Format a name, short or long as requested
+		var formatName = function(match, value, shortNames, longNames) {
+			return (lookAhead(match) ? longNames[value] : shortNames[value]);
+		};
+		var output = '';
+		var literal = false;
+		if (date)
+			for (var iFormat = 0; iFormat < format.length; iFormat++) {
+				if (literal)
+					if (format.charAt(iFormat) == "'" && !lookAhead("'"))
+						literal = false;
+					else
+						output += format.charAt(iFormat);
+				else
+					switch (format.charAt(iFormat)) {
+						case 'd':
+							output += formatNumber('d', date.getDate()); 
+							break;
+						case 'D': 
+							output += formatName('D', date.getDay(), dayNamesShort, dayNames);
+							break;
+						case 'm': 
+							output += formatNumber('m', date.getMonth() + 1); 
+							break;
+						case 'M':
+							output += formatName('M', date.getMonth(), monthNamesShort, monthNames); 
+							break;
+						case 'y':
+							output += (lookAhead('y') ? date.getFullYear() : 
+								(date.getYear() % 100 < 10 ? '0' : '') + date.getYear() % 100);
+							break;
+						case '@':
+							output += date.getTime(); 
+							break;
+						case "'":
+							if (lookAhead("'"))
+								output += "'";
+							else
+								literal = true;
+							break;
+						default:
+							output += format.charAt(iFormat);
+					}
+			}
+		return output;
+	},
+
+	/* Extract all possible characters from the date format. */
+	_possibleChars: function (format) {
+		var chars = '';
+		var literal = false;
+		for (var iFormat = 0; iFormat < format.length; iFormat++)
+			if (literal)
+				if (format.charAt(iFormat) == "'" && !lookAhead("'"))
+					literal = false;
+				else
+					chars += format.charAt(iFormat);
+			else
+				switch (format.charAt(iFormat)) {
+					case 'd': case 'm': case 'y': case '@':
+						chars += '0123456789'; 
+						break;
+					case 'D': case 'M':
+						return null; // Accept anything
+					case "'":
+						if (lookAhead("'"))
+							chars += "'";
+						else
+							literal = true;
+						break;
+					default:
+						chars += format.charAt(iFormat);
+				}
+		return chars;
+	},
+
+	/* Get a setting value, defaulting if necessary. */
+	_get: function(inst, name) {
+		return inst.settings[name] !== undefined ?
+			inst.settings[name] : this._defaults[name];
+	},
+
+	/* Parse existing date and initialise date picker. */
+	_setDateFromField: function(inst) {
+		var dateFormat = this._get(inst, 'dateFormat');
+		var dates = inst.input ? inst.input.val().split(this._get(inst, 'rangeSeparator')) : null; 
+		inst.endDay = inst.endMonth = inst.endYear = null;
+		var date = defaultDate = this._getDefaultDate(inst);
+		if (dates.length > 0) {
+			var settings = this._getFormatConfig(inst);
+			if (dates.length > 1) {
+				date = this.parseDate(dateFormat, dates[1], settings) || defaultDate;
+				inst.endDay = date.getDate();
+				inst.endMonth = date.getMonth();
+				inst.endYear = date.getFullYear();
+			}
+			try {
+				date = this.parseDate(dateFormat, dates[0], settings) || defaultDate;
+			} catch (e) {
+				this.log(e);
+				date = defaultDate;
+			}
+		}
+		inst.selectedDay = date.getDate();
+		inst.drawMonth = inst.selectedMonth = date.getMonth();
+		inst.drawYear = inst.selectedYear = date.getFullYear();
+		inst.currentDay = (dates[0] ? date.getDate() : 0);
+		inst.currentMonth = (dates[0] ? date.getMonth() : 0);
+		inst.currentYear = (dates[0] ? date.getFullYear() : 0);
+		this._adjustInstDate(inst);
+	},
+	
+	/* Retrieve the default date shown on opening. */
+	_getDefaultDate: function(inst) {
+		var date = this._determineDate(this._get(inst, 'defaultDate'), new Date());
+		var minDate = this._getMinMaxDate(inst, 'min', true);
+		var maxDate = this._getMinMaxDate(inst, 'max');
+		date = (minDate && date < minDate ? minDate : date);
+		date = (maxDate && date > maxDate ? maxDate : date);
+		return date;
+	},
+
+	/* A date may be specified as an exact value or a relative one. */
+	_determineDate: function(date, defaultDate) {
+		var offsetNumeric = function(offset) {
+			var date = new Date();
+			date.setUTCDate(date.getUTCDate() + offset);
+			return date;
+		};
+		var offsetString = function(offset, getDaysInMonth) {
+			var date = new Date();
+			var year = date.getFullYear();
+			var month = date.getMonth();
+			var day = date.getDate();
+			var pattern = /([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g;
+			var matches = pattern.exec(offset);
+			while (matches) {
+				switch (matches[2] || 'd') {
+					case 'd' : case 'D' :
+						day += (matches[1] - 0); break;
+					case 'w' : case 'W' :
+						day += (matches[1] * 7); break;
+					case 'm' : case 'M' :
+						month += (matches[1] - 0); 
+						day = Math.min(day, getDaysInMonth(year, month));
+						break;
+					case 'y': case 'Y' :
+						year += (matches[1] - 0);
+						day = Math.min(day, getDaysInMonth(year, month));
+						break;
+				}
+				matches = pattern.exec(offset);
+			}
+			return new Date(year, month, day);
+		};
+		return (date == null ? defaultDate :
+			(typeof date == 'string' ? offsetString(date, this._getDaysInMonth) :
+			(typeof date == 'number' ? offsetNumeric(date) : date)));
+	},
+
+	/* Set the date(s) directly. */
+	_setDate: function(inst, date, endDate) {
+		var clear = !(date);
+		date = this._determineDate(date, new Date());
+		inst.selectedDay = inst.currentDay = date.getDate();
+		inst.drawMonth = inst.selectedMonth = inst.currentMonth = date.getMonth();
+		inst.drawYear = inst.selectedYear = inst.currentYear = date.getFullYear();
+		if (this._get(inst, 'rangeSelect')) {
+			if (endDate) {
+				endDate = this._determineDate(endDate, null);
+				inst.endDay = endDate.getDate();
+				inst.endMonth = endDate.getMonth();
+				inst.endYear = endDate.getFullYear();
+			} else {
+				inst.endDay = inst.currentDay;
+				inst.endMonth = inst.currentMonth;
+				inst.endYear = inst.currentYear;
+			}
+		}
+		this._adjustInstDate(inst);
+		if (inst.input)
+			inst.input.val(clear ? '' : this._formatDate(inst) +
+				(!this._get(inst, 'rangeSelect') ? '' : this._get(inst, 'rangeSeparator') +
+				this._formatDate(inst, inst.endDay, inst.endMonth, inst.endYear)));
+	},
+
+	/* Retrieve the date(s) directly. */
+	_getDate: function(inst) {
+		var startDate = (!inst.currentYear || (inst.input && inst.input.val() == '') ? null :
+			new Date(inst.currentYear, inst.currentMonth, inst.currentDay));
+		if (this._get(inst, 'rangeSelect')) {
+			return [inst.rangeStart || startDate, (!inst.endYear ? null :
+				new Date(inst.endYear, inst.endMonth, inst.endDay))];
+		} else
+			return startDate;
+	},
+
+	/* Generate the HTML for the current state of the date picker. */
+	_generateDatepicker: function(inst) {
+		var today = new Date();
+		today = new Date(today.getFullYear(), today.getMonth(), today.getDate()); // clear time
+		var showStatus = this._get(inst, 'showStatus');
+		var isRTL = this._get(inst, 'isRTL');
+		// build the date picker HTML
+		var clear = (this._get(inst, 'mandatory') ? '' :
+			'<div class="ui-datepicker-clear"><a onclick="jQuery.datepicker._clearDate(\'#' + inst.id + '\');"' +
+			(showStatus ? this._addStatus(inst, this._get(inst, 'clearStatus') || '&#xa0;') : '') + '>' +
+			this._get(inst, 'clearText') + '</a></div>');
+		var controls = '<div class="ui-datepicker-control">' + (isRTL ? '' : clear) +
+			'<div class="ui-datepicker-close"><a onclick="jQuery.datepicker._hideDatepicker();"' +
+			(showStatus ? this._addStatus(inst, this._get(inst, 'closeStatus') || '&#xa0;') : '') + '>' +
+			this._get(inst, 'closeText') + '</a></div>' + (isRTL ? clear : '')  + '</div>';
+		var prompt = this._get(inst, 'prompt');
+		var closeAtTop = this._get(inst, 'closeAtTop');
+		var hideIfNoPrevNext = this._get(inst, 'hideIfNoPrevNext');
+		var navigationAsDateFormat = this._get(inst, 'navigationAsDateFormat');
+		var numMonths = this._getNumberOfMonths(inst);
+		var stepMonths = this._get(inst, 'stepMonths');
+		var isMultiMonth = (numMonths[0] != 1 || numMonths[1] != 1);
+		var currentDate = (!inst.currentDay ? new Date(9999, 9, 9) :
+			new Date(inst.currentYear, inst.currentMonth, inst.currentDay));
+		var minDate = this._getMinMaxDate(inst, 'min', true);
+		var maxDate = this._getMinMaxDate(inst, 'max');
+		var drawMonth = inst.drawMonth;
+		var drawYear = inst.drawYear;
+		if (maxDate) {
+			var maxDraw = new Date(maxDate.getFullYear(),
+				maxDate.getMonth() - numMonths[1] + 1, maxDate.getDate());
+			maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
+			while (new Date(drawYear, drawMonth, 1) > maxDraw) {
+				drawMonth--;
+				if (drawMonth < 0) {
+					drawMonth = 11;
+					drawYear--;
+				}
+			}
+		}
+		// controls and links
+		var prevText = this._get(inst, 'prevText');
+		prevText = (!navigationAsDateFormat ? prevText : this.formatDate(
+			prevText, new Date(drawYear, drawMonth - stepMonths, 1), this._getFormatConfig(inst)));
+		var prev = '<div class="ui-datepicker-prev">' + (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ? 
+			'<a onclick="jQuery.datepicker._adjustDate(\'#' + inst.id + '\', -' + stepMonths + ', \'M\');"' +
+			(showStatus ? this._addStatus(inst, this._get(inst, 'prevStatus') || '&#xa0;') : '') + '>' + prevText + '</a>' :
+			(hideIfNoPrevNext ? '' : '<label>' + prevText + '</label>')) + '</div>';
+		var nextText = this._get(inst, 'nextText');
+		nextText = (!navigationAsDateFormat ? nextText : this.formatDate(
+			nextText, new Date(drawYear, drawMonth + stepMonths, 1), this._getFormatConfig(inst)));
+		var next = '<div class="ui-datepicker-next">' + (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
+			'<a onclick="jQuery.datepicker._adjustDate(\'#' + inst.id + '\', +' + stepMonths + ', \'M\');"' +
+			(showStatus ? this._addStatus(inst, this._get(inst, 'nextStatus') || '&#xa0;') : '') + '>' + nextText + '</a>' :
+			(hideIfNoPrevNext ? '' : '<label>' + nextText + '</label>')) + '</div>';
+		var currentText = this._get(inst, 'currentText');
+		currentText = (!navigationAsDateFormat ? currentText: this.formatDate(
+			currentText, today, this._getFormatConfig(inst)));
+		var html = (prompt ? '<div class="' + this._promptClass + '">' + prompt + '</div>' : '') +
+			(closeAtTop && !inst.inline ? controls : '') +
+			'<div class="ui-datepicker-links">' + (isRTL ? next : prev) +
+			(this._isInRange(inst, (this._get(inst, 'gotoCurrent') && inst.currentDay ?
+			currentDate : today)) ? '<div class="ui-datepicker-current">' +
+			'<a onclick="jQuery.datepicker._gotoToday(\'#' + inst.id + '\');"' +
+			(showStatus ? this._addStatus(inst, this._get(inst, 'currentStatus') || '&#xa0;') : '') + '>' +
+			currentText + '</a></div>' : '') + (isRTL ? prev : next) + '</div>';
+		var firstDay = this._get(inst, 'firstDay');
+		var changeFirstDay = this._get(inst, 'changeFirstDay');
+		var dayNames = this._get(inst, 'dayNames');
+		var dayNamesShort = this._get(inst, 'dayNamesShort');
+		var dayNamesMin = this._get(inst, 'dayNamesMin');
+		var monthNames = this._get(inst, 'monthNames');
+		var beforeShowDay = this._get(inst, 'beforeShowDay');
+		var highlightWeek = this._get(inst, 'highlightWeek');
+		var showOtherMonths = this._get(inst, 'showOtherMonths');
+		var showWeeks = this._get(inst, 'showWeeks');
+		var calculateWeek = this._get(inst, 'calculateWeek') || this.iso8601Week;
+		var status = (showStatus ? this._get(inst, 'dayStatus') || '&#xa0;' : '');
+		var dateStatus = this._get(inst, 'statusForDate') || this.dateStatus;
+		var endDate = inst.endDay ? new Date(inst.endYear, inst.endMonth, inst.endDay) : currentDate;
+		for (var row = 0; row < numMonths[0]; row++)
+			for (var col = 0; col < numMonths[1]; col++) {
+				var selectedDate = new Date(drawYear, drawMonth, inst.selectedDay);
+				html += '<div class="ui-datepicker-one-month' + (col == 0 ? ' ui-datepicker-new-row' : '') + '">' +
+					this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
+					selectedDate, row > 0 || col > 0, showStatus, monthNames) + // draw month headers
+					'<table class="ui-datepicker" cellpadding="0" cellspacing="0"><thead>' + 
+					'<tr class="ui-datepicker-title-row">' +
+					(showWeeks ? '<td>' + this._get(inst, 'weekHeader') + '</td>' : '');
+				for (var dow = 0; dow < 7; dow++) { // days of the week
+					var day = (dow + firstDay) % 7;
+					var dayStatus = (status.indexOf('DD') > -1 ? status.replace(/DD/, dayNames[day]) :
+						status.replace(/D/, dayNamesShort[day]));
+					html += '<td' + ((dow + firstDay + 6) % 7 >= 5 ? ' class="ui-datepicker-week-end-cell"' : '') + '>' +
+						(!changeFirstDay ? '<span' :
+						'<a onclick="jQuery.datepicker._changeFirstDay(\'#' + inst.id + '\', ' + day + ');"') + 
+						(showStatus ? this._addStatus(inst, dayStatus) : '') + ' title="' + dayNames[day] + '">' +
+						dayNamesMin[day] + (changeFirstDay ? '</a>' : '</span>') + '</td>';
+				}
+				html += '</tr></thead><tbody>';
+				var daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
+				if (drawYear == inst.selectedYear && drawMonth == inst.selectedMonth)
+					inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
+				var leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
+				var printDate = new Date(drawYear, drawMonth, 1 - leadDays);
+				var numRows = (isMultiMonth ? 6 : Math.ceil((leadDays + daysInMonth) / 7)); // calculate the number of rows to generate
+				for (var dRow = 0; dRow < numRows; dRow++) { // create date picker rows
+					html += '<tr class="ui-datepicker-days-row">' +
+						(showWeeks ? '<td class="ui-datepicker-week-col">' + calculateWeek(printDate) + '</td>' : '');
+					for (var dow = 0; dow < 7; dow++) { // create date picker days
+						var daySettings = (beforeShowDay ?
+							beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, '']);
+						var otherMonth = (printDate.getMonth() != drawMonth);
+						var unselectable = otherMonth || !daySettings[0] ||
+							(minDate && printDate < minDate) || (maxDate && printDate > maxDate);
+						html += '<td class="ui-datepicker-days-cell' +
+							((dow + firstDay + 6) % 7 >= 5 ? ' ui-datepicker-week-end-cell' : '') + // highlight weekends
+							(otherMonth ? ' ui-datepicker-otherMonth' : '') + // highlight days from other months
+							(printDate.getTime() == selectedDate.getTime() && drawMonth == inst.selectedMonth ?
+							' ui-datepicker-days-cell-over' : '') + // highlight selected day
+							(unselectable ? ' ' + this._unselectableClass : '') +  // highlight unselectable days
+							(otherMonth && !showOtherMonths ? '' : ' ' + daySettings[1] + // highlight custom dates
+							(printDate.getTime() >= currentDate.getTime() && printDate.getTime() <= endDate.getTime() ?  // in current range
+							' ' + this._currentClass : '') + // highlight selected day
+							(printDate.getTime() == today.getTime() ? ' ui-datepicker-today' : '')) + '"' + // highlight today (if different)
+							((!otherMonth || showOtherMonths) && daySettings[2] ? ' title="' + daySettings[2] + '"' : '') + // cell title
+							(unselectable ? (highlightWeek ? ' onmouseover="jQuery(this).parent().addClass(\'ui-datepicker-week-over\');"' + // highlight selection week
+							' onmouseout="jQuery(this).parent().removeClass(\'ui-datepicker-week-over\');"' : '') : // unhighlight selection week
+							' onmouseover="jQuery(this).addClass(\'ui-datepicker-days-cell-over\')' + // highlight selection
+							(highlightWeek ? '.parent().addClass(\'ui-datepicker-week-over\')' : '') + ';' + // highlight selection week
+							(!showStatus || (otherMonth && !showOtherMonths) ? '' : 'jQuery(\'#ui-datepicker-status-' +
+							inst.id + '\').html(\'' + (dateStatus.apply((inst.input ? inst.input[0] : null),
+							[printDate, inst]) || '&#xa0;') +'\');') + '"' +
+							' onmouseout="jQuery(this).removeClass(\'ui-datepicker-days-cell-over\')' + // unhighlight selection
+							(highlightWeek ? '.parent().removeClass(\'ui-datepicker-week-over\')' : '') + ';' + // unhighlight selection week
+							(!showStatus || (otherMonth && !showOtherMonths) ? '' : 'jQuery(\'#ui-datepicker-status-' +
+							inst.id + '\').html(\'&#xa0;\');') + '" onclick="jQuery.datepicker._selectDay(\'#' +
+							inst.id + '\',' + drawMonth + ',' + drawYear + ', this);"') + '>' + // actions
+							(otherMonth ? (showOtherMonths ? printDate.getDate() : '&#xa0;') : // display for other months
+							(unselectable ? printDate.getDate() : '<a>' + printDate.getDate() + '</a>')) + '</td>'; // display for this month
+						printDate.setUTCDate(printDate.getUTCDate() + 1);
+					}
+					html += '</tr>';
+				}
+				drawMonth++;
+				if (drawMonth > 11) {
+					drawMonth = 0;
+					drawYear++;
+				}
+				html += '</tbody></table></div>';
+			}
+		html += (showStatus ? '<div style="clear: both;"></div><div id="ui-datepicker-status-' + inst.id + 
+			'" class="ui-datepicker-status">' + (this._get(inst, 'initStatus') || '&#xa0;') + '</div>' : '') +
+			(!closeAtTop && !inst.inline ? controls : '') +
+			'<div style="clear: both;"></div>' + 
+			($.browser.msie && parseInt($.browser.version) < 7 && !inst.inline ? 
+			'<iframe src="javascript:false;" class="ui-datepicker-cover"></iframe>' : '');
+		return html;
+	},
+	
+	/* Generate the month and year header. */
+	_generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
+			selectedDate, secondary, showStatus, monthNames) {
+		minDate = (inst.rangeStart && minDate && selectedDate < minDate ? selectedDate : minDate);
+		var html = '<div class="ui-datepicker-header">';
+		// month selection
+		if (secondary || !this._get(inst, 'changeMonth'))
+			html += monthNames[drawMonth] + '&#xa0;';
+		else {
+			var inMinYear = (minDate && minDate.getFullYear() == drawYear);
+			var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear);
+			html += '<select class="ui-datepicker-new-month" ' +
+				'onchange="jQuery.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'M\');" ' +
+				'onclick="jQuery.datepicker._clickMonthYear(\'#' + inst.id + '\');"' +
+				(showStatus ? this._addStatus(inst, this._get(inst, 'monthStatus') || '&#xa0;') : '') + '>';
+			for (var month = 0; month < 12; month++) {
+				if ((!inMinYear || month >= minDate.getMonth()) &&
+						(!inMaxYear || month <= maxDate.getMonth()))
+					html += '<option value="' + month + '"' +
+						(month == drawMonth ? ' selected="selected"' : '') +
+						'>' + monthNames[month] + '</option>';
+			}
+			html += '</select>';
+		}
+		// year selection
+		if (secondary || !this._get(inst, 'changeYear'))
+			html += drawYear;
+		else {
+			// determine range of years to display
+			var years = this._get(inst, 'yearRange').split(':');
+			var year = 0;
+			var endYear = 0;
+			if (years.length != 2) {
+				year = drawYear - 10;
+				endYear = drawYear + 10;
+			} else if (years[0].charAt(0) == '+' || years[0].charAt(0) == '-') {
+				year = endYear = new Date().getFullYear();
+				year += parseInt(years[0], 10);
+				endYear += parseInt(years[1], 10);
+			} else {
+				year = parseInt(years[0], 10);
+				endYear = parseInt(years[1], 10);
+			}
+			year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
+			endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
+			html += '<select class="ui-datepicker-new-year" ' +
+				'onchange="jQuery.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'Y\');" ' +
+				'onclick="jQuery.datepicker._clickMonthYear(\'#' + inst.id + '\');"' +
+				(showStatus ? this._addStatus(inst, this._get(inst, 'yearStatus') || '&#xa0;') : '') + '>';
+			for (; year <= endYear; year++) {
+				html += '<option value="' + year + '"' +
+					(year == drawYear ? ' selected="selected"' : '') +
+					'>' + year + '</option>';
+			}
+			html += '</select>';
+		}
+		html += '</div>'; // Close datepicker_header
+		return html;
+	},
+
+	/* Provide code to set and clear the status panel. */
+	_addStatus: function(inst, text) {
+		return ' onmouseover="jQuery(\'#ui-datepicker-status-' + inst.id + '\').html(\'' + text + '\');" ' +
+			'onmouseout="jQuery(\'#ui-datepicker-status-' + inst.id + '\').html(\'&#xa0;\');"';
+	},
+
+	/* Adjust one of the date sub-fields. */
+	_adjustInstDate: function(inst, offset, period) {
+		var year = inst.drawYear + (period == 'Y' ? offset : 0);
+		var month = inst.drawMonth + (period == 'M' ? offset : 0);
+		var day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) +
+			(period == 'D' ? offset : 0);
+		var date = new Date(year, month, day);
+		// ensure it is within the bounds set
+		var minDate = this._getMinMaxDate(inst, 'min', true);
+		var maxDate = this._getMinMaxDate(inst, 'max');
+		date = (minDate && date < minDate ? minDate : date);
+		date = (maxDate && date > maxDate ? maxDate : date);
+		inst.selectedDay = date.getDate();
+		inst.drawMonth = inst.selectedMonth = date.getMonth();
+		inst.drawYear = inst.selectedYear = date.getFullYear();
+		if (period == 'M' || period == 'Y')
+			this._notifyChange(inst);
+	},
+
+	/* Notify change of month/year. */
+	_notifyChange: function(inst) {
+		var onChange = this._get(inst, 'onChangeMonthYear');
+		if (onChange)
+			onChange.apply((inst.input ? inst.input[0] : null),
+				[new Date(inst.selectedYear, inst.selectedMonth, 1), inst]);
+	},
+	
+	/* Determine the number of months to show. */
+	_getNumberOfMonths: function(inst) {
+		var numMonths = this._get(inst, 'numberOfMonths');
+		return (numMonths == null ? [1, 1] : (typeof numMonths == 'number' ? [1, numMonths] : numMonths));
+	},
+
+	/* Determine the current maximum date - ensure no time components are set - may be overridden for a range. */
+	_getMinMaxDate: function(inst, minMax, checkRange) {
+		var date = this._determineDate(this._get(inst, minMax + 'Date'), null);
+		if (date) {
+			date.setHours(0);
+			date.setMinutes(0);
+			date.setSeconds(0);
+			date.setMilliseconds(0);
+		}
+		return (!checkRange || !inst.rangeStart ? date :
+			(!date || inst.rangeStart > date ? inst.rangeStart : date));
+	},
+
+	/* Find the number of days in a given month. */
+	_getDaysInMonth: function(year, month) {
+		return 32 - new Date(year, month, 32).getDate();
+	},
+
+	/* Find the day of the week of the first of a month. */
+	_getFirstDayOfMonth: function(year, month) {
+		return new Date(year, month, 1).getDay();
+	},
+
+	/* Determines if we should allow a "next/prev" month display change. */
+	_canAdjustMonth: function(inst, offset, curYear, curMonth) {
+		var numMonths = this._getNumberOfMonths(inst);
+		var date = new Date(curYear, curMonth + (offset < 0 ? offset : numMonths[1]), 1);
+		if (offset < 0)
+			date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
+		return this._isInRange(inst, date);
+	},
+
+	/* Is the given date in the accepted range? */
+	_isInRange: function(inst, date) {
+		// during range selection, use minimum of selected date and range start
+		var newMinDate = (!inst.rangeStart ? null :
+			new Date(inst.selectedYear, inst.selectedMonth, inst.selectedDay));
+		newMinDate = (newMinDate && inst.rangeStart < newMinDate ? inst.rangeStart : newMinDate);
+		var minDate = newMinDate || this._getMinMaxDate(inst, 'min');
+		var maxDate = this._getMinMaxDate(inst, 'max');
+		return ((!minDate || date >= minDate) && (!maxDate || date <= maxDate));
+	},
+	
+	/* Provide the configuration settings for formatting/parsing. */
+	_getFormatConfig: function(inst) {
+		var shortYearCutoff = this._get(inst, 'shortYearCutoff');
+		shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
+			new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
+		return {shortYearCutoff: shortYearCutoff,
+			dayNamesShort: this._get(inst, 'dayNamesShort'), dayNames: this._get(inst, 'dayNames'),
+			monthNamesShort: this._get(inst, 'monthNamesShort'), monthNames: this._get(inst, 'monthNames')};
+	},
+
+	/* Format the given date for display. */
+	_formatDate: function(inst, day, month, year) {
+		if (!day) {
+			inst.currentDay = inst.selectedDay;
+			inst.currentMonth = inst.selectedMonth;
+			inst.currentYear = inst.selectedYear;
+		}
+		var date = (day ? (typeof day == 'object' ? day : new Date(year, month, day)) :
+			new Date(inst.currentYear, inst.currentMonth, inst.currentDay));
+		return this.formatDate(this._get(inst, 'dateFormat'), date, this._getFormatConfig(inst));
+	}
+});
+
+/* jQuery extend now ignores nulls! */
+function extendRemove(target, props) {
+	$.extend(target, props);
+	for (var name in props)
+		if (props[name] == null || props[name] == undefined)
+			target[name] = props[name];
+	return target;
+};
+
+/* Determine whether an object is an array. */
+function isArray(a) {
+	return (a && (($.browser.safari && typeof a == 'object' && a.length) ||
+		(a.constructor && a.constructor.toString().match(/\Array\(\)/))));
+};
+
+/* Invoke the datepicker functionality.
+   @param  options  string - a command, optionally followed by additional parameters or
+                    Object - settings for attaching new datepicker functionality
+   @return  jQuery object */
+$.fn.datepicker = function(options){
+	var otherArgs = Array.prototype.slice.call(arguments, 1);
+	if (typeof options == 'string' && (options == 'isDisabled' || options == 'getDate'))
+		return $.datepicker['_' + options + 'Datepicker'].
+			apply($.datepicker, [this[0]].concat(otherArgs));
+	return this.each(function() {
+		typeof options == 'string' ?
+			$.datepicker['_' + options + 'Datepicker'].
+				apply($.datepicker, [this].concat(otherArgs)) :
+			$.datepicker._attachDatepicker(this, options);
+	});
+};
+
+$.datepicker = new Datepicker(); // singleton instance
+	
+/* Initialise the date picker. */
+$(document).ready(function() {
+	$(document.body).append($.datepicker.dpDiv).
+		mousedown($.datepicker._checkExternalClick);
+});
+
+})(jQuery);
Index: /tags/2.0.2/template-common/lib/ui/ui.datepicker.packed.js
===================================================================
--- /tags/2.0.2/template-common/lib/ui/ui.datepicker.packed.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/ui.datepicker.packed.js	(revision 3278)
@@ -0,0 +1,2 @@
+eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)d[e(c)]=k[c]||e(c);k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(n($){c 19="f";n 3A(){b.7i=F;b.44=r;b.2s=[];b.2W=F;b.2G=F;b.5w="t-f-I";b.5O="t-f-3a";b.2p="t-f-41";b.5x="t-f-9D";b.5g="t-f-3l";b.5a="t-f-3H";b.4o="t-f-4u-G";b.5Q=[];b.5Q[""]={6C:"9C",6D:"9B 4a 4u h",6A:"7m",6B:"7m 9A 6P",2A:"&#9z;9y",6z:"4b 4a 9x C",2z:"9w&#9v;",6y:"4b 4a 3P C",2U:"9u",6x:"4b 4a 4u C",1g:["9t","9s","9r","9q","7l","9p","9o","9n","9m","9l","9k","9j"],1P:["9i","9h","9g","9f","7l","9e","9d","9c","9b","9a","99","98"],6g:"4b a 7k C",69:"4b a 7k A",6v:"97",96:"95 94 4a A",1o:["93","92","91","90","8Z","8Y","8X"],1t:["8W","8V","8U","8T","8S","8R","8Q"],4r:["8P","8O","8N","8M","8L","8K","8J"],4s:"8I 3N 8H 8G 2y G",2S:"7j 3N, M d",2L:"4z/3o/2V",1x:0,6k:"7j a h",1D:F};b.1z={31:"2E",1K:"5H",5A:{},2C:r,49:"",2K:"...",3y:"",7g:F,3G:1i,5i:F,3Q:F,3m:F,5f:F,6h:1i,6d:1i,6c:"-10:+10",3M:1i,3g:F,2w:F,3L:F,4q:b.3O,1C:"+10",1j:F,6w:b.2S,O:r,S:r,1c:"8F",3K:r,48:r,2F:r,68:r,46:r,67:1,2m:1,1E:F,3T:" - ",3Z:"",3q:""};$.4d(b.1z,b.5Q[""]);b.J=$(\'<I x="\'+b.5w+\'" 4l="5I: 6Y;"></I>\')}$.4d(3A.5V,{2H:"8E",5o:n(){k(b.7i){8D.5o.2b("",4T)}},8C:n(u){3D(b.1z,u||{});q b},5S:n(o,u){c 3z=r;1m(4R 61 b.1z){c 4Q=o.8B("h:"+4R);k(4Q){3z=3z||{};6J{3z[4R]=8A(4Q)}6I(8z){3z[4R]=4Q}}}c 1Y=o.1Y.5J();c 1v=(1Y=="I"||1Y=="3k");k(!o.x){o.x="78"+v z().1R()}c 8=b.5P($(o),1v);8.u=$.4d({},u||{},3z||{});k(1Y=="p"){b.7h(o,8)}N{k(1v){b.7b(o,8)}}},5P:n(o,1v){q{x:o[0].x,p:o,1s:0,1r:0,1B:0,H:0,K:0,1v:1v,J:(!1v?b.J:$(\'<I V="t-f-1v"></I>\'))}},7h:n(o,8){c p=$(o);k(p.42(b.2H)){q}c 49=b.l(8,"49");c 1D=b.l(8,"1D");k(49){p[1D?"7d":"7c"](\'<3k V="\'+b.5O+\'">\'+49+"</3k>")}c 31=b.l(8,"31");k(31=="2E"||31=="4k"){p.2E(b.3v)}k(31=="3x"||31=="4k"){c 2K=b.l(8,"2K");c 3y=b.l(8,"3y");c 41=$(b.l(8,"7g")?$("<4N/>").2j(b.2p).7f({56:3y,7e:2K,3J:2K}):$(\'<3x 47="3x"></3x>\').2j(b.2p).R(3y==""?2K:$("<4N/>").7f({56:3y,7e:2K,3J:2K})));p[1D?"7d":"7c"](41);41.8y(n(){k($.f.2W&&$.f.3r==o){$.f.2B()}N{$.f.3v(o)}q F})}p.2j(b.2H).5N(b.4M).75(b.5M).4P("7a.f",n(3s,2J,E){8.u[2J]=E}).4P("79.f",n(3s,2J){q b.l(8,2J)});$.1d(o,19,8)},7b:n(o,8){c p=$(o);k(p.42(b.2H)){q}p.2j(b.2H).3a(8.J).4P("7a.f",n(3s,2J,E){8.u[2J]=E}).4P("79.f",n(3s,2J){q b.l(8,2J)});$.1d(o,19,8);b.5k(8,b.5n(8));b.24(8)},8x:n(8){c 1b=b.3d(8);8.J.1M(1b[1]*$(".t-f",8.J[0]).1M())},8w:n(p,76,2F,u,2r){c 8=b.77;k(!8){c x="78"+v z().1R();b.26=$(\'<p 47="50" x="\'+x+\'" 23="1" 4l="1W: 4F; 1X: -6R;"/>\');b.26.5N(b.4M);$("29").3a(b.26);8=b.77=b.5P(b.26,F);8.u={};$.1d(b.26[0],19,8)}3D(8.u,u||{});b.26.3n(76);b.1H=(2r?(2r.1a?2r:[2r.8v,2r.8u]):r);k(!b.1H){c 4I=4J.6T||15.1L.5F||15.29.5F;c 4H=4J.6S||15.1L.5E||15.29.5E;c 30=15.1L.3u||15.29.3u;c 2Z=15.1L.3t||15.29.3t;b.1H=[(4I/2)-2O+30,(4H/2)-8t+2Z]}b.26.25("2q",b.1H[0]+"4K").25("1X",b.1H[1]+"4K");8.u.2F=2F;b.2G=1i;b.J.2j(b.5x);b.3v(b.26[0]);k($.43){$.43(b.J)}$.1d(b.26[0],19,8);q b},8s:n(o){c 1Y=o.1Y.5J();c $o=$(o);$.8r(o,19);k(1Y=="p"){$o.3w("."+b.5O).45().3i().3w("."+b.2p).45().3i().2Q(b.2H).4E("2E",b.3v).4E("5N",b.4M).4E("75",b.5M)}N{k(1Y=="I"||1Y=="3k"){$o.2Q(b.2H).6X()}}},8q:n(o){o.4O=F;$(o).3w("3x."+b.2p).3C(n(){b.4O=F}).3i().3w("4N."+b.2p).25({74:"1.0",73:""});b.2s=$.72(b.2s,n(E){q(E==o?r:E)})},8p:n(o){o.4O=1i;$(o).3w("3x."+b.2p).3C(n(){b.4O=1i}).3i().3w("4N."+b.2p).25({74:"0.5",73:"3V"});b.2s=$.72(b.2s,n(E){q(E==o?r:E)});b.2s[b.2s.1a]=o},70:n(o){k(!o){q F}1m(c i=0;i<b.2s.1a;i++){k(b.2s[i]==o){q 1i}}q F},8o:n(o,1e,E){c u=1e||{};k(1O 1e=="3B"){u={};u[1e]=E}k(8=$.1d(o,19)){3D(8.u,u);b.24(8)}},8n:n(o,h,1S){c 8=$.1d(o,19);k(8){b.5k(8,h,1S);b.24(8)}},8m:n(o){c 8=$.1d(o,19);k(8){b.5q(8)}q(8?b.4w(8):r)},4M:n(e){c 8=$.1d(e.o,19);c 4L=1i;k($.f.2W){3U(e.5L){B 9:$.f.2B(r,"");L;B 13:$.f.59(e.o,8.1r,8.1B,$("1w.t-f-3h-2R-2x",8.J)[0]);q F;L;B 27:$.f.2B(r,$.f.l(8,"1c"));L;B 33:$.f.1U(e.o,(e.1N?-1:-$.f.l(8,"2m")),(e.1N?"Y":"M"));L;B 34:$.f.1U(e.o,(e.1N?+1:+$.f.l(8,"2m")),(e.1N?"Y":"M"));L;B 35:k(e.1N){$.f.5h(e.o)}L;B 36:k(e.1N){$.f.5e(e.o)}L;B 37:k(e.1N){$.f.1U(e.o,-1,"D")}L;B 38:k(e.1N){$.f.1U(e.o,-7,"D")}L;B 39:k(e.1N){$.f.1U(e.o,+1,"D")}L;B 40:k(e.1N){$.f.1U(e.o,+7,"D")}L;3V:4L=F}}N{k(e.5L==36&&e.1N){$.f.3v(b)}N{4L=F}}k(4L){e.8l();e.8k()}},5M:n(e){c 8=$.1d(e.o,19);c 2n=$.f.6K($.f.l(8,"2L"));c 5K=8j.8i(e.71==4U?e.5L:e.71);q e.1N||(5K<" "||!2n||2n.6u(5K)>-1)},3v:n(p){p=p.o||p;k(p.1Y.5J()!="p"){p=$("p",p.8h)[0]}k($.f.70(p)||$.f.3r==p){q}c 8=$.1d(p,19);c 48=$.f.l(8,"48");3D(8.u,(48?48.2b(p,[p,8]):{}));$.f.2B(r,"");$.f.3r=p;$.f.5q(8);k($.f.2G){p.E=""}k(!$.f.1H){$.f.1H=$.f.5C(p);$.f.1H[1]+=p.8g}c 1p=F;$(p).6Q().3C(n(){1p|=$(b).25("1W")=="6Z";q!1p});k(1p&&$.2c.5D){$.f.1H[0]-=15.1L.3u;$.f.1H[1]-=15.1L.3t}c P={2q:$.f.1H[0],1X:$.f.1H[1]};$.f.1H=r;8.1h=r;8.J.25({1W:"4F",5I:"8f",1X:"-8e"});$.f.24(8);8.J.1M($.f.3d(8)[1]*$(".t-f",8.J[0])[0].8d);P=$.f.6U(8,P,1p);8.J.25({1W:($.f.2G&&$.43?"8c":(1p?"6Z":"4F")),5I:"6Y",2q:P.2q+"4K",1X:P.1X+"4K"});k(!8.1v){c 1K=$.f.l(8,"1K")||"5H";c 1c=$.f.l(8,"1c");c 2X=n(){$.f.2W=1i;k($.2c.57&&2N($.2c.6j)<7){$("4j.t-f-55").25({1M:8.J.1M()+4,2I:8.J.2I()+4})}};k($.4G&&$.4G[1K]){8.J.5H(1K,$.f.l(8,"5A"),1c,2X)}N{8.J[1K](1c,2X)}k(1c==""){2X()}k(8.p[0].47!="5B"){8.p[0].2E()}$.f.44=8}},24:n(8){c 5G={1M:8.J.1M()+4,2I:8.J.2I()+4};8.J.6X().3a(b.6E(8)).8b("4j.t-f-55").25({1M:5G.1M,2I:5G.2I});c 1b=b.3d(8);8.J[(1b[0]!=1||1b[1]!=1?"6W":"45")+"6V"]("t-f-8a");8.J[(b.l(8,"1D")?"6W":"45")+"6V"]("t-f-89");k(8.p&&8.p[0].47!="5B"){$(8.p[0]).2E()}},6U:n(8,P,1p){c 2r=8.p?b.5C(8.p[0]):r;c 4I=4J.6T||15.1L.5F;c 4H=4J.6S||15.1L.5E;c 30=15.1L.3u||15.29.3u;c 2Z=15.1L.3t||15.29.3t;k(b.l(8,"1D")||(P.2q+8.J.1M()-30)>4I){P.2q=1Q.2t((1p?0:30),2r[0]+(8.p?8.p.1M():0)-(1p?30:0)-8.J.1M()-(1p&&$.2c.5D?15.1L.3u:0))}N{P.2q-=(1p?30:0)}k((P.1X+8.J.2I()-2Z)>4H){P.1X=1Q.2t((1p?0:2Z),2r[1]-(1p?2Z:0)-(b.2G?0:8.J.2I())-(1p&&$.2c.5D?15.1L.3t:0))}N{P.1X-=(1p?2Z:0)}q P},5C:n(2Y){3S(2Y&&(2Y.47=="5B"||2Y.88!=1)){2Y=2Y.87}c 1W=$(2Y).P();q[1W.2q,1W.1X]},2B:n(p,1c){c 8=b.44;k(!8){q}c 1E=b.l(8,"1E");k(1E&&b.2o){b.4C("#"+8.x,b.2M(8,8.1f,8.1q,8.1n))}b.2o=F;k(b.2W){1c=(1c!=r?1c:b.l(8,"1c"));c 1K=b.l(8,"1K");c 2X=n(){$.f.5y(8)};k(1c!=""&&$.4G&&$.4G[1K]){8.J.5z(1K,$.f.l(8,"5A"),1c,2X)}N{8.J[(1c==""?"5z":(1K=="86"?"85":(1K=="84"?"83":"5z")))](1c,2X)}k(1c==""){b.5y(8)}c 46=b.l(8,"46");k(46){46.2b((8.p?8.p[0]:r),[b.4w(8),8])}b.2W=F;b.3r=r;8.u.3l=r;k(b.2G){b.26.25({1W:"4F",2q:"0",1X:"-6R"});k($.43){$.82();$("29").3a(b.J)}}b.2G=F}b.44=r},5y:n(8){8.J.2Q(b.5x).4E(".t-f");$("."+b.5g,8.J).45()},5R:n(3s){k(!$.f.44){q}c $o=$(3s.o);k(($o.6Q("#"+$.f.5w).1a==0)&&!$o.42($.f.2H)&&!$o.42($.f.2p)&&$.f.2W&&!($.f.2G&&$.43)){$.f.2B(r,"")}},1U:n(x,P,20){c o=$(x);c 8=$.1d(o[0],19);b.4g(8,P,20);b.24(8)},5e:n(x){c o=$(x);c 8=$.1d(o[0],19);k(b.l(8,"5f")&&8.1f){8.1s=8.1f;8.H=8.1r=8.1q;8.K=8.1B=8.1n}N{c h=v z();8.1s=h.U();8.H=8.1r=h.16();8.K=8.1B=h.Q()}b.1U(o);b.4f(8)},53:n(x,2P,20){c o=$(x);c 8=$.1d(o[0],19);8.4D=F;8[20=="M"?"H":"K"]=2P.2a[2P.81].E-0;b.1U(o);b.4f(8)},52:n(x){c o=$(x);c 8=$.1d(o[0],19);k(8.p&&8.4D&&!$.2c.57){8.p[0].2E()}8.4D=!8.4D},6s:n(x,G){c o=$(x);c 8=$.1d(o[0],19);8.u.1x=G;b.24(8)},59:n(x,C,A,1w){k($(1w).42(b.5a)){q}c o=$(x);c 8=$.1d(o[0],19);c 1E=b.l(8,"1E");k(1E){b.2o=!b.2o;k(b.2o){$(".t-f 1w").2Q(b.4o);$(1w).2j(b.4o)}}8.1s=8.1f=$("a",1w).R();8.1r=8.1q=C;8.1B=8.1n=A;k(b.2o){8.1T=8.22=8.17=r}N{k(1E){8.1T=8.1f;8.22=8.1q;8.17=8.1n}}b.4C(x,b.2M(8,8.1f,8.1q,8.1n));k(b.2o){8.1h=v z(8.1n,8.1q,8.1f);b.24(8)}N{k(1E){8.1s=8.1f=8.1h.U();8.1r=8.1q=8.1h.16();8.1B=8.1n=8.1h.Q();8.1h=r;k(8.1v){b.24(8)}}}},5h:n(x){c o=$(x);c 8=$.1d(o[0],19);k(b.l(8,"5i")){q}b.2o=F;8.1T=8.22=8.17=8.1h=r;b.4C(o,"")},4C:n(x,1J){c o=$(x);c 8=$.1d(o[0],19);1J=(1J!=r?1J:b.2M(8));k(b.l(8,"1E")&&1J){1J=(8.1h?b.2M(8,8.1h):1J)+b.l(8,"3T")+1J}k(8.p){8.p.3n(1J)}b.6O(8);c 2F=b.l(8,"2F");k(2F){2F.2b((8.p?8.p[0]:r),[1J,8])}N{k(8.p){8.p.41("6P")}}k(8.1v){b.24(8)}N{k(!b.2o){b.2B(r,b.l(8,"1c"));b.3r=8.p[0];k(1O(8.p[0])!="4c"){8.p[0].2E()}b.3r=r}}},6O:n(8){c 3Z=b.l(8,"3Z");k(3Z){c 3q=b.l(8,"3q");c h=b.4w(8);1J=(5Z(h)?(!h[0]&&!h[1]?"":b.2d(3q,h[0],b.1Z(8))+b.l(8,"3T")+b.2d(3q,h[1]||h[0],b.1Z(8))):b.2d(3q,h,b.1Z(8)));$(3Z).3C(n(){$(b).3n(1J)})}},80:n(h){c G=h.3e();q[(G>0&&G<6),""]},3O:n(h){c 1A=v z(h.Q(),h.16(),h.U(),(h.7Z()/-60));c 3p=v z(1A.Q(),1-1,4);c 1x=3p.3e()||7;3p.4e(3p.U()+1-1x);k(1x<4&&1A<3p){1A.4e(1A.U()-3);q $.f.3O(1A)}N{k(1A>v z(1A.Q(),12-1,28)){1x=v z(1A.Q()+1,1-1,4).3e()||7;k(1x>4&&(1A.3e()||7)<1x-3){1A.4e(1A.U()+3);q $.f.3O(1A)}}}q 1Q.7Y(((1A-3p)/7X)/7)+1},2S:n(h,8){q $.f.2d($.f.l(8,"2S"),h,$.f.1Z(8))},5p:n(X,E,u){k(X==r||E==r){3W"6M 4T"}E=(1O E=="4c"?E.5X():E+"");k(E==""){q r}c 1C=(u?u.1C:r)||b.1z.1C;c 1t=(u?u.1t:r)||b.1z.1t;c 1o=(u?u.1o:r)||b.1z.1o;c 1P=(u?u.1P:r)||b.1z.1P;c 1g=(u?u.1g:r)||b.1z.1g;c A=-1;c C=-1;c G=-1;c 1F=F;c 1G=n(1l){c 1y=(T+1<X.1a&&X.18(T+1)==1l);k(1y){T++}q 1y};c 3X=n(1l){1G(1l);c 5v=(1l=="@"?14:(1l=="y"?4:2));c 23=5v;c 4B=0;3S(23>0&&1I<E.1a&&E.18(1I)>="0"&&E.18(1I)<="9"){4B=4B*10+(E.18(1I++)-0);23--}k(23==5v){3W"7W 4X 5u 1W "+1I}q 4B};c 5t=n(1l,4x,4y){c 3Y=(1G(1l)?4y:4x);c 23=0;1m(c j=0;j<3Y.1a;j++){23=1Q.2t(23,3Y[j].1a)}c 1e="";c 6N=1I;3S(23>0&&1I<E.1a){1e+=E.18(1I++);1m(c i=0;i<3Y.1a;i++){k(1e==3Y[i]){q i+1}}23--}3W"7V 1e 5u 1W "+6N};c 4A=n(){k(E.18(1I)!=X.18(T)){3W"7U 1F 5u 1W "+1I}1I++};c 1I=0;1m(c T=0;T<X.1a;T++){k(1F){k(X.18(T)=="\'"&&!1G("\'")){1F=F}N{4A()}}N{3U(X.18(T)){B"d":G=3X("d");L;B"D":5t("D",1t,1o);L;B"m":C=3X("m");L;B"M":C=5t("M",1P,1g);L;B"y":A=3X("y");L;B"@":c h=v z(3X("@"));A=h.Q();C=h.16()+1;G=h.U();L;B"\'":k(1G("\'")){4A()}N{1F=1i}L;3V:4A()}}}k(A<2O){A+=v z().Q()-v z().Q()%2O+(A<=1C?0:-2O)}c h=v z(A,C-1,G);k(h.Q()!=A||h.16()+1!=C||h.U()!=G){3W"6M h"}q h},7T:"2V-4z-3o",7S:"D, 3o M 2V",7R:"2V-4z-3o",7Q:"D, d M y",7P:"3N, 3o-M-y",7O:"D, d M y",7N:"D, d M 2V",7M:"D, d M 2V",7L:"D, d M y",7K:"@",7J:"2V-4z-3o",2d:n(X,h,u){k(!h){q""}c 1t=(u?u.1t:r)||b.1z.1t;c 1o=(u?u.1o:r)||b.1z.1o;c 1P=(u?u.1P:r)||b.1z.1P;c 1g=(u?u.1g:r)||b.1z.1g;c 1G=n(1l){c 1y=(T+1<X.1a&&X.18(T+1)==1l);k(1y){T++}q 1y};c 5s=n(1l,E){q(1G(1l)&&E<10?"0":"")+E};c 5r=n(1l,E,4x,4y){q(1G(1l)?4y[E]:4x[E])};c 1V="";c 1F=F;k(h){1m(c T=0;T<X.1a;T++){k(1F){k(X.18(T)=="\'"&&!1G("\'")){1F=F}N{1V+=X.18(T)}}N{3U(X.18(T)){B"d":1V+=5s("d",h.U());L;B"D":1V+=5r("D",h.3e(),1t,1o);L;B"m":1V+=5s("m",h.16()+1);L;B"M":1V+=5r("M",h.16(),1P,1g);L;B"y":1V+=(1G("y")?h.Q():(h.6L()%2O<10?"0":"")+h.6L()%2O);L;B"@":1V+=h.1R();L;B"\'":k(1G("\'")){1V+="\'"}N{1F=1i}L;3V:1V+=X.18(T)}}}}q 1V},6K:n(X){c 2n="";c 1F=F;1m(c T=0;T<X.1a;T++){k(1F){k(X.18(T)=="\'"&&!1G("\'")){1F=F}N{2n+=X.18(T)}}N{3U(X.18(T)){B"d":B"m":B"y":B"@":2n+="7I";L;B"D":B"M":q r;B"\'":k(1G("\'")){2n+="\'"}N{1F=1i}L;3V:2n+=X.18(T)}}}q 2n},l:n(8,1e){q 8.u[1e]!==4U?8.u[1e]:b.1z[1e]},5q:n(8){c 2L=b.l(8,"2L");c 2D=8.p?8.p.3n().6b(b.l(8,"3T")):r;8.1T=8.22=8.17=r;c h=2C=b.5n(8);k(2D.1a>0){c u=b.1Z(8);k(2D.1a>1){h=b.5p(2L,2D[1],u)||2C;8.1T=h.U();8.22=h.16();8.17=h.Q()}6J{h=b.5p(2L,2D[0],u)||2C}6I(e){b.5o(e);h=2C}}8.1s=h.U();8.H=8.1r=h.16();8.K=8.1B=h.Q();8.1f=(2D[0]?h.U():0);8.1q=(2D[0]?h.16():0);8.1n=(2D[0]?h.Q():0);b.4g(8)},5n:n(8){c h=b.3F(b.l(8,"2C"),v z());c O=b.2e(8,"2f",1i);c S=b.2e(8,"2t");h=(O&&h<O?O:h);h=(S&&h>S?S:h);q h},3F:n(h,2C){c 6F=n(P){c h=v z();h.6o(h.6n()+P);q h};c 6G=n(P,5m){c h=v z();c A=h.Q();c C=h.16();c G=h.U();c 5l=/([+-]?[0-9]+)\\s*(d|D|w|W|m|M|y|Y)?/g;c 1y=5l.6H(P);3S(1y){3U(1y[2]||"d"){B"d":B"D":G+=(1y[1]-0);L;B"w":B"W":G+=(1y[1]*7);L;B"m":B"M":C+=(1y[1]-0);G=1Q.2f(G,5m(A,C));L;B"y":B"Y":A+=(1y[1]-0);G=1Q.2f(G,5m(A,C));L}1y=5l.6H(P)}q v z(A,C,G)};q(h==r?2C:(1O h=="3B"?6G(h,b.3E):(1O h=="4X"?6F(h):h)))},5k:n(8,h,1S){c 2v=!(h);h=b.3F(h,v z());8.1s=8.1f=h.U();8.H=8.1r=8.1q=h.16();8.K=8.1B=8.1n=h.Q();k(b.l(8,"1E")){k(1S){1S=b.3F(1S,r);8.1T=1S.U();8.22=1S.16();8.17=1S.Q()}N{8.1T=8.1f;8.22=8.1q;8.17=8.1n}}b.4g(8);k(8.p){8.p.3n(2v?"":b.2M(8)+(!b.l(8,"1E")?"":b.l(8,"3T")+b.2M(8,8.1T,8.22,8.17)))}},4w:n(8){c 5j=(!8.1n||(8.p&&8.p.3n()=="")?r:v z(8.1n,8.1q,8.1f));k(b.l(8,"1E")){q[8.1h||5j,(!8.17?r:v z(8.17,8.22,8.1T))]}N{q 5j}},6E:n(8){c 2k=v z();2k=v z(2k.Q(),2k.16(),2k.U());c 1j=b.l(8,"1j");c 1D=b.l(8,"1D");c 2v=(b.l(8,"5i")?"":\'<I V="t-f-2v"><a 2h="Z.f.5h(\\\'#\'+8.x+"\');\\""+(1j?b.2g(8,b.l(8,"6D")||"&#1u;"):"")+">"+b.l(8,"6C")+"</a></I>");c 58=\'<I V="t-f-7H">\'+(1D?"":2v)+\'<I V="t-f-7G"><a 2h="Z.f.2B();"\'+(1j?b.2g(8,b.l(8,"6B")||"&#1u;"):"")+">"+b.l(8,"6A")+"</a></I>"+(1D?2v:"")+"</I>";c 3l=b.l(8,"3l");c 3G=b.l(8,"3G");c 3Q=b.l(8,"3Q");c 3m=b.l(8,"3m");c 1b=b.3d(8);c 2m=b.l(8,"2m");c 6q=(1b[0]!=1||1b[1]!=1);c 4p=(!8.1f?v z(7F,9,9):v z(8.1n,8.1q,8.1f));c O=b.2e(8,"2f",1i);c S=b.2e(8,"2t");c H=8.H;c K=8.K;k(S){c 3R=v z(S.Q(),S.16()-1b[1]+1,S.U());3R=(O&&3R<O?O:3R);3S(v z(K,H,1)>3R){H--;k(H<0){H=11;K--}}}c 2A=b.l(8,"2A");2A=(!3m?2A:b.2d(2A,v z(K,H-2m,1),b.1Z(8)));c 4t=\'<I V="t-f-4t">\'+(b.4W(8,-1,K,H)?"<a 2h=\\"Z.f.1U(\'#"+8.x+"\', -"+2m+", \'M\');\\""+(1j?b.2g(8,b.l(8,"6z")||"&#1u;"):"")+">"+2A+"</a>":(3Q?"":"<4v>"+2A+"</4v>"))+"</I>";c 2z=b.l(8,"2z");2z=(!3m?2z:b.2d(2z,v z(K,H+2m,1),b.1Z(8)));c 3P=\'<I V="t-f-3P">\'+(b.4W(8,+1,K,H)?"<a 2h=\\"Z.f.1U(\'#"+8.x+"\', +"+2m+", \'M\');\\""+(1j?b.2g(8,b.l(8,"6y")||"&#1u;"):"")+">"+2z+"</a>":(3Q?"":"<4v>"+2z+"</4v>"))+"</I>";c 2U=b.l(8,"2U");2U=(!3m?2U:b.2d(2U,2k,b.1Z(8)));c R=(3l?\'<I V="\'+b.5g+\'">\'+3l+"</I>":"")+(3G&&!8.1v?58:"")+\'<I V="t-f-7E">\'+(1D?3P:4t)+(b.4V(8,(b.l(8,"5f")&&8.1f?4p:2k))?\'<I V="t-f-4u"><a 2h="Z.f.5e(\\\'#\'+8.x+"\');\\""+(1j?b.2g(8,b.l(8,"6x")||"&#1u;"):"")+">"+2U+"</a></I>":"")+(1D?4t:3P)+"</I>";c 1x=b.l(8,"1x");c 3M=b.l(8,"3M");c 1o=b.l(8,"1o");c 1t=b.l(8,"1t");c 4r=b.l(8,"4r");c 1g=b.l(8,"1g");c 3K=b.l(8,"3K");c 3g=b.l(8,"3g");c 2w=b.l(8,"2w");c 3L=b.l(8,"3L");c 4q=b.l(8,"4q")||b.3O;c 21=(1j?b.l(8,"4s")||"&#1u;":"");c 2S=b.l(8,"6w")||b.2S;c 1S=8.1T?v z(8.17,8.22,8.1T):4p;1m(c 2T=0;2T<1b[0];2T++){1m(c 3j=0;3j<1b[1];3j++){c 3f=v z(K,H,8.1s);R+=\'<I V="t-f-7D-C\'+(3j==0?" t-f-v-2T":"")+\'">\'+b.6i(8,H,K,O,S,3f,2T>0||3j>0,1j,1g)+\'<6l V="t-f" 7C="0" 7B="0"><6r><4m V="t-f-3J-2T">\'+(3L?"<1w>"+b.l(8,"6v")+"</1w>":"");1m(c 2l=0;2l<7;2l++){c G=(2l+1x)%7;c 4s=(21.6u("3N")>-1?21.6t(/3N/,1o[G]):21.6t(/D/,1t[G]));R+="<1w"+((2l+1x+6)%7>=5?\' V="t-f-2y-3i-2R"\':"")+">"+(!3M?"<3k":"<a 2h=\\"Z.f.6s(\'#"+8.x+"\', "+G+\');"\')+(1j?b.2g(8,4s):"")+\' 3J="\'+1o[G]+\'">\'+4r[G]+(3M?"</a>":"</3k>")+"</1w>"}R+="</4m></6r><6m>";c 5c=b.3E(K,H);k(K==8.1B&&H==8.1r){8.1s=1Q.2f(8.1s,5c)}c 5d=(b.64(K,H)-1x+7)%7;c 1k=v z(K,H,1-5d);c 6p=(6q?6:1Q.7A((5d+5c)/7));1m(c 5b=0;5b<6p;5b++){R+=\'<4m V="t-f-3h-2T">\'+(3L?\'<1w V="t-f-2y-3j">\'+4q(1k)+"</1w>":"");1m(c 2l=0;2l<7;2l++){c 3I=(3K?3K.2b((8.p?8.p[0]:r),[1k]):[1i,""]);c 2i=(1k.16()!=H);c 3H=2i||!3I[0]||(O&&1k<O)||(S&&1k>S);R+=\'<1w V="t-f-3h-2R\'+((2l+1x+6)%7>=5?" t-f-2y-3i-2R":"")+(2i?" t-f-2i":"")+(1k.1R()==3f.1R()&&H==8.1r?" t-f-3h-2R-2x":"")+(3H?" "+b.5a:"")+(2i&&!2w?"":" "+3I[1]+(1k.1R()>=4p.1R()&&1k.1R()<=1S.1R()?" "+b.4o:"")+(1k.1R()==2k.1R()?" t-f-2k":""))+\'"\'+((!2i||2w)&&3I[2]?\' 3J="\'+3I[2]+\'"\':"")+(3H?(3g?" 51=\\"Z(b).4n().2j(\'t-f-2y-2x\');\\" 4Z=\\"Z(b).4n().2Q(\'t-f-2y-2x\');\\"":""):" 51=\\"Z(b).2j(\'t-f-3h-2R-2x\')"+(3g?".4n().2j(\'t-f-2y-2x\')":"")+";"+(!1j||(2i&&!2w)?"":"Z(\'#t-f-21-"+8.x+"\').R(\'"+(2S.2b((8.p?8.p[0]:r),[1k,8])||"&#1u;")+"\');")+"\\" 4Z=\\"Z(b).2Q(\'t-f-3h-2R-2x\')"+(3g?".4n().2Q(\'t-f-2y-2x\')":"")+";"+(!1j||(2i&&!2w)?"":"Z(\'#t-f-21-"+8.x+"\').R(\'&#1u;\');")+\'" 2h="Z.f.59(\\\'#\'+8.x+"\',"+H+","+K+\', b);"\')+">"+(2i?(2w?1k.U():"&#1u;"):(3H?1k.U():"<a>"+1k.U()+"</a>"))+"</1w>";1k.6o(1k.6n()+1)}R+="</4m>"}H++;k(H>11){H=0;K++}R+="</6m></6l></I>"}}R+=(1j?\'<I 4l="2v: 4k;"></I><I x="t-f-21-\'+8.x+\'" V="t-f-21">\'+(b.l(8,"6k")||"&#1u;")+"</I>":"")+(!3G&&!8.1v?58:"")+\'<I 4l="2v: 4k;"></I>\'+($.2c.57&&2N($.2c.6j)<7&&!8.1v?\'<4j 56="7z:F;" V="t-f-55"></4j>\':"");q R},6i:n(8,H,K,O,S,3f,54,1j,1g){O=(8.1h&&O&&3f<O?3f:O);c R=\'<I V="t-f-7y">\';k(54||!b.l(8,"6h")){R+=1g[H]+"&#1u;"}N{c 6f=(O&&O.Q()==K);c 6e=(S&&S.Q()==K);R+=\'<2P V="t-f-v-C" 6a="Z.f.53(\\\'#\'+8.x+"\', b, \'M\');\\" 2h=\\"Z.f.52(\'#"+8.x+"\');\\""+(1j?b.2g(8,b.l(8,"6g")||"&#1u;"):"")+">";1m(c C=0;C<12;C++){k((!6f||C>=O.16())&&(!6e||C<=S.16())){R+=\'<4h E="\'+C+\'"\'+(C==H?\' 4i="4i"\':"")+">"+1g[C]+"</4h>"}}R+="</2P>"}k(54||!b.l(8,"6d")){R+=K}N{c 2u=b.l(8,"6c").6b(":");c A=0;c 17=0;k(2u.1a!=2){A=K-10;17=K+10}N{k(2u[0].18(0)=="+"||2u[0].18(0)=="-"){A=17=v z().Q();A+=2N(2u[0],10);17+=2N(2u[1],10)}N{A=2N(2u[0],10);17=2N(2u[1],10)}}A=(O?1Q.2t(A,O.Q()):A);17=(S?1Q.2f(17,S.Q()):17);R+=\'<2P V="t-f-v-A" 6a="Z.f.53(\\\'#\'+8.x+"\', b, \'Y\');\\" 2h=\\"Z.f.52(\'#"+8.x+"\');\\""+(1j?b.2g(8,b.l(8,"69")||"&#1u;"):"")+">";1m(;A<=17;A++){R+=\'<4h E="\'+A+\'"\'+(A==K?\' 4i="4i"\':"")+">"+A+"</4h>"}R+="</2P>"}R+="</I>";q R},2g:n(8,50){q" 51=\\"Z(\'#t-f-21-"+8.x+"\').R(\'"+50+"\');\\" 4Z=\\"Z(\'#t-f-21-"+8.x+"\').R(\'&#1u;\');\\""},4g:n(8,P,20){c A=8.K+(20=="Y"?P:0);c C=8.H+(20=="M"?P:0);c G=1Q.2f(8.1s,b.3E(A,C))+(20=="D"?P:0);c h=v z(A,C,G);c O=b.2e(8,"2f",1i);c S=b.2e(8,"2t");h=(O&&h<O?O:h);h=(S&&h>S?S:h);8.1s=h.U();8.H=8.1r=h.16();8.K=8.1B=h.Q();k(20=="M"||20=="Y"){b.4f(8)}},4f:n(8){c 4Y=b.l(8,"68");k(4Y){4Y.2b((8.p?8.p[0]:r),[v z(8.1B,8.1r,1),8])}},3d:n(8){c 1b=b.l(8,"67");q(1b==r?[1,1]:(1O 1b=="4X"?[1,1b]:1b))},2e:n(8,66,65){c h=b.3F(b.l(8,66+"z"),r);k(h){h.7x(0);h.7w(0);h.7v(0);h.7u(0)}q(!65||!8.1h?h:(!h||8.1h>h?8.1h:h))},3E:n(A,C){q 32-v z(A,C,32).U()},64:n(A,C){q v z(A,C,1).3e()},4W:n(8,P,63,62){c 1b=b.3d(8);c h=v z(63,62+(P<0?P:1b[1]),1);k(P<0){h.4e(b.3E(h.Q(),h.16()))}q b.4V(8,h)},4V:n(8,h){c 3c=(!8.1h?r:v z(8.1B,8.1r,8.1s));3c=(3c&&8.1h<3c?8.1h:3c);c O=3c||b.2e(8,"2f");c S=b.2e(8,"2t");q((!O||h>=O)&&(!S||h<=S))},1Z:n(8){c 1C=b.l(8,"1C");1C=(1O 1C!="3B"?1C:v z().Q()%2O+2N(1C,10));q{1C:1C,1t:b.l(8,"1t"),1o:b.l(8,"1o"),1P:b.l(8,"1P"),1g:b.l(8,"1g")}},2M:n(8,G,C,A){k(!G){8.1f=8.1s;8.1q=8.1r;8.1n=8.1B}c h=(G?(1O G=="4c"?G:v z(A,C,G)):v z(8.1n,8.1q,8.1f));q b.2d(b.l(8,"2L"),h,b.1Z(8))}});n 3D(o,3b){$.4d(o,3b);1m(c 1e 61 3b){k(3b[1e]==r||3b[1e]==4U){o[1e]=3b[1e]}}q o}n 5Z(a){q(a&&(($.2c.7t&&1O a=="4c"&&a.1a)||(a.5Y&&a.5Y.5X().1l(/\\5W\\(\\)/))))}$.7s.f=n(2a){c 4S=5W.5V.7r.7q(4T,1);k(1O 2a=="3B"&&(2a=="7p"||2a=="U")){q $.f["5U"+2a+"3A"].2b($.f,[b[0]].5T(4S))}q b.3C(n(){1O 2a=="3B"?$.f["5U"+2a+"3A"].2b($.f,[b].5T(4S)):$.f.5S(b,2a)})};$.f=v 3A();$(15).7o(n(){$(15.29).3a($.f.J).7n($.f.5R)})})(Z)',62,598,'||||||||inst|||this|var|||datepicker||date|||if|_get||function|target|input|return|null||ui|settings|new||id||Date|year|case|month||value|false|day|drawMonth|div|dpDiv|drawYear|break||else|minDate|offset|getFullYear|html|maxDate|iFormat|getDate|class||format||jQuery||||||document|getMonth|endYear|charAt|PROP_NAME|length|numMonths|duration|data|name|currentDay|monthNames|rangeStart|true|showStatus|printDate|match|for|currentYear|dayNames|isFixed|currentMonth|selectedMonth|selectedDay|dayNamesShort|xa0|inline|td|firstDay|matches|_defaults|checkDate|selectedYear|shortYearCutoff|isRTL|rangeSelect|literal|lookAhead|_pos|iValue|dateStr|showAnim|documentElement|width|ctrlKey|typeof|monthNamesShort|Math|getTime|endDate|endDay|_adjustDate|output|position|top|nodeName|_getFormatConfig|period|status|endMonth|size|_updateDatepicker|css|_dialogInput|||body|options|apply|browser|formatDate|_getMinMaxDate|min|_addStatus|onclick|otherMonth|addClass|today|dow|stepMonths|chars|_stayOpen|_triggerClass|left|pos|_disabledInputs|max|years|clear|showOtherMonths|over|week|nextText|prevText|_hideDatepicker|defaultDate|dates|focus|onSelect|_inDialog|markerClassName|height|key|buttonText|dateFormat|_formatDate|parseInt|100|select|removeClass|cell|dateStatus|row|currentText|yy|_datepickerShowing|postProcess|obj|scrollY|scrollX|showOn|||||||||append|props|newMinDate|_getNumberOfMonths|getDay|selectedDate|highlightWeek|days|end|col|span|prompt|navigationAsDateFormat|val|dd|firstMon|altFormat|_lastInput|event|scrollTop|scrollLeft|_showDatepicker|siblings|button|buttonImage|inlineSettings|Datepicker|string|each|extendRemove|_getDaysInMonth|_determineDate|closeAtTop|unselectable|daySettings|title|beforeShowDay|showWeeks|changeFirstDay|DD|iso8601Week|next|hideIfNoPrevNext|maxDraw|while|rangeSeparator|switch|default|throw|getNumber|names|altField||trigger|hasClass|blockUI|_curInst|remove|onClose|type|beforeShow|appendText|the|Show|object|extend|setDate|_notifyChange|_adjustInstDate|option|selected|iframe|both|style|tr|parent|_currentClass|currentDate|calculateWeek|dayNamesMin|dayStatus|prev|current|label|_getDate|shortNames|longNames|mm|checkLiteral|num|_selectDate|_selectingMonthYear|unbind|absolute|effects|browserHeight|browserWidth|window|px|handled|_doKeyDown|img|disabled|bind|attrValue|attrName|otherArgs|arguments|undefined|_isInRange|_canAdjustMonth|number|onChange|onmouseout|text|onmouseover|_clickMonthYear|_selectMonthYear|secondary|cover|src|msie|controls|_selectDay|_unselectableClass|dRow|daysInMonth|leadDays|_gotoToday|gotoCurrent|_promptClass|_clearDate|mandatory|startDate|_setDate|pattern|getDaysInMonth|_getDefaultDate|log|parseDate|_setDateFromField|formatName|formatNumber|getName|at|origSize|_mainDivId|_dialogClass|_tidyDialog|hide|showOptions|hidden|_findPos|opera|clientHeight|clientWidth|dims|show|display|toLowerCase|chr|keyCode|_doKeyPress|keydown|_appendClass|_newInst|regional|_checkExternalClick|_attachDatepicker|concat|_|prototype|Array|toString|constructor|isArray||in|curMonth|curYear|_getFirstDayOfMonth|checkRange|minMax|numberOfMonths|onChangeMonthYear|yearStatus|onchange|split|yearRange|changeYear|inMaxYear|inMinYear|monthStatus|changeMonth|_generateMonthYearHeader|version|initStatus|table|tbody|getUTCDate|setUTCDate|numRows|isMultiMonth|thead|_changeFirstDay|replace|indexOf|weekHeader|statusForDate|currentStatus|nextStatus|prevStatus|closeText|closeStatus|clearText|clearStatus|_generateDatepicker|offsetNumeric|offsetString|exec|catch|try|_possibleChars|getYear|Invalid|iInit|_updateAlternate|change|parents|100px|innerHeight|innerWidth|_checkOffset|Class|add|empty|none|fixed|_isDisabledDatepicker|charCode|map|cursor|opacity|keypress|dateText|_dialogInst|dp|getData|setData|_inlineDatepicker|after|before|alt|attr|buttonImageOnly|_connectDatepicker|debug|Select|different|May|Close|mousedown|ready|isDisabled|call|slice|fn|safari|setMilliseconds|setSeconds|setMinutes|setHours|header|javascript|ceil|cellspacing|cellpadding|one|links|9999|close|control|0123456789|W3C|TIMESTAMP|RSS|RFC_2822|RFC_1123|RFC_1036|RFC_850|RFC_822|ISO_8601|COOKIE|ATOM|Unexpected|Unknown|Missing|86400000|floor|getTimezoneOffset|noWeekends|selectedIndex|unblockUI|fadeOut|fadeIn|slideUp|slideDown|nextSibling|nodeType|rtl|multi|find|static|offsetWidth|1000px|block|offsetHeight|parentNode|fromCharCode|String|stopPropagation|preventDefault|_getDateDatepicker|_setDateDatepicker|_changeDatepicker|_disableDatepicker|_enableDatepicker|removeData|_destroyDatepicker|150|pageY|pageX|_dialogDatepicker|_inlineShow|click|err|eval|getAttribute|setDefaults|console|hasDatepicker|normal|first|as|Set|Sa|Fr|Th|We|Tu|Mo|Su|Sat|Fri|Thu|Wed|Tue|Mon|Sun|Saturday|Friday|Thursday|Wednesday|Tuesday|Monday|Sunday|of|Week|weekStatus|Wk|Dec|Nov|Oct|Sep|Aug|Jul|Jun|Apr|Mar|Feb|Jan|December|November|October|September|August|July|June|April|March|February|January|Today|x3e|Next|previous|Prev|x3c|without|Erase|Clear|dialog'.split('|'),0,{}))
+
Index: /tags/2.0.2/template-common/lib/ui/ui.dialog.js
===================================================================
--- /tags/2.0.2/template-common/lib/ui/ui.dialog.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/ui.dialog.js	(revision 3278)
@@ -0,0 +1,497 @@
+/*
+ * jQuery UI Dialog
+ *
+ * Copyright (c) 2008 Richard D. Worth (rdworth.org)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ * 
+ * http://docs.jquery.com/UI/Dialog
+ *
+ * Depends:
+ *	ui.core.js
+ *	ui.draggable.js
+ *	ui.resizable.js
+ */
+(function($) {
+
+var setDataSwitch = {
+	dragStart: "start.draggable",
+	drag: "drag.draggable",
+	dragStop: "stop.draggable",
+	maxHeight: "maxHeight.resizable",
+	minHeight: "minHeight.resizable",
+	maxWidth: "maxWidth.resizable",
+	minWidth: "minWidth.resizable",
+	resizeStart: "start.resizable",
+	resize: "drag.resizable",
+	resizeStop: "stop.resizable"
+};
+
+$.widget("ui.dialog", {
+	init: function() {
+		var self = this,
+			options = this.options,
+			resizeHandles = typeof options.resizable == 'string'
+				? options.resizable
+				: 'n,e,s,w,se,sw,ne,nw',
+			
+			uiDialogContent = this.element
+				.addClass('ui-dialog-content')
+				.wrap('<div/>')
+				.wrap('<div/>'),
+			
+			uiDialogContainer = (this.uiDialogContainer = uiDialogContent.parent()
+				.addClass('ui-dialog-container')
+				.css({position: 'relative', width: '100%', height: '100%'})),
+			
+			title = options.title || uiDialogContent.attr('title') || '',
+			uiDialogTitlebar = (this.uiDialogTitlebar =
+				$('<div class="ui-dialog-titlebar"/>'))
+				.append('<span class="ui-dialog-title">' + title + '</span>')
+				.append('<a href="#" class="ui-dialog-titlebar-close"><span>X</span></a>')
+				.prependTo(uiDialogContainer),
+			
+			uiDialog = (this.uiDialog = uiDialogContainer.parent())
+				.appendTo(document.body)
+				.hide()
+				.addClass('ui-dialog')
+				.addClass(options.dialogClass)
+				// add content classes to dialog
+				// to inherit theme at top level of element
+				.addClass(uiDialogContent.attr('className'))
+					.removeClass('ui-dialog-content')
+				.css({
+					position: 'absolute',
+					width: options.width,
+					height: options.height,
+					overflow: 'hidden',
+					zIndex: options.zIndex
+				})
+				// setting tabIndex makes the div focusable
+				// setting outline to 0 prevents a border on focus in Mozilla
+				.attr('tabIndex', -1).css('outline', 0).keydown(function(ev) {
+					if (options.closeOnEscape) {
+						var ESC = 27;
+						(ev.keyCode && ev.keyCode == ESC && self.close());
+					}
+				})
+				.mousedown(function() {
+					self.moveToTop();
+				}),
+			
+			uiDialogButtonPane = (this.uiDialogButtonPane = $('<div/>'))
+				.addClass('ui-dialog-buttonpane').css({ position: 'absolute', bottom: 0 })
+				.appendTo(uiDialog);
+		
+		this.uiDialogTitlebarClose = $('.ui-dialog-titlebar-close', uiDialogTitlebar)
+			.hover(
+				function() {
+					$(this).addClass('ui-dialog-titlebar-close-hover');
+				},
+				function() {
+					$(this).removeClass('ui-dialog-titlebar-close-hover');
+				}
+			)
+			.mousedown(function(ev) {
+				ev.stopPropagation();
+			})
+			.click(function() {
+				self.close();
+				return false;
+			});
+
+		this.uiDialogTitlebar.find("*").add(this.uiDialogTitlebar).each(function() {
+			$.ui.disableSelection(this);
+		});
+
+		if ($.fn.draggable) {
+			uiDialog.draggable({
+				cancel: '.ui-dialog-content',
+				helper: options.dragHelper,
+				handle: '.ui-dialog-titlebar',
+				start: function(e, ui) {
+					self.moveToTop();
+					(options.dragStart && options.dragStart.apply(self.element[0], arguments));
+				},
+				drag: function(e, ui) {
+					(options.drag && options.drag.apply(self.element[0], arguments));
+				},
+				stop: function(e, ui) {
+					(options.dragStop && options.dragStop.apply(self.element[0], arguments));
+					$.ui.dialog.overlay.resize();
+				}
+			});
+			(options.draggable || uiDialog.draggable('disable'));
+		}
+		
+		if ($.fn.resizable) {
+			uiDialog.resizable({
+				cancel: '.ui-dialog-content',
+				helper: options.resizeHelper,
+				maxWidth: options.maxWidth,
+				maxHeight: options.maxHeight,
+				minWidth: options.minWidth,
+				minHeight: options.minHeight,
+				start: function() {
+					(options.resizeStart && options.resizeStart.apply(self.element[0], arguments));
+				},
+				resize: function(e, ui) {
+					(options.autoResize && self.size.apply(self));
+					(options.resize && options.resize.apply(self.element[0], arguments));
+				},
+				handles: resizeHandles,
+				stop: function(e, ui) {
+					(options.autoResize && self.size.apply(self));
+					(options.resizeStop && options.resizeStop.apply(self.element[0], arguments));
+					$.ui.dialog.overlay.resize();
+				}
+			});
+			(options.resizable || uiDialog.resizable('disable'));
+		}
+		
+		this.createButtons(options.buttons);
+		this.isOpen = false;
+		
+		(options.bgiframe && $.fn.bgiframe && uiDialog.bgiframe());
+		(options.autoOpen && this.open());
+	},
+	
+	setData: function(key, value){
+		(setDataSwitch[key] && this.uiDialog.data(setDataSwitch[key], value));
+		switch (key) {
+			case "buttons":
+				this.createButtons(value);
+				break;
+			case "draggable":
+				this.uiDialog.draggable(value ? 'enable' : 'disable');
+				break;
+			case "height":
+				this.uiDialog.height(value);
+				break;
+			case "position":
+				this.position(value);
+				break;
+			case "resizable":
+				(typeof value == 'string' && this.uiDialog.data('handles.resizable', value));
+				this.uiDialog.resizable(value ? 'enable' : 'disable');
+				break;
+			case "title":
+				$(".ui-dialog-title", this.uiDialogTitlebar).text(value);
+				break;
+			case "width":
+				this.uiDialog.width(value);
+				break;
+		}
+		
+		$.widget.prototype.setData.apply(this, arguments);
+	},
+	
+	position: function(pos) {
+		var wnd = $(window), doc = $(document),
+			pTop = doc.scrollTop(), pLeft = doc.scrollLeft(),
+			minTop = pTop;
+		
+		if ($.inArray(pos, ['center','top','right','bottom','left']) >= 0) {
+			pos = [
+				pos == 'right' || pos == 'left' ? pos : 'center',
+				pos == 'top' || pos == 'bottom' ? pos : 'middle'
+			];
+		}
+		if (pos.constructor != Array) {
+			pos = ['center', 'middle'];
+		}
+		if (pos[0].constructor == Number) {
+			pLeft += pos[0];
+		} else {
+			switch (pos[0]) {
+				case 'left':
+					pLeft += 0;
+					break;
+				case 'right':
+					pLeft += wnd.width() - this.uiDialog.width();
+					break;
+				default:
+				case 'center':
+					pLeft += (wnd.width() - this.uiDialog.width()) / 2;
+			}
+		}
+		if (pos[1].constructor == Number) {
+			pTop += pos[1];
+		} else {
+			switch (pos[1]) {
+				case 'top':
+					pTop += 0;
+					break;
+				case 'bottom':
+					pTop += wnd.height() - this.uiDialog.height();
+					break;
+				default:
+				case 'middle':
+					pTop += (wnd.height() - this.uiDialog.height()) / 2;
+			}
+		}
+		
+		// prevent the dialog from being too high (make sure the titlebar
+		// is accessible)
+		pTop = Math.max(pTop, minTop);
+		this.uiDialog.css({top: pTop, left: pLeft});
+	},
+
+	size: function() {
+		var container = this.uiDialogContainer,
+			titlebar = this.uiDialogTitlebar,
+			content = this.element,
+			tbMargin = parseInt(content.css('margin-top'),10) + parseInt(content.css('margin-bottom'),10),
+			lrMargin = parseInt(content.css('margin-left'),10) + parseInt(content.css('margin-right'),10);
+		content.height(container.height() - titlebar.outerHeight() - tbMargin);
+		content.width(container.width() - lrMargin);
+	},
+	
+	open: function() {
+		if (this.isOpen) { return; }
+		
+		this.overlay = this.options.modal ? new $.ui.dialog.overlay(this) : null;
+		(this.uiDialog.next().length > 0) && this.uiDialog.appendTo('body');
+		this.position(this.options.position);
+		this.uiDialog.show(this.options.show);
+		this.options.autoResize && this.size();
+		this.moveToTop(true);
+		
+		// CALLBACK: open
+		var openEV = null;
+		var openUI = {
+			options: this.options
+		};
+		this.uiDialogTitlebarClose.focus();
+		this.element.triggerHandler("dialogopen", [openEV, openUI], this.options.open);
+		
+		this.isOpen = true;
+	},
+	
+	// the force parameter allows us to move modal dialogs to their correct
+	// position on open
+	moveToTop: function(force) {
+		if ((this.options.modal && !force)
+			|| (!this.options.stack && !this.options.modal)) { return this.element.triggerHandler("dialogfocus", [null, { options: this.options }], this.options.focus); }
+		
+		var maxZ = this.options.zIndex, options = this.options;
+		$('.ui-dialog:visible').each(function() {
+			maxZ = Math.max(maxZ, parseInt($(this).css('z-index'), 10) || options.zIndex);
+		});
+		(this.overlay && this.overlay.$el.css('z-index', ++maxZ));
+		this.uiDialog.css('z-index', ++maxZ);
+		
+		this.element.triggerHandler("dialogfocus", [null, { options: this.options }], this.options.focus);
+	},
+	
+	close: function() {
+		(this.overlay && this.overlay.destroy());
+		this.uiDialog.hide(this.options.hide);
+
+		// CALLBACK: close
+		var closeEV = null;
+		var closeUI = {
+			options: this.options
+		};
+		this.element.triggerHandler("dialogclose", [closeEV, closeUI], this.options.close);
+		$.ui.dialog.overlay.resize();
+		
+		this.isOpen = false;
+	},
+	
+	destroy: function() {
+		(this.overlay && this.overlay.destroy());
+		this.uiDialog.hide();
+		this.element
+			.unbind('.dialog')
+			.removeData('dialog')
+			.removeClass('ui-dialog-content')
+			.hide().appendTo('body');
+		this.uiDialog.remove();
+	},
+	
+	createButtons: function(buttons) {
+		var self = this,
+			hasButtons = false,
+			uiDialogButtonPane = this.uiDialogButtonPane;
+		
+		// remove any existing buttons
+		uiDialogButtonPane.empty().hide();
+		
+		$.each(buttons, function() { return !(hasButtons = true); });
+		if (hasButtons) {
+			uiDialogButtonPane.show();
+			$.each(buttons, function(name, fn) {
+				$('<button/>')
+					.text(name)
+					.click(function() { fn.apply(self.element[0], arguments); })
+					.appendTo(uiDialogButtonPane);
+			});
+		}
+	}
+});
+
+$.extend($.ui.dialog, {
+	defaults: {
+		autoOpen: true,
+		autoResize: true,
+		bgiframe: false,
+		buttons: {},
+		closeOnEscape: true,
+		draggable: true,
+		height: 200,
+		minHeight: 100,
+		minWidth: 150,
+		modal: false,
+		overlay: {},
+		position: 'center',
+		resizable: true,
+		stack: true,
+		width: 300,
+		zIndex: 1000
+	},
+	
+	overlay: function(dialog) {
+		this.$el = $.ui.dialog.overlay.create(dialog);
+	}
+});
+
+$.extend($.ui.dialog.overlay, {
+	instances: [],
+	events: $.map('focus,mousedown,mouseup,keydown,keypress,click'.split(','),
+		function(e) { return e + '.dialog-overlay'; }).join(' '),
+	create: function(dialog) {
+		if (this.instances.length === 0) {
+			// prevent use of anchors and inputs
+			// we use a setTimeout in case the overlay is created from an
+			// event that we're going to be cancelling (see #2804)
+			setTimeout(function() {
+				$('a, :input').bind($.ui.dialog.overlay.events, function() {
+					// allow use of the element if inside a dialog and
+					// - there are no modal dialogs
+					// - there are modal dialogs, but we are in front of the topmost modal
+					var allow = false;
+					var $dialog = $(this).parents('.ui-dialog');
+					if ($dialog.length) {
+						var $overlays = $('.ui-dialog-overlay');
+						if ($overlays.length) {
+							var maxZ = parseInt($overlays.css('z-index'), 10);
+							$overlays.each(function() {
+								maxZ = Math.max(maxZ, parseInt($(this).css('z-index'), 10));
+							});
+							allow = parseInt($dialog.css('z-index'), 10) > maxZ;
+						} else {
+							allow = true;
+						}
+					}
+					return allow;
+				});
+			}, 1);
+			
+			// allow closing by pressing the escape key
+			$(document).bind('keydown.dialog-overlay', function(e) {
+				var ESC = 27;
+				(e.keyCode && e.keyCode == ESC && dialog.close()); 
+			});
+			
+			// handle window resize
+			$(window).bind('resize.dialog-overlay', $.ui.dialog.overlay.resize);
+		}
+		
+		var $el = $('<div/>').appendTo(document.body)
+			.addClass('ui-dialog-overlay').css($.extend({
+				borderWidth: 0, margin: 0, padding: 0,
+				position: 'absolute', top: 0, left: 0,
+				width: this.width(),
+				height: this.height()
+			}, dialog.options.overlay));
+		
+		(dialog.options.bgiframe && $.fn.bgiframe && $el.bgiframe());
+		
+		this.instances.push($el);
+		return $el;
+	},
+	
+	destroy: function($el) {
+		this.instances.splice($.inArray(this.instances, $el), 1);
+		
+		if (this.instances.length === 0) {
+			$('a, :input').add([document, window]).unbind('.dialog-overlay');
+		}
+		
+		$el.remove();
+	},
+	
+	height: function() {
+		if ($.browser.msie && $.browser.version < 7) {
+			var scrollHeight = Math.max(
+				document.documentElement.scrollHeight,
+				document.body.scrollHeight
+			);
+			var offsetHeight = Math.max(
+				document.documentElement.offsetHeight,
+				document.body.offsetHeight
+			);
+			
+			if (scrollHeight < offsetHeight) {
+				return $(window).height() + 'px';
+			} else {
+				return scrollHeight + 'px';
+			}
+		} else {
+			return $(document).height() + 'px';
+		}
+	},
+	
+	width: function() {
+		if ($.browser.msie && $.browser.version < 7) {
+			var scrollWidth = Math.max(
+				document.documentElement.scrollWidth,
+				document.body.scrollWidth
+			);
+			var offsetWidth = Math.max(
+				document.documentElement.offsetWidth,
+				document.body.offsetWidth
+			);
+			
+			if (scrollWidth < offsetWidth) {
+				return $(window).width() + 'px';
+			} else {
+				return scrollWidth + 'px';
+			}
+		} else {
+			return $(document).width() + 'px';
+		}
+	},
+	
+	resize: function() {
+		/* If the dialog is draggable and the user drags it past the
+		 * right edge of the window, the document becomes wider so we
+		 * need to stretch the overlay. If the user then drags the
+		 * dialog back to the left, the document will become narrower,
+		 * so we need to shrink the overlay to the appropriate size.
+		 * This is handled by shrinking the overlay before setting it
+		 * to the full document size.
+		 */
+		var $overlays = $([]);
+		$.each($.ui.dialog.overlay.instances, function() {
+			$overlays = $overlays.add(this);
+		});
+		
+		$overlays.css({
+			width: 0,
+			height: 0
+		}).css({
+			width: $.ui.dialog.overlay.width(),
+			height: $.ui.dialog.overlay.height()
+		});
+	}
+});
+
+$.extend($.ui.dialog.overlay.prototype, {
+	destroy: function() {
+		$.ui.dialog.overlay.destroy(this.$el);
+	}
+});
+
+})(jQuery);
Index: /tags/2.0.2/template-common/lib/ui/ui.dialog.packed.js
===================================================================
--- /tags/2.0.2/template-common/lib/ui/ui.dialog.packed.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/ui.dialog.packed.js	(revision 3278)
@@ -0,0 +1,2 @@
+eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)d[e(c)]=k[c]||e(c);k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(5(B){b A={1W:"1z.t",15:"15.t",1V:"1y.t",1A:"1A.i",1e:"1e.i",1B:"1B.i",1d:"1d.i",1U:"1z.i",p:"15.i",1T:"1y.i"};B.2p("6.4",{3o:5(){b J=3,K=3.9,D=2u K.i=="2t"?K.i:"n,e,s,w,3n,3m,3l,3k",E=3.k.y("6-4-1f").2z("<1a/>").2z("<1a/>"),G=(3.2l=E.2x().y("6-4-3j").g({q:"3i",d:"1K%",c:"1K%"})),H=K.1j||E.1Y("1j")||"",C=(3.1i=B(\'<1a 1Z="6-4-16"/>\')).2y(\'<1C 1Z="6-4-1j">\'+H+"</1C>").2y(\'<a 3h="#" 1Z="6-4-16-v"><1C>X</1C></a>\').3g(G),I=(3.f=G.2x()).12(j.x).14().y("6-4").y(K.3f).y(E.1Y("3e")).1O("6-4-1f").g({q:"1F",d:K.d,c:K.c,3d:"3c",1b:K.1b}).1Y("3b",-1).g("3a",0).1H(5(L){h(K.2f){b M=27;(L.1o&&L.1o==M&&J.v())}}).1J(5(){J.1u()}),F=(3.2i=B("<1a/>")).y("6-4-39").g({q:"1F",1h:0}).12(I);3.2k=B(".6-4-16-v",C).1X(5(){B(3).y("6-4-16-v-1X")},5(){B(3).1O("6-4-16-v-1X")}).1J(5(L){L.38()}).1I(5(){J.v();l U});3.1i.37("*").1E(3.1i).W(5(){B.6.36(3)});h(B.1n.t){I.t({2w:".6-4-1f",2v:K.35,34:".6-4-16",1z:5(M,L){J.1u();(K.1W&&K.1W.u(J.k[0],O))},15:5(M,L){(K.15&&K.15.u(J.k[0],O))},1y:5(M,L){(K.1V&&K.1V.u(J.k[0],O));B.6.4.8.p()}});(K.t||I.t("1x"))}h(B.1n.i){I.i({2w:".6-4-1f",2v:K.33,1B:K.1B,1A:K.1A,1d:K.1d,1e:K.1e,1z:5(){(K.1U&&K.1U.u(J.k[0],O))},p:5(M,L){(K.1r&&J.1v.u(J));(K.p&&K.p.u(J.k[0],O))},2r:D,1y:5(M,L){(K.1r&&J.1v.u(J));(K.1T&&K.1T.u(J.k[0],O));B.6.4.8.p()}});(K.i||I.i("1x"))}3.1N(K.1L);3.1s=U;(K.T&&B.1n.T&&I.T());(K.2g&&3.1P())},2o:5(C,D){(A[C]&&3.f.2s(A[C],D));1R(C){m"1L":3.1N(D);o;m"t":3.f.t(D?"2q":"1x");o;m"c":3.f.c(D);o;m"q":3.q(D);o;m"i":(2u D=="2t"&&3.f.2s("2r.i",D));3.f.i(D?"2q":"1x");o;m"1j":B(".6-4-1j",3.1i).2h(D);o;m"d":3.f.d(D);o}B.2p.20.2o.u(3,O)},q:5(H){b D=B(17),E=B(j),F=E.32(),C=E.31(),G=F;h(B.2b(H,["1c","11","1w","1h","Z"])>=0){H=[H=="1w"||H=="Z"?H:"1c",H=="11"||H=="1h"?H:"1Q"]}h(H.1S!=30){H=["1c","1Q"]}h(H[0].1S==2n){C+=H[0]}Q{1R(H[0]){m"Z":C+=0;o;m"1w":C+=D.d()-3.f.d();o;2m:m"1c":C+=(D.d()-3.f.d())/2}}h(H[1].1S==2n){F+=H[1]}Q{1R(H[1]){m"11":F+=0;o;m"1h":F+=D.c()-3.f.c();o;2m:m"1Q":F+=(D.c()-3.f.c())/2}}F=S.R(F,G);3.f.g({11:F,Z:C})},1v:5(){b D=3.2l,G=3.1i,E=3.k,F=N(E.g("19-11"),10)+N(E.g("19-1h"),10),C=N(E.g("19-Z"),10)+N(E.g("19-1w"),10);E.c(D.c()-G.2Z()-F);E.d(D.d()-C)},1P:5(){h(3.1s){l}3.8=3.9.1q?2Y B.6.4.8(3):1g;(3.f.2X().18>0)&&3.f.12("x");3.q(3.9.q);3.f.1M(3.9.1M);3.9.1r&&3.1v();3.1u(r);b C=1g;b D={9:3.9};3.2k.1p();3.k.1t("2W",[C,D],3.9.1P);3.1s=r},1u:5(E){h((3.9.1q&&!E)||(!3.9.2e&&!3.9.1q)){l 3.k.1t("2j",[1g,{9:3.9}],3.9.1p)}b D=3.9.1b,C=3.9;B(".6-4:2V").W(5(){D=S.R(D,N(B(3).g("z-13"),10)||C.1b)});(3.8&&3.8.$1D.g("z-13",++D));3.f.g("z-13",++D);3.k.1t("2j",[1g,{9:3.9}],3.9.1p)},v:5(){(3.8&&3.8.V());3.f.14(3.9.14);b D=1g;b C={9:3.9};3.k.1t("2U",[D,C],3.9.v);B.6.4.8.p();3.1s=U},V:5(){(3.8&&3.8.V());3.f.14();3.k.29(".4").2T("4").1O("6-4-1f").14().12("x");3.f.28()},1N:5(F){b E=3,C=U,D=3.2i;D.2S().14();B.W(F,5(){l!(C=r)});h(C){D.1M();B.W(F,5(G,H){B("<2R/>").2h(G).1I(5(){H.u(E.k[0],O)}).12(D)})}}});B.1k(B.6.4,{2Q:{2g:r,1r:r,T:U,1L:{},2f:r,t:r,c:2P,1e:1K,1d:2O,1q:U,8:{},q:"1c",i:r,2e:r,d:2N,1b:2M},8:5(C){3.$1D=B.6.4.8.2d(C)}});B.1k(B.6.4.8,{P:[],2c:B.2L("1p,1J,2K,1H,2J,1I".2I(","),5(C){l C+".4-8"}).2H(" "),2d:5(D){h(3.P.18===0){2G(5(){B("a, :2a").1G(B.6.4.8.2c,5(){b F=U;b H=B(3).2F(".6-4");h(H.18){b E=B(".6-4-8");h(E.18){b G=N(E.g("z-13"),10);E.W(5(){G=S.R(G,N(B(3).g("z-13"),10))});F=N(H.g("z-13"),10)>G}Q{F=r}}l F})},1);B(j).1G("1H.4-8",5(E){b F=27;(E.1o&&E.1o==F&&D.v())});B(17).1G("p.4-8",B.6.4.8.p)}b C=B("<1a/>").12(j.x).y("6-4-8").g(B.1k({2E:0,19:0,2D:0,q:"1F",11:0,Z:0,d:3.d(),c:3.c()},D.9.8));(D.9.T&&B.1n.T&&C.T());3.P.2C(C);l C},V:5(C){3.P.2B(B.2b(3.P,C),1);h(3.P.18===0){B("a, :2a").1E([j,17]).29(".4-8")}C.28()},c:5(){h(B.1m.24&&B.1m.23<7){b D=S.R(j.1l.26,j.x.26);b C=S.R(j.1l.25,j.x.25);h(D<C){l B(17).c()+"Y"}Q{l D+"Y"}}Q{l B(j).c()+"Y"}},d:5(){h(B.1m.24&&B.1m.23<7){b C=S.R(j.1l.22,j.x.22);b D=S.R(j.1l.21,j.x.21);h(C<D){l B(17).d()+"Y"}Q{l C+"Y"}}Q{l B(j).d()+"Y"}},p:5(){b C=B([]);B.W(B.6.4.8.P,5(){C=C.1E(3)});C.g({d:0,c:0}).g({d:B.6.4.8.d(),c:B.6.4.8.c()})}});B.1k(B.6.4.8.20,{V:5(){B.6.4.8.V(3.$1D)}})})(2A)',62,211,'|||this|dialog|function|ui||overlay|options||var|height|width||uiDialog|css|if|resizable|document|element|return|case||break|resize|position|true||draggable|apply|close||body|addClass|||||||||||||||parseInt|arguments|instances|else|max|Math|bgiframe|false|destroy|each||px|left||top|appendTo|index|hide|drag|titlebar|window|length|margin|div|zIndex|center|minWidth|minHeight|content|null|bottom|uiDialogTitlebar|title|extend|documentElement|browser|fn|keyCode|focus|modal|autoResize|isOpen|triggerHandler|moveToTop|size|right|disable|stop|start|maxHeight|maxWidth|span|el|add|absolute|bind|keydown|click|mousedown|100|buttons|show|createButtons|removeClass|open|middle|switch|constructor|resizeStop|resizeStart|dragStop|dragStart|hover|attr|class|prototype|offsetWidth|scrollWidth|version|msie|offsetHeight|scrollHeight||remove|unbind|input|inArray|events|create|stack|closeOnEscape|autoOpen|text|uiDialogButtonPane|dialogfocus|uiDialogTitlebarClose|uiDialogContainer|default|Number|setData|widget|enable|handles|data|string|typeof|helper|cancel|parent|append|wrap|jQuery|splice|push|padding|borderWidth|parents|setTimeout|join|split|keypress|mouseup|map|1000|300|150|200|defaults|button|empty|removeData|dialogclose|visible|dialogopen|next|new|outerHeight|Array|scrollLeft|scrollTop|resizeHelper|handle|dragHelper|disableSelection|find|stopPropagation|buttonpane|outline|tabIndex|hidden|overflow|className|dialogClass|prependTo|href|relative|container|nw|ne|sw|se|init'.split('|'),0,{}))
+
Index: /tags/2.0.2/template-common/lib/ui/ui.draggable.js
===================================================================
--- /tags/2.0.2/template-common/lib/ui/ui.draggable.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/ui.draggable.js	(revision 3278)
@@ -0,0 +1,562 @@
+/*
+ * jQuery UI Draggable
+ *
+ * Copyright (c) 2008 Paul Bakaus
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ * 
+ * http://docs.jquery.com/UI/Draggables
+ *
+ * Depends:
+ *	ui.core.js
+ */
+(function($) {
+
+$.widget("ui.draggable", $.extend({}, $.ui.mouse, {
+	init: function() {
+		
+		//Initialize needed constants
+		var o = this.options;
+
+		//Position the node
+		if (o.helper == 'original' && !(/(relative|absolute|fixed)/).test(this.element.css('position')))
+			this.element.css('position', 'relative');
+
+		this.element.addClass('ui-draggable');
+		(o.disabled && this.element.addClass('ui-draggable-disabled'));
+		
+		this.mouseInit();
+		
+	},
+	mouseStart: function(e) {
+		var o = this.options;
+		
+		if (this.helper || o.disabled || $(e.target).is('.ui-resizable-handle')) return false;
+		
+		var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false;
+		
+	
+		$(this.options.handle, this.element).find("*").andSelf().each(function() {
+			if(this == e.target) handle = true;
+		});
+		if (!handle) return false;
+		
+		if($.ui.ddmanager) $.ui.ddmanager.current = this;
+		
+		//Create and append the visible helper
+		this.helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [e])) : (o.helper == 'clone' ? this.element.clone() : this.element);
+		if(!this.helper.parents('body').length) this.helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo));
+		if(this.helper[0] != this.element[0] && !(/(fixed|absolute)/).test(this.helper.css("position"))) this.helper.css("position", "absolute");
+		
+		/*
+		 * - Position generation -
+		 * This block generates everything position related - it's the core of draggables.
+		 */
+		
+		this.margins = {																				//Cache the margins
+			left: (parseInt(this.element.css("marginLeft"),10) || 0),
+			top: (parseInt(this.element.css("marginTop"),10) || 0)
+		};		
+		
+		this.cssPosition = this.helper.css("position");													//Store the helper's css position
+		this.offset = this.element.offset();															//The element's absolute position on the page
+		this.offset = {																					//Substract the margins from the element's absolute offset
+			top: this.offset.top - this.margins.top,
+			left: this.offset.left - this.margins.left
+		};
+		
+		this.offset.click = {																			//Where the click happened, relative to the element
+			left: e.pageX - this.offset.left,
+			top: e.pageY - this.offset.top
+		};
+		
+		this.offsetParent = this.helper.offsetParent(); var po = this.offsetParent.offset();			//Get the offsetParent and cache its position
+		if(this.offsetParent[0] == document.body && $.browser.mozilla) po = { top: 0, left: 0 };		//Ugly FF3 fix
+		this.offset.parent = {																			//Store its position plus border
+			top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
+			left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
+		};
+		
+		var p = this.element.position();																//This is a relative to absolute position minus the actual position calculation - only used for relative positioned helpers
+		this.offset.relative = this.cssPosition == "relative" ? {
+			top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.offsetParent[0].scrollTop,
+			left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.offsetParent[0].scrollLeft
+		} : { top: 0, left: 0 };
+		
+		this.originalPosition = this.generatePosition(e);												//Generate the original position
+		this.helperProportions = { width: this.helper.outerWidth(), height: this.helper.outerHeight() };//Cache the helper size
+		
+		if(o.cursorAt) {
+			if(o.cursorAt.left != undefined) this.offset.click.left = o.cursorAt.left + this.margins.left;
+			if(o.cursorAt.right != undefined) this.offset.click.left = this.helperProportions.width - o.cursorAt.right + this.margins.left;
+			if(o.cursorAt.top != undefined) this.offset.click.top = o.cursorAt.top + this.margins.top;
+			if(o.cursorAt.bottom != undefined) this.offset.click.top = this.helperProportions.height - o.cursorAt.bottom + this.margins.top;
+		}
+		
+		
+		/*
+		 * - Position constraining -
+		 * Here we prepare position constraining like grid and containment.
+		 */	
+		
+		if(o.containment) {
+			if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
+			if(o.containment == 'document' || o.containment == 'window') this.containment = [
+				0 - this.offset.relative.left - this.offset.parent.left,
+				0 - this.offset.relative.top - this.offset.parent.top,
+				$(o.containment == 'document' ? document : window).width() - this.offset.relative.left - this.offset.parent.left - this.helperProportions.width - this.margins.left - (parseInt(this.element.css("marginRight"),10) || 0),
+				($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.offset.relative.top - this.offset.parent.top - this.helperProportions.height - this.margins.top - (parseInt(this.element.css("marginBottom"),10) || 0)
+			];
+			
+			if(!(/^(document|window|parent)$/).test(o.containment)) {
+				var ce = $(o.containment)[0];
+				var co = $(o.containment).offset();
+				
+				this.containment = [
+					co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) - this.offset.relative.left - this.offset.parent.left,
+					co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) - this.offset.relative.top - this.offset.parent.top,
+					co.left+Math.max(ce.scrollWidth,ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - this.offset.relative.left - this.offset.parent.left - this.helperProportions.width - this.margins.left - (parseInt(this.element.css("marginRight"),10) || 0),
+					co.top+Math.max(ce.scrollHeight,ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - this.offset.relative.top - this.offset.parent.top - this.helperProportions.height - this.margins.top - (parseInt(this.element.css("marginBottom"),10) || 0)
+				];
+			}
+		}
+		
+		//Call plugins and callbacks
+		this.propagate("start", e);
+		
+		this.helperProportions = { width: this.helper.outerWidth(), height: this.helper.outerHeight() };//Recache the helper size
+		if ($.ui.ddmanager && !o.dropBehaviour) $.ui.ddmanager.prepareOffsets(this, e);
+		
+		this.helper.addClass("ui-draggable-dragging");
+		this.mouseDrag(e); //Execute the drag once - this causes the helper not to be visible before getting its correct position
+		return true;
+	},
+	convertPositionTo: function(d, pos) {
+		if(!pos) pos = this.position;
+		var mod = d == "absolute" ? 1 : -1;
+		return {
+			top: (
+				pos.top																	// the calculated relative position
+				+ this.offset.relative.top	* mod										// Only for relative positioned nodes: Relative offset from element to offset parent
+				+ this.offset.parent.top * mod											// The offsetParent's offset without borders (offset + border)
+				- (this.cssPosition == "fixed" || (this.cssPosition == "absolute" && this.offsetParent[0] == document.body) ? 0 : this.offsetParent[0].scrollTop) * mod	// The offsetParent's scroll position, not if the element is fixed
+				+ (this.cssPosition == "fixed" ? $(document).scrollTop() : 0) * mod
+				+ this.margins.top * mod												//Add the margin (you don't want the margin counting in intersection methods)
+			),
+			left: (
+				pos.left																// the calculated relative position
+				+ this.offset.relative.left	* mod										// Only for relative positioned nodes: Relative offset from element to offset parent
+				+ this.offset.parent.left * mod											// The offsetParent's offset without borders (offset + border)
+				- (this.cssPosition == "fixed" || (this.cssPosition == "absolute" && this.offsetParent[0] == document.body) ? 0 : this.offsetParent[0].scrollLeft) * mod	// The offsetParent's scroll position, not if the element is fixed
+				+ (this.cssPosition == "fixed" ? $(document).scrollLeft() : 0) * mod
+				+ this.margins.left * mod												//Add the margin (you don't want the margin counting in intersection methods)
+			)
+		};
+	},
+	generatePosition: function(e) {
+		
+		var o = this.options;
+		var position = {
+			top: (
+				e.pageY																	// The absolute mouse position
+				- this.offset.click.top													// Click offset (relative to the element)
+				- this.offset.relative.top												// Only for relative positioned nodes: Relative offset from element to offset parent
+				- this.offset.parent.top												// The offsetParent's offset without borders (offset + border)
+				+ (this.cssPosition == "fixed" || (this.cssPosition == "absolute" && this.offsetParent[0] == document.body) ? 0 : this.offsetParent[0].scrollTop)	// The offsetParent's scroll position, not if the element is fixed
+				- (this.cssPosition == "fixed" ? $(document).scrollTop() : 0)
+			),
+			left: (
+				e.pageX																	// The absolute mouse position
+				- this.offset.click.left												// Click offset (relative to the element)
+				- this.offset.relative.left												// Only for relative positioned nodes: Relative offset from element to offset parent
+				- this.offset.parent.left												// The offsetParent's offset without borders (offset + border)
+				+ (this.cssPosition == "fixed" || (this.cssPosition == "absolute" && this.offsetParent[0] == document.body) ? 0 : this.offsetParent[0].scrollLeft)	// The offsetParent's scroll position, not if the element is fixed
+				- (this.cssPosition == "fixed" ? $(document).scrollLeft() : 0)
+			)
+		};
+		
+		if(!this.originalPosition) return position;										//If we are not dragging yet, we won't check for options
+		
+		/*
+		 * - Position constraining -
+		 * Constrain the position to a mix of grid, containment.
+		 */
+		if(this.containment) {
+			if(position.left < this.containment[0]) position.left = this.containment[0];
+			if(position.top < this.containment[1]) position.top = this.containment[1];
+			if(position.left > this.containment[2]) position.left = this.containment[2];
+			if(position.top > this.containment[3]) position.top = this.containment[3];
+		}
+		
+		if(o.grid) {
+			var top = this.originalPosition.top + Math.round((position.top - this.originalPosition.top) / o.grid[1]) * o.grid[1];
+			position.top = this.containment ? (!(top < this.containment[1] || top > this.containment[3]) ? top : (!(top < this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
+			
+			var left = this.originalPosition.left + Math.round((position.left - this.originalPosition.left) / o.grid[0]) * o.grid[0];
+			position.left = this.containment ? (!(left < this.containment[0] || left > this.containment[2]) ? left : (!(left < this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
+		}
+		
+		return position;
+	},
+	mouseDrag: function(e) {
+		
+		//Compute the helpers position
+		this.position = this.generatePosition(e);
+		this.positionAbs = this.convertPositionTo("absolute");
+		
+		//Call plugins and callbacks and use the resulting position if something is returned		
+		this.position = this.propagate("drag", e) || this.position;
+		
+		if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
+		if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
+		if($.ui.ddmanager) $.ui.ddmanager.drag(this, e);
+		
+		return false;
+	},
+	mouseStop: function(e) {
+		
+		//If we are using droppables, inform the manager about the drop
+		var dropped = false;
+		if ($.ui.ddmanager && !this.options.dropBehaviour)
+			var dropped = $.ui.ddmanager.drop(this, e);		
+		
+		if((this.options.revert == "invalid" && !dropped) || (this.options.revert == "valid" && dropped) || this.options.revert === true) {
+			var self = this;
+			$(this.helper).animate(this.originalPosition, parseInt(this.options.revert, 10) || 500, function() {
+				self.propagate("stop", e);
+				self.clear();
+			});
+		} else {
+			this.propagate("stop", e);
+			this.clear();
+		}
+		
+		return false;
+	},
+	clear: function() {
+		this.helper.removeClass("ui-draggable-dragging");
+		if(this.options.helper != 'original' && !this.cancelHelperRemoval) this.helper.remove();
+		//if($.ui.ddmanager) $.ui.ddmanager.current = null;
+		this.helper = null;
+		this.cancelHelperRemoval = false;
+	},
+	
+	// From now on bulk stuff - mainly helpers
+	plugins: {},
+	uiHash: function(e) {
+		return {
+			helper: this.helper,
+			position: this.position,
+			absolutePosition: this.positionAbs,
+			options: this.options			
+		};
+	},
+	propagate: function(n,e) {
+		$.ui.plugin.call(this, n, [e, this.uiHash()]);
+		if(n == "drag") this.positionAbs = this.convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins
+		return this.element.triggerHandler(n == "drag" ? n : "drag"+n, [e, this.uiHash()], this.options[n]);
+	},
+	destroy: function() {
+		if(!this.element.data('draggable')) return;
+		this.element.removeData("draggable").unbind(".draggable").removeClass('ui-draggable');
+		this.mouseDestroy();
+	}
+}));
+
+$.extend($.ui.draggable, {
+	defaults: {
+		appendTo: "parent",
+		axis: false,
+		cancel: ":input",
+		delay: 0,
+		distance: 1,
+		helper: "original"
+	}
+});
+
+$.ui.plugin.add("draggable", "cursor", {
+	start: function(e, ui) {
+		var t = $('body');
+		if (t.css("cursor")) ui.options._cursor = t.css("cursor");
+		t.css("cursor", ui.options.cursor);
+	},
+	stop: function(e, ui) {
+		if (ui.options._cursor) $('body').css("cursor", ui.options._cursor);
+	}
+});
+
+$.ui.plugin.add("draggable", "zIndex", {
+	start: function(e, ui) {
+		var t = $(ui.helper);
+		if(t.css("zIndex")) ui.options._zIndex = t.css("zIndex");
+		t.css('zIndex', ui.options.zIndex);
+	},
+	stop: function(e, ui) {
+		if(ui.options._zIndex) $(ui.helper).css('zIndex', ui.options._zIndex);
+	}
+});
+
+$.ui.plugin.add("draggable", "opacity", {
+	start: function(e, ui) {
+		var t = $(ui.helper);
+		if(t.css("opacity")) ui.options._opacity = t.css("opacity");
+		t.css('opacity', ui.options.opacity);
+	},
+	stop: function(e, ui) {
+		if(ui.options._opacity) $(ui.helper).css('opacity', ui.options._opacity);
+	}
+});
+
+$.ui.plugin.add("draggable", "iframeFix", {
+	start: function(e, ui) {
+		$(ui.options.iframeFix === true ? "iframe" : ui.options.iframeFix).each(function() {					
+			$('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>')
+			.css({
+				width: this.offsetWidth+"px", height: this.offsetHeight+"px",
+				position: "absolute", opacity: "0.001", zIndex: 1000
+			})
+			.css($(this).offset())
+			.appendTo("body");
+		});
+	},
+	stop: function(e, ui) {
+		$("div.DragDropIframeFix").each(function() { this.parentNode.removeChild(this); }); //Remove frame helpers	
+	}
+});
+
+$.ui.plugin.add("draggable", "scroll", {
+	start: function(e, ui) {
+		var o = ui.options;
+		var i = $(this).data("draggable");
+		o.scrollSensitivity	= o.scrollSensitivity || 20;
+		o.scrollSpeed		= o.scrollSpeed || 20;
+		
+		i.overflowY = function(el) {
+			do { if(/auto|scroll/.test(el.css('overflow')) || (/auto|scroll/).test(el.css('overflow-y'))) return el; el = el.parent(); } while (el[0].parentNode);
+			return $(document);
+		}(this);
+		i.overflowX = function(el) {
+			do { if(/auto|scroll/.test(el.css('overflow')) || (/auto|scroll/).test(el.css('overflow-x'))) return el; el = el.parent(); } while (el[0].parentNode);
+			return $(document);
+		}(this);
+		
+		if(i.overflowY[0] != document && i.overflowY[0].tagName != 'HTML') i.overflowYOffset = i.overflowY.offset();
+		if(i.overflowX[0] != document && i.overflowX[0].tagName != 'HTML') i.overflowXOffset = i.overflowX.offset();
+		
+	},
+	drag: function(e, ui) {
+		
+		var o = ui.options;
+		var i = $(this).data("draggable");
+		
+		if(i.overflowY[0] != document && i.overflowY[0].tagName != 'HTML') {
+			if((i.overflowYOffset.top + i.overflowY[0].offsetHeight) - e.pageY < o.scrollSensitivity)
+				i.overflowY[0].scrollTop = i.overflowY[0].scrollTop + o.scrollSpeed;
+			if(e.pageY - i.overflowYOffset.top < o.scrollSensitivity)
+				i.overflowY[0].scrollTop = i.overflowY[0].scrollTop - o.scrollSpeed;
+							
+		} else {
+			if(e.pageY - $(document).scrollTop() < o.scrollSensitivity)
+				$(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
+			if($(window).height() - (e.pageY - $(document).scrollTop()) < o.scrollSensitivity)
+				$(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
+		}
+		
+		if(i.overflowX[0] != document && i.overflowX[0].tagName != 'HTML') {
+			if((i.overflowXOffset.left + i.overflowX[0].offsetWidth) - e.pageX < o.scrollSensitivity)
+				i.overflowX[0].scrollLeft = i.overflowX[0].scrollLeft + o.scrollSpeed;
+			if(e.pageX - i.overflowXOffset.left < o.scrollSensitivity)
+				i.overflowX[0].scrollLeft = i.overflowX[0].scrollLeft - o.scrollSpeed;
+		} else {
+			if(e.pageX - $(document).scrollLeft() < o.scrollSensitivity)
+				$(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
+			if($(window).width() - (e.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
+				$(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
+		}
+		
+	}
+});
+
+$.ui.plugin.add("draggable", "snap", {
+	start: function(e, ui) {
+		
+		var inst = $(this).data("draggable");
+		inst.snapElements = [];
+		$(ui.options.snap === true ? '.ui-draggable' : ui.options.snap).each(function() {
+			var $t = $(this); var $o = $t.offset();
+			if(this != inst.element[0]) inst.snapElements.push({
+				item: this,
+				width: $t.outerWidth(), height: $t.outerHeight(),
+				top: $o.top, left: $o.left
+			});
+		});
+		
+	},
+	drag: function(e, ui) {
+		
+		var inst = $(this).data("draggable");
+		var d = ui.options.snapTolerance || 20;
+		var x1 = ui.absolutePosition.left, x2 = x1 + inst.helperProportions.width,
+			y1 = ui.absolutePosition.top, y2 = y1 + inst.helperProportions.height;
+		
+		for (var i = inst.snapElements.length - 1; i >= 0; i--){
+			
+			var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width, 
+				t = inst.snapElements[i].top, b = t + inst.snapElements[i].height;
+			
+			//Yes, I know, this is insane ;)
+			if(!((l-d < x1 && x1 < r+d && t-d < y1 && y1 < b+d) || (l-d < x1 && x1 < r+d && t-d < y2 && y2 < b+d) || (l-d < x2 && x2 < r+d && t-d < y1 && y1 < b+d) || (l-d < x2 && x2 < r+d && t-d < y2 && y2 < b+d))) continue;
+			
+			if(ui.options.snapMode != 'inner') {
+				var ts = Math.abs(t - y2) <= 20;
+				var bs = Math.abs(b - y1) <= 20;
+				var ls = Math.abs(l - x2) <= 20;
+				var rs = Math.abs(r - x1) <= 20;
+				if(ts) ui.position.top = inst.convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top;
+				if(bs) ui.position.top = inst.convertPositionTo("relative", { top: b, left: 0 }).top;
+				if(ls) ui.position.left = inst.convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left;
+				if(rs) ui.position.left = inst.convertPositionTo("relative", { top: 0, left: r }).left;
+			}
+			
+			if(ui.options.snapMode != 'outer') {
+				var ts = Math.abs(t - y1) <= 20;
+				var bs = Math.abs(b - y2) <= 20;
+				var ls = Math.abs(l - x1) <= 20;
+				var rs = Math.abs(r - x2) <= 20;
+				if(ts) ui.position.top = inst.convertPositionTo("relative", { top: t, left: 0 }).top;
+				if(bs) ui.position.top = inst.convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top;
+				if(ls) ui.position.left = inst.convertPositionTo("relative", { top: 0, left: l }).left;
+				if(rs) ui.position.left = inst.convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left;
+			}
+			
+		};
+	}
+});
+
+$.ui.plugin.add("draggable", "connectToSortable", {
+	start: function(e,ui) {
+	
+		var inst = $(this).data("draggable");
+		inst.sortables = [];
+		$(ui.options.connectToSortable).each(function() {
+			if($.data(this, 'sortable')) {
+				var sortable = $.data(this, 'sortable');
+				inst.sortables.push({
+					instance: sortable,
+					shouldRevert: sortable.options.revert
+				});
+				sortable.refreshItems();	//Do a one-time refresh at start to refresh the containerCache	
+				sortable.propagate("activate", e, inst);
+			}
+		});
+
+	},
+	stop: function(e,ui) {
+		
+		//If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
+		var inst = $(this).data("draggable");
+		
+		$.each(inst.sortables, function() {
+			if(this.instance.isOver) {
+				this.instance.isOver = 0;
+				inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
+				this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
+				if(this.shouldRevert) this.instance.options.revert = true; //revert here
+				this.instance.mouseStop(e);
+				
+				//Also propagate receive event, since the sortable is actually receiving a element
+				this.instance.element.triggerHandler("sortreceive", [e, $.extend(this.instance.ui(), { sender: inst.element })], this.instance.options["receive"]);
+
+				this.instance.options.helper = this.instance.options._helper;
+			} else {
+				this.instance.propagate("deactivate", e, inst);
+			}
+
+		});
+		
+	},
+	drag: function(e,ui) {
+
+		var inst = $(this).data("draggable"), self = this;
+		
+		var checkPos = function(o) {
+				
+			var l = o.left, r = l + o.width,
+				t = o.top, b = t + o.height;
+
+			return (l < (this.positionAbs.left + this.offset.click.left) && (this.positionAbs.left + this.offset.click.left) < r
+					&& t < (this.positionAbs.top + this.offset.click.top) && (this.positionAbs.top + this.offset.click.top) < b);				
+		};
+		
+		$.each(inst.sortables, function(i) {
+
+			if(checkPos.call(inst, this.instance.containerCache)) {
+
+				//If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
+				if(!this.instance.isOver) {
+					this.instance.isOver = 1;
+
+					//Now we fake the start of dragging for the sortable instance,
+					//by cloning the list group item, appending it to the sortable and using it as inst.currentItem
+					//We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one)
+					this.instance.currentItem = $(self).clone().appendTo(this.instance.element).data("sortable-item", true);
+					this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
+					this.instance.options.helper = function() { return ui.helper[0]; };
+				
+					e.target = this.instance.currentItem[0];
+					this.instance.mouseCapture(e, true);
+					this.instance.mouseStart(e, true, true);
+
+					//Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
+					this.instance.offset.click.top = inst.offset.click.top;
+					this.instance.offset.click.left = inst.offset.click.left;
+					this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
+					this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
+					
+					inst.propagate("toSortable", e);
+				
+				}
+				
+				//Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable
+				if(this.instance.currentItem) this.instance.mouseDrag(e);
+				
+			} else {
+				
+				//If it doesn't intersect with the sortable, and it intersected before,
+				//we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
+				if(this.instance.isOver) {
+					this.instance.isOver = 0;
+					this.instance.cancelHelperRemoval = true;
+					this.instance.options.revert = false; //No revert here
+					this.instance.mouseStop(e, true);
+					this.instance.options.helper = this.instance.options._helper;
+					
+					//Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
+					this.instance.currentItem.remove();
+					if(this.instance.placeholder) this.instance.placeholder.remove();
+					
+					inst.propagate("fromSortable", e);
+				}
+				
+			};
+
+		});
+
+	}
+});
+
+$.ui.plugin.add("draggable", "stack", {
+	start: function(e,ui) {
+		var group = $.makeArray($(ui.options.stack.group)).sort(function(a,b) {
+			return (parseInt($(a).css("zIndex"),10) || ui.options.stack.min) - (parseInt($(b).css("zIndex"),10) || ui.options.stack.min);
+		});
+		
+		$(group).each(function(i) {
+			this.style.zIndex = ui.options.stack.min + i;
+		});
+		
+		this[0].style.zIndex = ui.options.stack.min + group.length;
+	}
+});
+
+})(jQuery);
Index: /tags/2.0.2/template-common/lib/ui/ui.draggable.packed.js
===================================================================
--- /tags/2.0.2/template-common/lib/ui/ui.draggable.packed.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/ui.draggable.packed.js	(revision 3278)
@@ -0,0 +1,2 @@
+eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)d[e(c)]=k[c]||e(c);k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(b(A){A.3y("g.i",A.1T({},A.g.3x,{3w:b(){a B=4.9;7(B.d=="27"&&!(/(l|Z|15)/).1k(4.j.e("m"))){4.j.e("m","l")}4.j.2b("g-i");(B.2e&&4.j.2b("g-i-2e"));4.3v()},2g:b(F){a H=4.9;7(4.d||H.2e||A(F.1Q).3u(".g-3t-1L")){n 11}a C=!4.9.1L||!A(4.9.1L,4.j).1A?t:11;A(4.9.1L,4.j).3s("*").3r().1b(b(){7(4==F.1Q){C=t}});7(!C){n 11}7(A.g.1f){A.g.1f.3q=4}4.d=A.3p(H.d)?A(H.d.3o(4.j[0],[F])):(H.d=="1S"?4.j.1S():4.j);7(!4.d.3n("14").1A){4.d.1p((H.1p=="k"?4.j[0].1t:H.1p))}7(4.d[0]!=4.j[0]&&!(/(15|Z)/).1k(4.d.e("m"))){4.d.e("m","Z")}4.S={6:(o(4.j.e("3m"),10)||0),5:(o(4.j.e("3l"),10)||0)};4.z=4.d.e("m");4.8=4.j.8();4.8={5:4.8.5-4.S.5,6:4.8.6-4.S.6};4.8.q={6:F.1q-4.8.6,5:F.1s-4.8.5};4.p=4.d.p();a B=4.p.8();7(4.p[0]==f.14&&A.3k.3j){B={5:0,6:0}}4.8.k={5:B.5+(o(4.p.e("2c"),10)||0),6:B.6+(o(4.p.e("2d"),10)||0)};a E=4.j.m();4.8.l=4.z=="l"?{5:E.5-(o(4.d.e("5"),10)||0)+4.p[0].s,6:E.6-(o(4.d.e("6"),10)||0)+4.p[0].r}:{5:0,6:0};4.1m=4.2a(F);4.w={v:4.d.1W(),u:4.d.1V()};7(H.1a){7(H.1a.6!=1K){4.8.q.6=H.1a.6+4.S.6}7(H.1a.2z!=1K){4.8.q.6=4.w.v-H.1a.2z+4.S.6}7(H.1a.5!=1K){4.8.q.5=H.1a.5+4.S.5}7(H.1a.2y!=1K){4.8.q.5=4.w.u-H.1a.2y+4.S.5}}7(H.h){7(H.h=="k"){H.h=4.d[0].1t}7(H.h=="f"||H.h=="1r"){4.h=[0-4.8.l.6-4.8.k.6,0-4.8.l.5-4.8.k.5,A(H.h=="f"?f:1r).v()-4.8.l.6-4.8.k.6-4.w.v-4.S.6-(o(4.j.e("2x"),10)||0),(A(H.h=="f"?f:1r).u()||f.14.1t.2v)-4.8.l.5-4.8.k.5-4.w.u-4.S.5-(o(4.j.e("2u"),10)||0)]}7(!(/^(f|1r|k)$/).1k(H.h)){a D=A(H.h)[0];a G=A(H.h).8();4.h=[G.6+(o(A(D).e("2d"),10)||0)-4.8.l.6-4.8.k.6,G.5+(o(A(D).e("2c"),10)||0)-4.8.l.5-4.8.k.5,G.6+T.2w(D.3i,D.1Z)-(o(A(D).e("2d"),10)||0)-4.8.l.6-4.8.k.6-4.w.v-4.S.6-(o(4.j.e("2x"),10)||0),G.5+T.2w(D.2v,D.22)-(o(A(D).e("2c"),10)||0)-4.8.l.5-4.8.k.5-4.w.u-4.S.5-(o(4.j.e("2u"),10)||0)]}}4.18("16",F);4.w={v:4.d.1W(),u:4.d.1V()};7(A.g.1f&&!H.2s){A.g.1f.3h(4,F)}4.d.2b("g-i-2r");4.1P(F);n t},W:b(C,D){7(!D){D=4.m}a B=C=="Z"?1:-1;n{5:(D.5+4.8.l.5*B+4.8.k.5*B-(4.z=="15"||(4.z=="Z"&&4.p[0]==f.14)?0:4.p[0].s)*B+(4.z=="15"?A(f).s():0)*B+4.S.5*B),6:(D.6+4.8.l.6*B+4.8.k.6*B-(4.z=="15"||(4.z=="Z"&&4.p[0]==f.14)?0:4.p[0].r)*B+(4.z=="15"?A(f).r():0)*B+4.S.6*B)}},2a:b(E){a F=4.9;a B={5:(E.1s-4.8.q.5-4.8.l.5-4.8.k.5+(4.z=="15"||(4.z=="Z"&&4.p[0]==f.14)?0:4.p[0].s)-(4.z=="15"?A(f).s():0)),6:(E.1q-4.8.q.6-4.8.l.6-4.8.k.6+(4.z=="15"||(4.z=="Z"&&4.p[0]==f.14)?0:4.p[0].r)-(4.z=="15"?A(f).r():0))};7(!4.1m){n B}7(4.h){7(B.6<4.h[0]){B.6=4.h[0]}7(B.5<4.h[1]){B.5=4.h[1]}7(B.6>4.h[2]){B.6=4.h[2]}7(B.5>4.h[3]){B.5=4.h[3]}}7(F.19){a D=4.1m.5+T.2t((B.5-4.1m.5)/F.19[1])*F.19[1];B.5=4.h?(!(D<4.h[1]||D>4.h[3])?D:(!(D<4.h[1])?D-F.19[1]:D+F.19[1])):D;a C=4.1m.6+T.2t((B.6-4.1m.6)/F.19[0])*F.19[0];B.6=4.h?(!(C<4.h[0]||C>4.h[2])?C:(!(C<4.h[0])?C-F.19[0]:C+F.19[0])):C}n B},1P:b(B){4.m=4.2a(B);4.1h=4.W("Z");4.m=4.18("1d",B)||4.m;7(!4.9.1z||4.9.1z!="y"){4.d[0].1v.6=4.m.6+"1I"}7(!4.9.1z||4.9.1z!="x"){4.d[0].1v.5=4.m.5+"1I"}7(A.g.1f){A.g.1f.1d(4,B)}n 11},1O:b(C){a D=11;7(A.g.1f&&!4.9.2s){a D=A.g.1f.3g(4,C)}7((4.9.1g=="3f"&&!D)||(4.9.1g=="3e"&&D)||4.9.1g===t){a B=4;A(4.d).3d(4.1m,o(4.9.1g,10)||3c,b(){B.18("1i",C);B.29()})}1x{4.18("1i",C);4.29()}n 11},29:b(){4.d.2q("g-i-2r");7(4.9.d!="27"&&!4.1w){4.d.1M()}4.d=3b;4.1w=11},3a:{},28:b(B){n{d:4.d,m:4.m,1U:4.1h,9:4.9}},18:b(C,B){A.g.17.2i(4,C,[B,4.28()]);7(C=="1d"){4.1h=4.W("Z")}n 4.j.2j(C=="1d"?C:"1d"+C,[B,4.28()],4.9[C])},39:b(){7(!4.j.V("i")){n}4.j.38("i").37(".i").2q("g-i");4.36()}}));A.1T(A.g.i,{35:{1p:"k",1z:11,34:":33",32:0,31:1,d:"27"}});A.g.17.1c("i","1u",{16:b(D,C){a B=A("14");7(B.e("1u")){C.9.26=B.e("1u")}B.e("1u",C.9.1u)},1i:b(C,B){7(B.9.26){A("14").e("1u",B.9.26)}}});A.g.17.1c("i","U",{16:b(D,C){a B=A(C.d);7(B.e("U")){C.9.25=B.e("U")}B.e("U",C.9.U)},1i:b(C,B){7(B.9.25){A(B.d).e("U",B.9.25)}}});A.g.17.1c("i","1l",{16:b(D,C){a B=A(C.d);7(B.e("1l")){C.9.24=B.e("1l")}B.e("1l",C.9.1l)},1i:b(C,B){7(B.9.24){A(B.d).e("1l",B.9.24)}}});A.g.17.1c("i","1J",{16:b(C,B){A(B.9.1J===t?"30":B.9.1J).1b(b(){A(\'<23 2Z="g-i-1J" 1v="2Y: #2X;"></23>\').e({v:4.1Z+"1I",u:4.22+"1I",m:"Z",1l:"0.2W",U:2V}).e(A(4).8()).1p("14")})},1i:b(C,B){A("23.2U").1b(b(){4.1t.2T(4)})}});A.g.17.1c("i","1y",{16:b(D,C){a E=C.9;a B=A(4).V("i");E.13=E.13||20;E.12=E.12||20;B.Y=b(F){2p{7(/1H|1y/.1k(F.e("1G"))||(/1H|1y/).1k(F.e("1G-y"))){n F}F=F.k()}2o(F[0].1t);n A(f)}(4);B.X=b(F){2p{7(/1H|1y/.1k(F.e("1G"))||(/1H|1y/).1k(F.e("1G-x"))){n F}F=F.k()}2o(F[0].1t);n A(f)}(4);7(B.Y[0]!=f&&B.Y[0].1F!="1E"){B.21=B.Y.8()}7(B.X[0]!=f&&B.X[0].1F!="1E"){B.1Y=B.X.8()}},1d:b(D,C){a E=C.9;a B=A(4).V("i");7(B.Y[0]!=f&&B.Y[0].1F!="1E"){7((B.21.5+B.Y[0].22)-D.1s<E.13){B.Y[0].s=B.Y[0].s+E.12}7(D.1s-B.21.5<E.13){B.Y[0].s=B.Y[0].s-E.12}}1x{7(D.1s-A(f).s()<E.13){A(f).s(A(f).s()-E.12)}7(A(1r).u()-(D.1s-A(f).s())<E.13){A(f).s(A(f).s()+E.12)}}7(B.X[0]!=f&&B.X[0].1F!="1E"){7((B.1Y.6+B.X[0].1Z)-D.1q<E.13){B.X[0].r=B.X[0].r+E.12}7(D.1q-B.1Y.6<E.13){B.X[0].r=B.X[0].r-E.12}}1x{7(D.1q-A(f).r()<E.13){A(f).r(A(f).r()-E.12)}7(A(1r).v()-(D.1q-A(f).r())<E.13){A(f).r(A(f).r()+E.12)}}}});A.g.17.1c("i","1X",{16:b(D,C){a B=A(4).V("i");B.1j=[];A(C.9.1X===t?".g-i":C.9.1X).1b(b(){a F=A(4);a E=F.8();7(4!=B.j[0]){B.1j.2l({2h:4,v:F.1W(),u:F.1V(),5:E.5,6:E.6})}})},1d:b(J,N){a I=A(4).V("i");a L=N.9.2S||20;a D=N.1U.6,C=D+I.w.v,P=N.1U.5,O=P+I.w.u;2R(a H=I.1j.1A-1;H>=0;H--){a E=I.1j[H].6,B=E+I.1j[H].v,R=I.1j[H].5,M=R+I.1j[H].u;7(!((E-L<D&&D<B+L&&R-L<P&&P<M+L)||(E-L<D&&D<B+L&&R-L<O&&O<M+L)||(E-L<C&&C<B+L&&R-L<P&&P<M+L)||(E-L<C&&C<B+L&&R-L<O&&O<M+L))){2Q}7(N.9.2n!="2P"){a K=T.1e(R-O)<=20;a Q=T.1e(M-P)<=20;a G=T.1e(E-C)<=20;a F=T.1e(B-D)<=20;7(K){N.m.5=I.W("l",{5:R-I.w.u,6:0}).5}7(Q){N.m.5=I.W("l",{5:M,6:0}).5}7(G){N.m.6=I.W("l",{5:0,6:E-I.w.v}).6}7(F){N.m.6=I.W("l",{5:0,6:B}).6}}7(N.9.2n!="2O"){a K=T.1e(R-P)<=20;a Q=T.1e(M-O)<=20;a G=T.1e(E-D)<=20;a F=T.1e(B-C)<=20;7(K){N.m.5=I.W("l",{5:R,6:0}).5}7(Q){N.m.5=I.W("l",{5:M-I.w.u,6:0}).5}7(G){N.m.6=I.W("l",{5:0,6:E}).6}7(F){N.m.6=I.W("l",{5:0,6:B-I.w.v}).6}}}}});A.g.17.1c("i","2m",{16:b(D,C){a B=A(4).V("i");B.1D=[];A(C.9.2m).1b(b(){7(A.V(4,"1R")){a E=A.V(4,"1R");B.1D.2l({c:E,2k:E.9.1g});E.2N();E.18("2M",D,B)}})},1i:b(D,C){a B=A(4).V("i");A.1b(B.1D,b(){7(4.c.1o){4.c.1o=0;B.1w=t;4.c.1w=11;7(4.2k){4.c.9.1g=t}4.c.1O(D);4.c.j.2j("2L",[D,A.1T(4.c.g(),{2K:B.j})],4.c.9["2J"]);4.c.9.d=4.c.9.1N}1x{4.c.18("2I",D,B)}})},1d:b(F,E){a D=A(4).V("i"),B=4;a C=b(K){a H=K.6,J=H+K.v,I=K.5,G=I+K.u;n(H<(4.1h.6+4.8.q.6)&&(4.1h.6+4.8.q.6)<J&&I<(4.1h.5+4.8.q.5)&&(4.1h.5+4.8.q.5)<G)};A.1b(D.1D,b(G){7(C.2i(D,4.c.2H)){7(!4.c.1o){4.c.1o=1;4.c.1C=A(B).1S().1p(4.c.j).V("1R-2h",t);4.c.9.1N=4.c.9.d;4.c.9.d=b(){n E.d[0]};F.1Q=4.c.1C[0];4.c.2G(F,t);4.c.2g(F,t,t);4.c.8.q.5=D.8.q.5;4.c.8.q.6=D.8.q.6;4.c.8.k.6-=D.8.k.6-4.c.8.k.6;4.c.8.k.5-=D.8.k.5-4.c.8.k.5;D.18("2F",F)}7(4.c.1C){4.c.1P(F)}}1x{7(4.c.1o){4.c.1o=0;4.c.1w=t;4.c.9.1g=11;4.c.1O(F,t);4.c.9.d=4.c.9.1N;4.c.1C.1M();7(4.c.2f){4.c.2f.1M()}D.18("2E",F)}}})}});A.g.17.1c("i","1n",{16:b(D,B){a C=A.2D(A(B.9.1n.2C)).2B(b(F,E){n(o(A(F).e("U"),10)||B.9.1n.1B)-(o(A(E).e("U"),10)||B.9.1n.1B)});A(C).1b(b(E){4.1v.U=B.9.1n.1B+E});4[0].1v.U=B.9.1n.1B+C.1A}})})(2A)',62,221,'||||this|top|left|if|offset|options|var|function|instance|helper|css|document|ui|containment|draggable|element|parent|relative|position|return|parseInt|offsetParent|click|scrollLeft|scrollTop|true|height|width|helperProportions|||cssPosition|||||||||||||||||||margins|Math|zIndex|data|convertPositionTo|overflowX|overflowY|absolute||false|scrollSpeed|scrollSensitivity|body|fixed|start|plugin|propagate|grid|cursorAt|each|add|drag|abs|ddmanager|revert|positionAbs|stop|snapElements|test|opacity|originalPosition|stack|isOver|appendTo|pageX|window|pageY|parentNode|cursor|style|cancelHelperRemoval|else|scroll|axis|length|min|currentItem|sortables|HTML|tagName|overflow|auto|px|iframeFix|undefined|handle|remove|_helper|mouseStop|mouseDrag|target|sortable|clone|extend|absolutePosition|outerHeight|outerWidth|snap|overflowXOffset|offsetWidth||overflowYOffset|offsetHeight|div|_opacity|_zIndex|_cursor|original|uiHash|clear|generatePosition|addClass|borderTopWidth|borderLeftWidth|disabled|placeholder|mouseStart|item|call|triggerHandler|shouldRevert|push|connectToSortable|snapMode|while|do|removeClass|dragging|dropBehaviour|round|marginBottom|scrollHeight|max|marginRight|bottom|right|jQuery|sort|group|makeArray|fromSortable|toSortable|mouseCapture|containerCache|deactivate|receive|sender|sortreceive|activate|refreshItems|outer|inner|continue|for|snapTolerance|removeChild|DragDropIframeFix|1000|001|fff|background|class|iframe|distance|delay|input|cancel|defaults|mouseDestroy|unbind|removeData|destroy|plugins|null|500|animate|valid|invalid|drop|prepareOffsets|scrollWidth|mozilla|browser|marginTop|marginLeft|parents|apply|isFunction|current|andSelf|find|resizable|is|mouseInit|init|mouse|widget'.split('|'),0,{}))
+
Index: /tags/2.0.2/template-common/lib/ui/ui.droppable.js
===================================================================
--- /tags/2.0.2/template-common/lib/ui/ui.droppable.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/ui.droppable.js	(revision 3278)
@@ -0,0 +1,281 @@
+/*
+ * jQuery UI Droppable
+ *
+ * Copyright (c) 2008 Paul Bakaus
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ * 
+ * http://docs.jquery.com/UI/Droppables
+ *
+ * Depends:
+ *	ui.core.js
+ *	ui.draggable.js
+ */
+(function($) {
+
+$.widget("ui.droppable", {
+	init: function() {
+
+		this.element.addClass("ui-droppable");
+		this.isover = 0; this.isout = 1;
+		
+		//Prepare the passed options
+		var o = this.options, accept = o.accept;
+		o = $.extend(o, {
+			accept: o.accept && o.accept.constructor == Function ? o.accept : function(d) {
+				return $(d).is(accept);
+			}
+		});
+		
+		//Store the droppable's proportions
+		this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight };
+		
+		// Add the reference and positions to the manager
+		$.ui.ddmanager.droppables.push(this);
+		
+	},
+	plugins: {},
+	ui: function(c) {
+		return {
+			draggable: (c.currentItem || c.element),
+			helper: c.helper,
+			position: c.position,
+			absolutePosition: c.positionAbs,
+			options: this.options,
+			element: this.element
+		};
+	},
+	destroy: function() {
+		var drop = $.ui.ddmanager.droppables;
+		for ( var i = 0; i < drop.length; i++ )
+			if ( drop[i] == this )
+				drop.splice(i, 1);
+		
+		this.element
+			.removeClass("ui-droppable ui-droppable-disabled")
+			.removeData("droppable")
+			.unbind(".droppable");
+	},
+	over: function(e) {
+		
+		var draggable = $.ui.ddmanager.current;
+		if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
+		
+		if (this.options.accept.call(this.element,(draggable.currentItem || draggable.element))) {
+			$.ui.plugin.call(this, 'over', [e, this.ui(draggable)]);
+			this.element.triggerHandler("dropover", [e, this.ui(draggable)], this.options.over);
+		}
+		
+	},
+	out: function(e) {
+		
+		var draggable = $.ui.ddmanager.current;
+		if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
+		
+		if (this.options.accept.call(this.element,(draggable.currentItem || draggable.element))) {
+			$.ui.plugin.call(this, 'out', [e, this.ui(draggable)]);
+			this.element.triggerHandler("dropout", [e, this.ui(draggable)], this.options.out);
+		}
+		
+	},
+	drop: function(e,custom) {
+		
+		var draggable = custom || $.ui.ddmanager.current;
+		if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return false; // Bail if draggable and droppable are same element
+		
+		var childrenIntersection = false;
+		this.element.find(".ui-droppable").not(".ui-draggable-dragging").each(function() {
+			var inst = $.data(this, 'droppable');
+			if(inst.options.greedy && $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)) {
+				childrenIntersection = true; return false;
+			}
+		});
+		if(childrenIntersection) return false;
+		
+		if(this.options.accept.call(this.element,(draggable.currentItem || draggable.element))) {
+			$.ui.plugin.call(this, 'drop', [e, this.ui(draggable)]);
+			this.element.triggerHandler("drop", [e, this.ui(draggable)], this.options.drop);
+			return true;
+		}
+		
+		return false;
+		
+	},
+	activate: function(e) {
+		
+		var draggable = $.ui.ddmanager.current;
+		$.ui.plugin.call(this, 'activate', [e, this.ui(draggable)]);
+		if(draggable) this.element.triggerHandler("dropactivate", [e, this.ui(draggable)], this.options.activate);
+		
+	},
+	deactivate: function(e) {
+		
+		var draggable = $.ui.ddmanager.current;
+		$.ui.plugin.call(this, 'deactivate', [e, this.ui(draggable)]);
+		if(draggable) this.element.triggerHandler("dropdeactivate", [e, this.ui(draggable)], this.options.deactivate);
+		
+	}
+});
+
+$.extend($.ui.droppable, {
+	defaults: {
+		disabled: false,
+		tolerance: 'intersect'
+	}
+});
+
+$.ui.intersect = function(draggable, droppable, toleranceMode) {
+	
+	if (!droppable.offset) return false;
+	
+	var x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,
+		y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height;
+	var l = droppable.offset.left, r = l + droppable.proportions.width,
+		t = droppable.offset.top, b = t + droppable.proportions.height;
+	
+	switch (toleranceMode) {
+		case 'fit':
+			return (l < x1 && x2 < r
+				&& t < y1 && y2 < b);
+			break;
+		case 'intersect':
+			return (l < x1 + (draggable.helperProportions.width / 2) // Right Half
+				&& x2 - (draggable.helperProportions.width / 2) < r // Left Half
+				&& t < y1 + (draggable.helperProportions.height / 2) // Bottom Half
+				&& y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
+			break;
+		case 'pointer':
+			return (l < ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left) && ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left) < r
+				&& t < ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top) && ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top) < b);
+			break;
+		case 'touch':
+			return (
+					(y1 >= t && y1 <= b) ||	// Top edge touching
+					(y2 >= t && y2 <= b) ||	// Bottom edge touching
+					(y1 < t && y2 > b)		// Surrounded vertically
+				) && (
+					(x1 >= l && x1 <= r) ||	// Left edge touching
+					(x2 >= l && x2 <= r) ||	// Right edge touching
+					(x1 < l && x2 > r)		// Surrounded horizontally
+				);
+			break;
+		default:
+			return false;
+			break;
+		}
+	
+};
+
+/*
+	This manager tracks offsets of draggables and droppables
+*/
+$.ui.ddmanager = {
+	current: null,
+	droppables: [],
+	prepareOffsets: function(t, e) {
+		
+		var m = $.ui.ddmanager.droppables;
+		var type = e ? e.type : null; // workaround for #2317
+
+		for (var i = 0; i < m.length; i++) {
+			if(m[i].options.disabled || (t && !m[i].options.accept.call(m[i].element,(t.currentItem || t.element)))) continue;
+			m[i].visible = m[i].element.css("display") != "none"; if(!m[i].visible) continue; //If the element is not visible, continue
+			m[i].offset = m[i].element.offset();
+			m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };
+			
+			if(type == "dragstart" || type == "sortactivate") m[i].activate.call(m[i], e); //Activate the droppable if used directly from draggables
+		}
+		
+	},
+	drop: function(draggable, e) {
+		
+		var dropped = false;
+		$.each($.ui.ddmanager.droppables, function() {
+			
+			if(!this.options) return;
+			if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance))
+				dropped = this.drop.call(this, e);
+			
+			if (!this.options.disabled && this.visible && this.options.accept.call(this.element,(draggable.currentItem || draggable.element))) {
+				this.isout = 1; this.isover = 0;
+				this.deactivate.call(this, e);
+			}
+			
+		});
+		return dropped;
+		
+	},
+	drag: function(draggable, e) {
+		
+		//If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
+		if(draggable.options.refreshPositions) $.ui.ddmanager.prepareOffsets(draggable, e);
+		
+		//Run through all droppables and check their positions based on specific tolerance options
+
+		$.each($.ui.ddmanager.droppables, function() {
+			
+			if(this.options.disabled || this.greedyChild || !this.visible) return;
+			var intersects = $.ui.intersect(draggable, this, this.options.tolerance);
+			
+			var c = !intersects && this.isover == 1 ? 'isout' : (intersects && this.isover == 0 ? 'isover' : null);
+			if(!c) return;
+			
+			var parentInstance;
+			if (this.options.greedy) {
+				var parent = this.element.parents('.ui-droppable:eq(0)');
+				if (parent.length) {
+					parentInstance = $.data(parent[0], 'droppable');
+					parentInstance.greedyChild = (c == 'isover' ? 1 : 0);
+				}
+			}
+			
+			// we just moved into a greedy child
+			if (parentInstance && c == 'isover') {
+				parentInstance['isover'] = 0;
+				parentInstance['isout'] = 1;
+				parentInstance.out.call(parentInstance, e);
+			}
+			
+			this[c] = 1; this[c == 'isout' ? 'isover' : 'isout'] = 0;
+			this[c == "isover" ? "over" : "out"].call(this, e);
+			
+			// we just moved out of a greedy child
+			if (parentInstance && c == 'isout') {
+				parentInstance['isout'] = 0;
+				parentInstance['isover'] = 1;
+				parentInstance.over.call(parentInstance, e);
+			}
+		});
+		
+	}
+};
+
+/*
+ * Droppable Extensions
+ */
+
+$.ui.plugin.add("droppable", "activeClass", {
+	activate: function(e, ui) {
+		$(this).addClass(ui.options.activeClass);
+	},
+	deactivate: function(e, ui) {
+		$(this).removeClass(ui.options.activeClass);
+	},
+	drop: function(e, ui) {
+		$(this).removeClass(ui.options.activeClass);
+	}
+});
+
+$.ui.plugin.add("droppable", "hoverClass", {
+	over: function(e, ui) {
+		$(this).addClass(ui.options.hoverClass);
+	},
+	out: function(e, ui) {
+		$(this).removeClass(ui.options.hoverClass);
+	},
+	drop: function(e, ui) {
+		$(this).removeClass(ui.options.hoverClass);
+	}
+});
+
+})(jQuery);
Index: /tags/2.0.2/template-common/lib/ui/ui.droppable.packed.js
===================================================================
--- /tags/2.0.2/template-common/lib/ui/ui.droppable.packed.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/ui.droppable.packed.js	(revision 3278)
@@ -0,0 +1,2 @@
+eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)d[e(c)]=k[c]||e(c);k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(8(A){A.1P("4.c",{1O:8(){3.5.Z("4-c");3.e=0;3.k=1;9 C=3.6,B=C.g;C=A.13(C,{g:C.g&&C.g.1N==1M?C.g:8(D){a A(D).1L(B)}});3.V={u:3.5[0].1a,t:3.5[0].19};A.4.d.s.1K(3)},1J:{},4:8(B){a{1e:(B.h||B.5),1f:B.1f,l:B.l,1I:B.n,6:3.6,5:3.5}},1H:8(){9 B=A.4.d.s;1c(9 C=0;C<B.10;C++){7(B[C]==3){B.1G(C,1)}}3.5.M("4-c 4-c-r").1F("c").1E(".c")},p:8(C){9 B=A.4.d.v;7(!B||(B.h||B.5)[0]==3.5[0]){a}7(3.6.g.b(3.5,(B.h||B.5))){A.4.m.b(3,"p",[C,3.4(B)]);3.5.R("1D",[C,3.4(B)],3.6.p)}},o:8(C){9 B=A.4.d.v;7(!B||(B.h||B.5)[0]==3.5[0]){a}7(3.6.g.b(3.5,(B.h||B.5))){A.4.m.b(3,"o",[C,3.4(B)]);3.5.R("1C",[C,3.4(B)],3.6.o)}},j:8(D,C){9 B=C||A.4.d.v;7(!B||(B.h||B.5)[0]==3.5[0]){a i}9 E=i;3.5.1B(".4-c").1A(".4-1e-1z").12(8(){9 F=A.16(3,"c");7(F.6.17&&A.4.q(B,A.13(F,{f:F.5.f()}),F.6.U)){E=1d;a i}});7(E){a i}7(3.6.g.b(3.5,(B.h||B.5))){A.4.m.b(3,"j",[D,3.4(B)]);3.5.R("j",[D,3.4(B)],3.6.j);a 1d}a i},O:8(C){9 B=A.4.d.v;A.4.m.b(3,"O",[C,3.4(B)]);7(B){3.5.R("1y",[C,3.4(B)],3.6.O)}},N:8(C){9 B=A.4.d.v;A.4.m.b(3,"N",[C,3.4(B)]);7(B){3.5.R("1x",[C,3.4(B)],3.6.N)}}});A.13(A.4.c,{1w:{r:i,U:"q"}});A.4.q=8(L,F,J){7(!F.f){a i}9 D=(L.n||L.l.x).y,C=D+L.z.u,I=(L.n||L.l.x).w,H=I+L.z.t;9 E=F.f.y,B=E+F.V.u,K=F.f.w,G=K+F.V.t;1v(J){W"1u":a(E<D&&C<B&&K<I&&H<G);Q;W"q":a(E<D+(L.z.u/2)&&C-(L.z.u/2)<B&&K<I+(L.z.t/2)&&H-(L.z.t/2)<G);Q;W"1t":a(E<((L.n||L.l.x).y+(L.Y||L.f.X).y)&&((L.n||L.l.x).y+(L.Y||L.f.X).y)<B&&K<((L.n||L.l.x).w+(L.Y||L.f.X).w)&&((L.n||L.l.x).w+(L.Y||L.f.X).w)<G);Q;W"1s":a((I>=K&&I<=G)||(H>=K&&H<=G)||(I<K&&H>G))&&((D>=E&&D<=B)||(C>=E&&C<=B)||(D<E&&C>B));Q;1r:a i;Q}};A.4.d={v:11,s:[],18:8(D,F){9 B=A.4.d.s;9 E=F?F.1q:11;1c(9 C=0;C<B.10;C++){7(B[C].6.r||(D&&!B[C].6.g.b(B[C].5,(D.h||D.5)))){1b}B[C].P=B[C].5.1p("1o")!="1n";7(!B[C].P){1b}B[C].f=B[C].5.f();B[C].V={u:B[C].5[0].1a,t:B[C].5[0].19};7(E=="1m"||E=="1l"){B[C].O.b(B[C],F)}}},j:8(B,C){9 D=i;A.12(A.4.d.s,8(){7(!3.6){a}7(!3.6.r&&3.P&&A.4.q(B,3,3.6.U)){D=3.j.b(3,C)}7(!3.6.r&&3.P&&3.6.g.b(3.5,(B.h||B.5))){3.k=1;3.e=0;3.N.b(3,C)}});a D},1k:8(B,C){7(B.6.1j){A.4.d.18(B,C)}A.12(A.4.d.s,8(){7(3.6.r||3.15||!3.P){a}9 E=A.4.q(B,3,3.6.U);9 G=!E&&3.e==1?"k":(E&&3.e==0?"e":11);7(!G){a}9 F;7(3.6.17){9 D=3.5.1i(".4-c:1h(0)");7(D.10){F=A.16(D[0],"c");F.15=(G=="e"?1:0)}}7(F&&G=="e"){F["e"]=0;F["k"]=1;F.o.b(F,C)}3[G]=1;3[G=="k"?"e":"k"]=0;3[G=="e"?"p":"o"].b(3,C);7(F&&G=="k"){F["k"]=0;F["e"]=1;F.p.b(F,C)}})}};A.4.m.14("c","T",{O:8(C,B){A(3).Z(B.6.T)},N:8(C,B){A(3).M(B.6.T)},j:8(C,B){A(3).M(B.6.T)}});A.4.m.14("c","S",{p:8(C,B){A(3).Z(B.6.S)},o:8(C,B){A(3).M(B.6.S)},j:8(C,B){A(3).M(B.6.S)}})})(1g)',62,114,'|||this|ui|element|options|if|function|var|return|call|droppable|ddmanager|isover|offset|accept|currentItem|false|drop|isout|position|plugin|positionAbs|out|over|intersect|disabled|droppables|height|width|current|top|absolute|left|helperProportions|||||||||||||removeClass|deactivate|activate|visible|break|triggerHandler|hoverClass|activeClass|tolerance|proportions|case|click|clickOffset|addClass|length|null|each|extend|add|greedyChild|data|greedy|prepareOffsets|offsetHeight|offsetWidth|continue|for|true|draggable|helper|jQuery|eq|parents|refreshPositions|drag|sortactivate|dragstart|none|display|css|type|default|touch|pointer|fit|switch|defaults|dropdeactivate|dropactivate|dragging|not|find|dropout|dropover|unbind|removeData|splice|destroy|absolutePosition|plugins|push|is|Function|constructor|init|widget'.split('|'),0,{}))
+
Index: /tags/2.0.2/template-common/lib/ui/ui.resizable.js
===================================================================
--- /tags/2.0.2/template-common/lib/ui/ui.resizable.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/ui.resizable.js	(revision 3278)
@@ -0,0 +1,770 @@
+/*
+ * jQuery UI Resizable
+ *
+ * Copyright (c) 2008 Paul Bakaus
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ * 
+ * http://docs.jquery.com/UI/Resizables
+ *
+ * Depends:
+ *	ui.core.js
+ */
+(function($) {
+
+$.widget("ui.resizable", $.extend({}, $.ui.mouse, {
+	init: function() {
+
+		var self = this, o = this.options;
+
+		var elpos = this.element.css('position');
+		
+		this.originalElement = this.element;
+		
+		// simulate .ui-resizable { position: relative; }
+		this.element.addClass("ui-resizable").css({ position: /static/.test(elpos) ? 'relative' : elpos });
+		
+		$.extend(o, {
+			_aspectRatio: !!(o.aspectRatio),
+			helper: o.helper || o.ghost || o.animate ? o.helper || 'proxy' : null,
+			knobHandles: o.knobHandles === true ? 'ui-resizable-knob-handle' : o.knobHandles
+		});
+		
+		//Default Theme
+		var aBorder = '1px solid #DEDEDE';
+		
+		o.defaultTheme = {
+			'ui-resizable': { display: 'block' },
+			'ui-resizable-handle': { position: 'absolute', background: '#F2F2F2', fontSize: '0.1px' },
+			'ui-resizable-n': { cursor: 'n-resize', height: '4px', left: '0px', right: '0px', borderTop: aBorder },
+			'ui-resizable-s': { cursor: 's-resize', height: '4px', left: '0px', right: '0px', borderBottom: aBorder },
+			'ui-resizable-e': { cursor: 'e-resize', width: '4px', top: '0px', bottom: '0px', borderRight: aBorder },
+			'ui-resizable-w': { cursor: 'w-resize', width: '4px', top: '0px', bottom: '0px', borderLeft: aBorder },
+			'ui-resizable-se': { cursor: 'se-resize', width: '4px', height: '4px', borderRight: aBorder, borderBottom: aBorder },
+			'ui-resizable-sw': { cursor: 'sw-resize', width: '4px', height: '4px', borderBottom: aBorder, borderLeft: aBorder },
+			'ui-resizable-ne': { cursor: 'ne-resize', width: '4px', height: '4px', borderRight: aBorder, borderTop: aBorder },
+			'ui-resizable-nw': { cursor: 'nw-resize', width: '4px', height: '4px', borderLeft: aBorder, borderTop: aBorder }
+		};
+		
+		o.knobTheme = {
+			'ui-resizable-handle': { background: '#F2F2F2', border: '1px solid #808080', height: '8px', width: '8px' },
+			'ui-resizable-n': { cursor: 'n-resize', top: '0px', left: '45%' },
+			'ui-resizable-s': { cursor: 's-resize', bottom: '0px', left: '45%' },
+			'ui-resizable-e': { cursor: 'e-resize', right: '0px', top: '45%' },
+			'ui-resizable-w': { cursor: 'w-resize', left: '0px', top: '45%' },
+			'ui-resizable-se': { cursor: 'se-resize', right: '0px', bottom: '0px' },
+			'ui-resizable-sw': { cursor: 'sw-resize', left: '0px', bottom: '0px' },
+			'ui-resizable-nw': { cursor: 'nw-resize', left: '0px', top: '0px' },
+			'ui-resizable-ne': { cursor: 'ne-resize', right: '0px', top: '0px' }
+		};
+		
+		o._nodeName = this.element[0].nodeName;
+		
+		//Wrap the element if it cannot hold child nodes
+		if(o._nodeName.match(/canvas|textarea|input|select|button|img/i)) {
+			var el = this.element;
+			
+			//Opera fixing relative position
+			if (/relative/.test(el.css('position')) && $.browser.opera)
+				el.css({ position: 'relative', top: 'auto', left: 'auto' });
+			
+			//Create a wrapper element and set the wrapper to the new current internal element
+			el.wrap(
+				$('<div class="ui-wrapper"	style="overflow: hidden;"></div>').css( {
+					position: el.css('position'),
+					width: el.outerWidth(),
+					height: el.outerHeight(),
+					top: el.css('top'),
+					left: el.css('left')
+				})
+			);
+			
+			var oel = this.element; this.element = this.element.parent();
+			
+			// store instance on wrapper
+			this.element.data('resizable', this); 
+			
+			//Move margins to the wrapper
+			this.element.css({ marginLeft: oel.css("marginLeft"), marginTop: oel.css("marginTop"),
+				marginRight: oel.css("marginRight"), marginBottom: oel.css("marginBottom")
+			});
+			
+			oel.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
+			
+			//Prevent Safari textarea resize
+			if ($.browser.safari && o.preventDefault) oel.css('resize', 'none');
+			
+			o.proportionallyResize = oel.css({ position: 'static', zoom: 1, display: 'block' });
+			
+			// avoid IE jump
+			this.element.css({ margin: oel.css('margin') });
+			
+			// fix handlers offset
+			this._proportionallyResize();
+		}
+		
+		if(!o.handles) o.handles = !$('.ui-resizable-handle', this.element).length ? "e,s,se" : { n: '.ui-resizable-n', e: '.ui-resizable-e', s: '.ui-resizable-s', w: '.ui-resizable-w', se: '.ui-resizable-se', sw: '.ui-resizable-sw', ne: '.ui-resizable-ne', nw: '.ui-resizable-nw' };
+		if(o.handles.constructor == String) {
+			
+			o.zIndex = o.zIndex || 1000;
+			
+			if(o.handles == 'all') o.handles = 'n,e,s,w,se,sw,ne,nw';
+			
+			var n = o.handles.split(","); o.handles = {};
+			
+			// insertions are applied when don't have theme loaded
+			var insertionsDefault = {
+				handle: 'position: absolute; display: none; overflow:hidden;',
+				n: 'top: 0pt; width:100%;',
+				e: 'right: 0pt; height:100%;',
+				s: 'bottom: 0pt; width:100%;',
+				w: 'left: 0pt; height:100%;',
+				se: 'bottom: 0pt; right: 0px;',
+				sw: 'bottom: 0pt; left: 0px;',
+				ne: 'top: 0pt; right: 0px;',
+				nw: 'top: 0pt; left: 0px;'
+			};
+			
+			for(var i = 0; i < n.length; i++) {
+				var handle = $.trim(n[i]), dt = o.defaultTheme, hname = 'ui-resizable-'+handle, loadDefault = !$.ui.css(hname) && !o.knobHandles, userKnobClass = $.ui.css('ui-resizable-knob-handle'), 
+							allDefTheme = $.extend(dt[hname], dt['ui-resizable-handle']), allKnobTheme = $.extend(o.knobTheme[hname], !userKnobClass ? o.knobTheme['ui-resizable-handle'] : {});
+				
+				// increase zIndex of sw, se, ne, nw axis
+				var applyZIndex = /sw|se|ne|nw/.test(handle) ? { zIndex: ++o.zIndex } : {};
+				
+				var defCss = (loadDefault ? insertionsDefault[handle] : ''), 
+					axis = $(['<div class="ui-resizable-handle ', hname, '" style="', defCss, insertionsDefault.handle, '"></div>'].join('')).css( applyZIndex );
+				o.handles[handle] = '.ui-resizable-'+handle;
+				
+				this.element.append(
+					//Theme detection, if not loaded, load o.defaultTheme
+					axis.css( loadDefault ? allDefTheme : {} )
+						// Load the knobHandle css, fix width, height, top, left...
+						.css( o.knobHandles ? allKnobTheme : {} ).addClass(o.knobHandles ? 'ui-resizable-knob-handle' : '').addClass(o.knobHandles)
+				);
+			}
+			
+			if (o.knobHandles) this.element.addClass('ui-resizable-knob').css( !$.ui.css('ui-resizable-knob') ? { /*border: '1px #fff dashed'*/ } : {} );
+		}
+		
+		this._renderAxis = function(target) {
+			target = target || this.element;
+			
+			for(var i in o.handles) {
+				if(o.handles[i].constructor == String) 
+					o.handles[i] = $(o.handles[i], this.element).show();
+				
+				if (o.transparent)
+					o.handles[i].css({opacity:0});
+				
+				//Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
+				if (this.element.is('.ui-wrapper') && 
+					o._nodeName.match(/textarea|input|select|button/i)) {
+					
+					var axis = $(o.handles[i], this.element), padWrapper = 0;
+					
+					//Checking the correct pad and border
+					padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
+					
+					//The padding type i have to apply...
+					var padPos = [ 'padding', 
+						/ne|nw|n/.test(i) ? 'Top' :
+						/se|sw|s/.test(i) ? 'Bottom' : 
+						/^e$/.test(i) ? 'Right' : 'Left' ].join(""); 
+					
+					if (!o.transparent)
+						target.css(padPos, padWrapper);
+					
+					this._proportionallyResize();
+				}
+				if(!$(o.handles[i]).length) continue;
+			}
+		};
+		
+		this._renderAxis(this.element);
+		o._handles = $('.ui-resizable-handle', self.element);
+		
+		if (o.disableSelection)
+			o._handles.each(function(i, e) { $.ui.disableSelection(e); });
+		
+		//Matching axis name
+		o._handles.mouseover(function() {
+			if (!o.resizing) {
+				if (this.className) 
+					var axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
+				//Axis, default = se
+				self.axis = o.axis = axis && axis[1] ? axis[1] : 'se';
+			}
+		});
+		
+		//If we want to auto hide the elements
+		if (o.autoHide) {
+			o._handles.hide();
+			$(self.element).addClass("ui-resizable-autohide").hover(function() {
+				$(this).removeClass("ui-resizable-autohide");
+				o._handles.show();
+			},
+			function(){
+				if (!o.resizing) {
+					$(this).addClass("ui-resizable-autohide");
+					o._handles.hide();
+				}
+			});
+		}
+		
+		this.mouseInit();
+	},
+	plugins: {},
+	ui: function() {
+		return {
+			originalElement: this.originalElement,
+			element: this.element,
+			helper: this.helper,
+			position: this.position,
+			size: this.size,
+			options: this.options,
+			originalSize: this.originalSize,
+			originalPosition: this.originalPosition
+		};
+	},
+	propagate: function(n,e) {
+		$.ui.plugin.call(this, n, [e, this.ui()]);
+		if (n != "resize") this.element.triggerHandler(["resize", n].join(""), [e, this.ui()], this.options[n]);
+	},
+	destroy: function() {
+		var el = this.element, wrapped = el.children(".ui-resizable").get(0);
+		
+		this.mouseDestroy();
+		
+		var _destroy = function(exp) {
+			$(exp).removeClass("ui-resizable ui-resizable-disabled")
+				.removeData("resizable").unbind(".resizable").find('.ui-resizable-handle').remove();
+		};
+		
+		_destroy(el);
+		
+		if (el.is('.ui-wrapper') && wrapped) {
+			el.parent().append(
+				$(wrapped).css({
+					position: el.css('position'),
+					width: el.outerWidth(),
+					height: el.outerHeight(),
+					top: el.css('top'),
+					left: el.css('left')
+				})
+			).end().remove();
+			
+			_destroy(wrapped);
+		}
+	},
+	mouseStart: function(e) {
+		if(this.options.disabled) return false;
+		
+		var handle = false;
+		for(var i in this.options.handles) {
+			if($(this.options.handles[i])[0] == e.target) handle = true;
+		}
+		if (!handle) return false;
+		
+		var o = this.options, iniPos = this.element.position(), el = this.element, 
+			num = function(v) { return parseInt(v, 10) || 0; }, ie6 = $.browser.msie && $.browser.version < 7;
+		o.resizing = true;
+		o.documentScroll = { top: $(document).scrollTop(), left: $(document).scrollLeft() };
+		
+		// bugfix #1749
+		if (el.is('.ui-draggable') || (/absolute/).test(el.css('position'))) {
+			
+			// sOffset decides if document scrollOffset will be added to the top/left of the resizable element
+			var sOffset = $.browser.msie && !o.containment && (/absolute/).test(el.css('position')) && !(/relative/).test(el.parent().css('position'));
+			var dscrollt = sOffset ? o.documentScroll.top : 0, dscrolll = sOffset ? o.documentScroll.left : 0;
+			
+			el.css({ position: 'absolute', top: (iniPos.top + dscrollt), left: (iniPos.left + dscrolll) });
+		}
+		
+		//Opera fixing relative position
+		if ($.browser.opera && /relative/.test(el.css('position')))
+			el.css({ position: 'relative', top: 'auto', left: 'auto' });
+		
+		this._renderProxy();
+		
+		var curleft = num(this.helper.css('left')), curtop = num(this.helper.css('top'));
+		
+		if (o.containment) {
+			curleft += $(o.containment).scrollLeft()||0;
+			curtop += $(o.containment).scrollTop()||0;
+		}
+		
+		//Store needed variables
+		this.offset = this.helper.offset();
+		this.position = { left: curleft, top: curtop };
+		this.size = o.helper || ie6 ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
+		this.originalSize = o.helper || ie6 ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
+		this.originalPosition = { left: curleft, top: curtop };
+		this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
+		this.originalMousePosition = { left: e.pageX, top: e.pageY };
+		
+		//Aspect Ratio
+		o.aspectRatio = (typeof o.aspectRatio == 'number') ? o.aspectRatio : ((this.originalSize.height / this.originalSize.width)||1);
+		
+		if (o.preserveCursor)
+			$('body').css('cursor', this.axis + '-resize');
+			
+		this.propagate("start", e);
+		return true;
+	},
+	mouseDrag: function(e) {
+		
+		//Increase performance, avoid regex
+		var el = this.helper, o = this.options, props = {},
+			self = this, smp = this.originalMousePosition, a = this.axis;
+		
+		var dx = (e.pageX-smp.left)||0, dy = (e.pageY-smp.top)||0;
+		var trigger = this._change[a];
+		if (!trigger) return false;
+		
+		// Calculate the attrs that will be change
+		var data = trigger.apply(this, [e, dx, dy]), ie6 = $.browser.msie && $.browser.version < 7, csdif = this.sizeDiff;
+		
+		if (o._aspectRatio || e.shiftKey)
+			data = this._updateRatio(data, e);
+		
+		data = this._respectSize(data, e);
+		
+		// plugins callbacks need to be called first
+		this.propagate("resize", e);
+		
+		el.css({
+			top: this.position.top + "px", left: this.position.left + "px", 
+			width: this.size.width + "px", height: this.size.height + "px"
+		});
+		
+		if (!o.helper && o.proportionallyResize)
+			this._proportionallyResize();
+		
+		this._updateCache(data);
+		
+		// calling the user callback at the end
+		this.element.triggerHandler("resize", [e, this.ui()], this.options["resize"]);
+		
+		return false;
+	},
+	mouseStop: function(e) {
+		
+		this.options.resizing = false;
+		var o = this.options, num = function(v) { return parseInt(v, 10) || 0; }, self = this;
+		
+		if(o.helper) {
+			var pr = o.proportionallyResize, ista = pr && (/textarea/i).test(pr.get(0).nodeName), 
+						soffseth = ista && $.ui.hasScroll(pr.get(0), 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,
+							soffsetw = ista ? 0 : self.sizeDiff.width;
+			
+			var s = { width: (self.size.width - soffsetw), height: (self.size.height - soffseth) },
+				left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null, 
+				top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null;
+			
+			if (!o.animate)
+				this.element.css($.extend(s, { top: top, left: left }));
+			
+			if (o.helper && !o.animate) this._proportionallyResize();
+		}
+		
+		if (o.preserveCursor)
+			$('body').css('cursor', 'auto');
+		
+		this.propagate("stop", e);
+		
+		if (o.helper) this.helper.remove();
+		
+		return false;
+	},
+	_updateCache: function(data) {
+		var o = this.options;
+		this.offset = this.helper.offset();
+		if (data.left) this.position.left = data.left;
+		if (data.top) this.position.top = data.top;
+		if (data.height) this.size.height = data.height;
+		if (data.width) this.size.width = data.width;
+	},
+	_updateRatio: function(data, e) {
+		var o = this.options, cpos = this.position, csize = this.size, a = this.axis;
+		
+		if (data.height) data.width = (csize.height / o.aspectRatio);
+		else if (data.width) data.height = (csize.width * o.aspectRatio);
+		
+		if (a == 'sw') {
+			data.left = cpos.left + (csize.width - data.width);
+			data.top = null;
+		}
+		if (a == 'nw') { 
+			data.top = cpos.top + (csize.height - data.height);
+			data.left = cpos.left + (csize.width - data.width);
+		}
+		
+		return data;
+	},
+	_respectSize: function(data, e) {
+		
+		var el = this.helper, o = this.options, pRatio = o._aspectRatio || e.shiftKey, a = this.axis, 
+				ismaxw = data.width && o.maxWidth && o.maxWidth < data.width, ismaxh = data.height && o.maxHeight && o.maxHeight < data.height,
+					isminw = data.width && o.minWidth && o.minWidth > data.width, isminh = data.height && o.minHeight && o.minHeight > data.height;
+		
+		if (isminw) data.width = o.minWidth;
+		if (isminh) data.height = o.minHeight;
+		if (ismaxw) data.width = o.maxWidth;
+		if (ismaxh) data.height = o.maxHeight;
+		
+		var dw = this.originalPosition.left + this.originalSize.width, dh = this.position.top + this.size.height;
+		var cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
+		
+		if (isminw && cw) data.left = dw - o.minWidth;
+		if (ismaxw && cw) data.left = dw - o.maxWidth;
+		if (isminh && ch)	data.top = dh - o.minHeight;
+		if (ismaxh && ch)	data.top = dh - o.maxHeight;
+		
+		// fixing jump error on top/left - bug #2330
+		var isNotwh = !data.width && !data.height;
+		if (isNotwh && !data.left && data.top) data.top = null;
+		else if (isNotwh && !data.top && data.left) data.left = null;
+		
+		return data;
+	},
+	_proportionallyResize: function() {
+		var o = this.options;
+		if (!o.proportionallyResize) return;
+		var prel = o.proportionallyResize, el = this.helper || this.element;
+		
+		if (!o.borderDif) {
+			var b = [prel.css('borderTopWidth'), prel.css('borderRightWidth'), prel.css('borderBottomWidth'), prel.css('borderLeftWidth')],
+				p = [prel.css('paddingTop'), prel.css('paddingRight'), prel.css('paddingBottom'), prel.css('paddingLeft')];
+			
+			o.borderDif = $.map(b, function(v, i) {
+				var border = parseInt(v,10)||0, padding = parseInt(p[i],10)||0;
+				return border + padding; 
+			});
+		}
+		prel.css({
+			height: (el.height() - o.borderDif[0] - o.borderDif[2]) + "px",
+			width: (el.width() - o.borderDif[1] - o.borderDif[3]) + "px"
+		});
+	},
+	_renderProxy: function() {
+		var el = this.element, o = this.options;
+		this.elementOffset = el.offset();
+		
+		if(o.helper) {
+			this.helper = this.helper || $('<div style="overflow:hidden;"></div>');
+			
+			// fix ie6 offset
+			var ie6 = $.browser.msie && $.browser.version < 7, ie6offset = (ie6 ? 1 : 0),
+			pxyoffset = ( ie6 ? 2 : -1 );
+			
+			this.helper.addClass(o.helper).css({
+				width: el.outerWidth() + pxyoffset,
+				height: el.outerHeight() + pxyoffset,
+				position: 'absolute',
+				left: this.elementOffset.left - ie6offset +'px',
+				top: this.elementOffset.top - ie6offset +'px',
+				zIndex: ++o.zIndex
+			});
+			
+			this.helper.appendTo("body");
+			
+			if (o.disableSelection)
+				$.ui.disableSelection(this.helper.get(0));
+			
+		} else {
+			this.helper = el; 
+		}
+	},
+	_change: {
+		e: function(e, dx, dy) {
+			return { width: this.originalSize.width + dx };
+		},
+		w: function(e, dx, dy) {
+			var o = this.options, cs = this.originalSize, sp = this.originalPosition;
+			return { left: sp.left + dx, width: cs.width - dx };
+		},
+		n: function(e, dx, dy) {
+			var o = this.options, cs = this.originalSize, sp = this.originalPosition;
+			return { top: sp.top + dy, height: cs.height - dy };
+		},
+		s: function(e, dx, dy) {
+			return { height: this.originalSize.height + dy };
+		},
+		se: function(e, dx, dy) {
+			return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [e, dx, dy]));
+		},
+		sw: function(e, dx, dy) {
+			return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [e, dx, dy]));
+		},
+		ne: function(e, dx, dy) {
+			return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [e, dx, dy]));
+		},
+		nw: function(e, dx, dy) {
+			return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [e, dx, dy]));
+		}
+	}
+}));
+
+$.extend($.ui.resizable, {
+	defaults: {
+		cancel: ":input",
+		distance: 1,
+		delay: 0,
+		preventDefault: true,
+		transparent: false,
+		minWidth: 10,
+		minHeight: 10,
+		aspectRatio: false,
+		disableSelection: true,
+		preserveCursor: true,
+		autoHide: false,
+		knobHandles: false
+	}
+});
+
+/*
+ * Resizable Extensions
+ */
+
+$.ui.plugin.add("resizable", "containment", {
+	
+	start: function(e, ui) {
+		var o = ui.options, self = $(this).data("resizable"), el = self.element;
+		var oc = o.containment,	ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
+		if (!ce) return;
+		
+		self.containerElement = $(ce);
+		
+		if (/document/.test(oc) || oc == document) {
+			self.containerOffset = { left: 0, top: 0 };
+			self.containerPosition = { left: 0, top: 0 };
+			
+			self.parentData = { 
+				element: $(document), left: 0, top: 0, 
+				width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
+			};
+		}
+		
+				
+		// i'm a node, so compute top, left, right, bottom
+		else{
+			self.containerOffset = $(ce).offset();
+			self.containerPosition = $(ce).position();
+			self.containerSize = { height: $(ce).innerHeight(), width: $(ce).innerWidth() };
+		
+			var co = self.containerOffset, ch = self.containerSize.height,	cw = self.containerSize.width, 
+						width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ), height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);
+		
+			self.parentData = { 
+				element: ce, left: co.left, top: co.top, width: width, height: height
+			};
+		}
+	},
+	
+	resize: function(e, ui) {
+		var o = ui.options, self = $(this).data("resizable"), 
+				ps = self.containerSize, co = self.containerOffset, cs = self.size, cp = self.position,
+				pRatio = o._aspectRatio || e.shiftKey, cop = { top:0, left:0 }, ce = self.containerElement;
+		
+		if (ce[0] != document && /static/.test(ce.css('position')))
+			cop = self.containerPosition;
+		
+		if (cp.left < (o.helper ? co.left : cop.left)) {
+			self.size.width = self.size.width + (o.helper ? (self.position.left - co.left) : (self.position.left - cop.left));
+			if (pRatio) self.size.height = self.size.width * o.aspectRatio;
+			self.position.left = o.helper ? co.left : cop.left;
+		}
+		
+		if (cp.top < (o.helper ? co.top : 0)) {
+			self.size.height = self.size.height + (o.helper ? (self.position.top - co.top) : self.position.top);
+			if (pRatio) self.size.width = self.size.height / o.aspectRatio;
+			self.position.top = o.helper ? co.top : 0;
+		}
+		
+		var woset = (o.helper ? self.offset.left - co.left : (self.position.left - cop.left)) + self.sizeDiff.width, 
+					hoset = (o.helper ? self.offset.top - co.top : self.position.top) + self.sizeDiff.height;
+		
+		if (woset + self.size.width >= self.parentData.width) {
+			self.size.width = self.parentData.width - woset;
+			if (pRatio) self.size.height = self.size.width * o.aspectRatio;
+		}
+		
+		if (hoset + self.size.height >= self.parentData.height) {
+			self.size.height = self.parentData.height - hoset;
+			if (pRatio) self.size.width = self.size.height / o.aspectRatio;
+		}
+	},
+	
+	stop: function(e, ui){
+		var o = ui.options, self = $(this).data("resizable"), cp = self.position,
+				co = self.containerOffset, cop = self.containerPosition, ce = self.containerElement;
+		
+		var helper = $(self.helper), ho = helper.offset(), w = helper.innerWidth(), h = helper.innerHeight();
+		
+		
+		if (o.helper && !o.animate && /relative/.test(ce.css('position')))
+			$(this).css({ left: (ho.left - co.left), top: (ho.top - co.top), width: w, height: h });
+		
+		if (o.helper && !o.animate && /static/.test(ce.css('position')))
+			$(this).css({ left: cop.left + (ho.left - co.left), top: cop.top + (ho.top - co.top), width: w, height: h });
+		
+	}
+});
+
+$.ui.plugin.add("resizable", "grid", {
+	
+	resize: function(e, ui) {
+		var o = ui.options, self = $(this).data("resizable"), cs = self.size, os = self.originalSize, op = self.originalPosition, a = self.axis, ratio = o._aspectRatio || e.shiftKey;
+		o.grid = typeof o.grid == "number" ? [o.grid, o.grid] : o.grid;
+		var ox = Math.round((cs.width - os.width) / (o.grid[0]||1)) * (o.grid[0]||1), oy = Math.round((cs.height - os.height) / (o.grid[1]||1)) * (o.grid[1]||1);
+		
+		if (/^(se|s|e)$/.test(a)) {
+			self.size.width = os.width + ox;
+			self.size.height = os.height + oy;
+		}
+		else if (/^(ne)$/.test(a)) {
+			self.size.width = os.width + ox;
+			self.size.height = os.height + oy;
+			self.position.top = op.top - oy;
+		}
+		else if (/^(sw)$/.test(a)) {
+			self.size.width = os.width + ox;
+			self.size.height = os.height + oy;
+			self.position.left = op.left - ox;
+		}
+		else {
+			self.size.width = os.width + ox;
+			self.size.height = os.height + oy;
+			self.position.top = op.top - oy;
+			self.position.left = op.left - ox;
+		}
+	}
+	
+});
+
+$.ui.plugin.add("resizable", "animate", {
+	
+	stop: function(e, ui) {
+		var o = ui.options, self = $(this).data("resizable");
+		
+		var pr = o.proportionallyResize, ista = pr && (/textarea/i).test(pr.get(0).nodeName), 
+						soffseth = ista && $.ui.hasScroll(pr.get(0), 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,
+							soffsetw = ista ? 0 : self.sizeDiff.width;
+		
+		var style = { width: (self.size.width - soffsetw), height: (self.size.height - soffseth) },
+					left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null, 
+						top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null; 
+		
+		self.element.animate(
+			$.extend(style, top && left ? { top: top, left: left } : {}), { 
+				duration: o.animateDuration || "slow", easing: o.animateEasing || "swing", 
+				step: function() {
+					
+					var data = {
+						width: parseInt(self.element.css('width'), 10),
+						height: parseInt(self.element.css('height'), 10),
+						top: parseInt(self.element.css('top'), 10),
+						left: parseInt(self.element.css('left'), 10)
+					};
+					
+					if (pr) pr.css({ width: data.width, height: data.height });
+					
+					// propagating resize, and updating values for each animation step
+					self._updateCache(data);
+					self.propagate("animate", e);
+					
+				}
+			}
+		);
+	}
+	
+});
+
+$.ui.plugin.add("resizable", "ghost", {
+	
+	start: function(e, ui) {
+		var o = ui.options, self = $(this).data("resizable"), pr = o.proportionallyResize, cs = self.size;
+		
+		if (!pr) self.ghost = self.element.clone();
+		else self.ghost = pr.clone();
+		
+		self.ghost.css(
+			{ opacity: .25, display: 'block', position: 'relative', height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 }
+		)
+		.addClass('ui-resizable-ghost').addClass(typeof o.ghost == 'string' ? o.ghost : '');
+		
+		self.ghost.appendTo(self.helper);
+		
+	},
+	
+	resize: function(e, ui){
+		var o = ui.options, self = $(this).data("resizable"), pr = o.proportionallyResize;
+		
+		if (self.ghost) self.ghost.css({ position: 'relative', height: self.size.height, width: self.size.width });
+		
+	},
+	
+	stop: function(e, ui){
+		var o = ui.options, self = $(this).data("resizable"), pr = o.proportionallyResize;
+		if (self.ghost && self.helper) self.helper.get(0).removeChild(self.ghost.get(0));
+	}
+	
+});
+
+$.ui.plugin.add("resizable", "alsoResize", {
+	
+	start: function(e, ui) {
+		var o = ui.options, self = $(this).data("resizable"), 
+		
+		_store = function(exp) {
+			$(exp).each(function() {
+				$(this).data("resizable-alsoresize", {
+					width: parseInt($(this).width(), 10), height: parseInt($(this).height(), 10),
+					left: parseInt($(this).css('left'), 10), top: parseInt($(this).css('top'), 10)
+				});
+			});
+		};
+		
+		if (typeof(o.alsoResize) == 'object') {
+			if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0];	_store(o.alsoResize); }
+			else { $.each(o.alsoResize, function(exp, c) { _store(exp); }); }
+		}else{
+			_store(o.alsoResize);
+		} 
+	},
+	
+	resize: function(e, ui){
+		var o = ui.options, self = $(this).data("resizable"), os = self.originalSize, op = self.originalPosition;
+		
+		var delta = { 
+			height: (self.size.height - os.height) || 0, width: (self.size.width - os.width) || 0,
+			top: (self.position.top - op.top) || 0, left: (self.position.left - op.left) || 0
+		},
+		
+		_alsoResize = function(exp, c) {
+			$(exp).each(function() {
+				var start = $(this).data("resizable-alsoresize"), style = {}, css = c && c.length ? c : ['width', 'height', 'top', 'left'];
+				
+				$.each(css || ['width', 'height', 'top', 'left'], function(i, prop) {
+					var sum = (start[prop]||0) + (delta[prop]||0);
+					if (sum && sum >= 0)
+						style[prop] = sum || null;
+				});
+				$(this).css(style);
+			});
+		};
+		
+		if (typeof(o.alsoResize) == 'object') {
+			$.each(o.alsoResize, function(exp, c) { _alsoResize(exp, c); });
+		}else{
+			_alsoResize(o.alsoResize);
+		}
+	},
+	
+	stop: function(e, ui){
+		$(this).removeData("resizable-alsoresize-start");
+	}
+});
+
+})(jQuery);
Index: /tags/2.0.2/template-common/lib/ui/ui.resizable.packed.js
===================================================================
--- /tags/2.0.2/template-common/lib/ui/ui.resizable.packed.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/ui.resizable.packed.js	(revision 3278)
@@ -0,0 +1,2 @@
+eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)d[e(c)]=k[c]||e(c);k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(h(A){A.4s("b.c",A.19({},A.b.4r,{4q:h(){f M=4,N=4.m;f Q=4.k.d("g");4.2v=4.k;4.k.1j("b-c").d({g:/20/.q(Q)?"1i":Q});A.19(N,{1N:!!(N.1a),l:N.l||N.12||N.1o?N.l||"4p":1g,1m:N.1m===1v?"b-c-1V-13":N.1m});f H="2E 3m #4o";N.3j={"b-c":{1W:"2d"},"b-c-13":{g:"1D",3o:"#3n",4n:"0.2E"},"b-c-n":{t:"n-o",8:"16",5:"p",1s:"p",2F:H},"b-c-s":{t:"s-o",8:"16",5:"p",1s:"p",2I:H},"b-c-e":{t:"e-o",6:"16",9:"p",1t:"p",2H:H},"b-c-w":{t:"w-o",6:"16",9:"p",1t:"p",2G:H},"b-c-y":{t:"y-o",6:"16",8:"16",2H:H,2I:H},"b-c-x":{t:"x-o",6:"16",8:"16",2I:H,2G:H},"b-c-Z":{t:"Z-o",6:"16",8:"16",2H:H,2F:H},"b-c-z":{t:"z-o",6:"16",8:"16",2G:H,2F:H}};N.2z={"b-c-13":{3o:"#3n",4m:"2E 3m #4l",8:"3l",6:"3l"},"b-c-n":{t:"n-o",9:"p",5:"45%"},"b-c-s":{t:"s-o",1t:"p",5:"45%"},"b-c-e":{t:"e-o",1s:"p",9:"45%"},"b-c-w":{t:"w-o",5:"p",9:"45%"},"b-c-y":{t:"y-o",1s:"p",1t:"p"},"b-c-x":{t:"x-o",5:"p",1t:"p"},"b-c-z":{t:"z-o",5:"p",9:"p"},"b-c-Z":{t:"Z-o",1s:"p",9:"p"}};N.2y=4.k[0].2f;a(N.2y.2x(/4k|1Y|2j|3f|3e|4j/i)){f B=4.k;a(/1i/.q(B.d("g"))&&A.1f.35){B.d({g:"1i",9:"1U",5:"1U"})}B.4i(A(\'<1E 3i="b-2t"	2o="2n: 2m;"></1E>\').d({g:B.d("g"),6:B.1x(),8:B.1w(),9:B.d("9"),5:B.d("5")}));f J=4.k;4.k=4.k.1P();4.k.11("c",4);4.k.d({2D:J.d("2D"),2C:J.d("2C"),2B:J.d("2B"),2A:J.d("2A")});J.d({2D:0,2C:0,2B:0,2A:0});a(A.1f.4h&&N.2V){J.d("o","3k")}N.1h=J.d({g:"20",4g:1,1W:"2d"});4.k.d({2c:J.d("2c")});4.1T()}a(!N.u){N.u=!A(".b-c-13",4.k).1K?"e,s,y":{n:".b-c-n",e:".b-c-e",s:".b-c-s",w:".b-c-w",y:".b-c-y",x:".b-c-x",Z:".b-c-Z",z:".b-c-z"}}a(N.u.3h==3g){N.1C=N.1C||4f;a(N.u=="4e"){N.u="n,e,s,w,y,x,Z,z"}f O=N.u.4d(",");N.u={};f G={13:"g: 1D; 1W: 3k; 2n:2m;",n:"9: 1r; 6:2a%;",e:"1s: 1r; 8:2a%;",s:"1t: 1r; 6:2a%;",w:"5: 1r; 8:2a%;",y:"1t: 1r; 1s: p;",x:"1t: 1r; 5: p;",Z:"9: 1r; 1s: p;",z:"9: 1r; 5: p;"};2s(f R=0;R<O.1K;R++){f S=A.4c(O[R]),L=N.3j,F="b-c-"+S,C=!A.b.d(F)&&!N.1m,P=A.b.d("b-c-1V-13"),T=A.19(L[F],L["b-c-13"]),D=A.19(N.2z[F],!P?N.2z["b-c-13"]:{});f K=/x|y|Z|z/.q(S)?{1C:++N.1C}:{};f I=(C?G[S]:""),E=A([\'<1E 3i="b-c-13 \',F,\'" 2o="\',I,G.13,\'"></1E>\'].2u("")).d(K);N.u[S]=".b-c-"+S;4.k.38(E.d(C?T:{}).d(N.1m?D:{}).1j(N.1m?"b-c-1V-13":"").1j(N.1m))}a(N.1m){4.k.1j("b-c-1V").d(!A.b.d("b-c-1V")?{}:{})}}4.3d=h(Y){Y=Y||4.k;2s(f V 36 N.u){a(N.u[V].3h==3g){N.u[V]=A(N.u[V],4.k).3b()}a(N.2i){N.u[V].d({2M:0})}a(4.k.2r(".b-2t")&&N.2y.2x(/1Y|2j|3f|3e/i)){f W=A(N.u[V],4.k),X=0;X=/x|Z|z|y|n|s/.q(V)?W.1w():W.1x();f U=["4b",/Z|z|n/.q(V)?"4a":/y|x|s/.q(V)?"49":/^e$/.q(V)?"48":"47"].2u("");a(!N.2i){Y.d(U,X)}4.1T()}a(!A(N.u[V]).1K){46}}};4.3d(4.k);N.1G=A(".b-c-13",M.k);a(N.1Q){N.1G.1y(h(U,V){A.b.1Q(V)})}N.1G.44(h(){a(!N.29){a(4.3c){f U=4.3c.2x(/b-c-(y|x|Z|z|n|e|s|w)/i)}M.1u=N.1u=U&&U[1]?U[1]:"y"}});a(N.2U){N.1G.3a();A(M.k).1j("b-c-2w").43(h(){A(4).39("b-c-2w");N.1G.3b()},h(){a(!N.29){A(4).1j("b-c-2w");N.1G.3a()}})}4.42()},41:{},b:h(){r{2v:4.2v,k:4.k,l:4.l,g:4.g,j:4.j,m:4.m,15:4.15,14:4.14}},1M:h(C,B){A.b.1z.40(4,C,[B,4.b()]);a(C!="o"){4.k.2Z(["o",C].2u(""),[B,4.b()],4.m[C])}},3Z:h(){f D=4.k,C=D.3Y(".b-c").1c(0);4.3X();f B=h(E){A(E).39("b-c b-c-37").2J("c").3W(".c").3V(".b-c-13").2p()};B(D);a(D.2r(".b-2t")&&C){D.1P().38(A(C).d({g:D.d("g"),6:D.1x(),8:D.1w(),9:D.d("9"),5:D.d("5")})).3U().2p();B(C)}},3T:h(K){a(4.m.37){r 1b}f J=1b;2s(f H 36 4.m.u){a(A(4.m.u[H])[0]==K.3S){J=1v}}a(!J){r 1b}f C=4.m,B=4.k.g(),D=4.k,I=h(O){r v(O,10)||0},G=A.1f.26&&A.1f.2l<7;C.29=1v;C.2q={9:A(1l).33(),5:A(1l).34()};a(D.2r(".b-3R")||(/1D/).q(D.d("g"))){f M=A.1f.26&&!C.1B&&(/1D/).q(D.d("g"))&&!(/1i/).q(D.1P().d("g"));f L=M?C.2q.9:0,F=M?C.2q.5:0;D.d({g:"1D",9:(B.9+L),5:(B.5+F)})}a(A.1f.35&&/1i/.q(D.d("g"))){D.d({g:"1i",9:"1U",5:"1U"})}4.2W();f N=I(4.l.d("5")),E=I(4.l.d("9"));a(C.1B){N+=A(C.1B).34()||0;E+=A(C.1B).33()||0}4.1k=4.l.1k();4.g={5:N,9:E};4.j=C.l||G?{6:D.1x(),8:D.1w()}:{6:D.6(),8:D.8()};4.15=C.l||G?{6:D.1x(),8:D.1w()}:{6:D.6(),8:D.8()};4.14={5:N,9:E};4.1p={6:D.1x()-D.6(),8:D.1w()-D.8()};4.32={5:K.31,9:K.30};C.1a=(1J C.1a=="2Q")?C.1a:((4.15.8/4.15.6)||1);a(C.2h){A("23").d("t",4.1u+"-o")}4.1M("1H",K);r 1v},3Q:h(I){f D=4.l,C=4.m,J={},M=4,F=4.32,K=4.1u;f N=(I.31-F.5)||0,L=(I.30-F.9)||0;f E=4.1e[K];a(!E){r 1b}f H=E.1n(4,[I,N,L]),G=A.1f.26&&A.1f.2l<7,B=4.1p;a(C.1N||I.1Z){H=4.2Y(H,I)}H=4.2X(H,I);4.1M("o",I);D.d({9:4.g.9+"1q",5:4.g.5+"1q",6:4.j.6+"1q",8:4.j.8+"1q"});a(!C.l&&C.1h){4.1T()}4.2e(H);4.k.2Z("o",[I,4.b()],4.m["o"]);r 1b},3P:h(I){4.m.29=1b;f E=4.m,H=h(M){r v(M,10)||0},K=4;a(E.l){f D=E.1h,B=D&&(/1Y/i).q(D.1c(0).2f),C=B&&A.b.1X(D.1c(0),"5")?0:K.1p.8,G=B?0:K.1p.6;f L={6:(K.j.6-G),8:(K.j.8-C)},F=(v(K.k.d("5"),10)+(K.g.5-K.14.5))||1g,J=(v(K.k.d("9"),10)+(K.g.9-K.14.9))||1g;a(!E.1o){4.k.d(A.19(L,{9:J,5:F}))}a(E.l&&!E.1o){4.1T()}}a(E.2h){A("23").d("t","1U")}4.1M("1I",I);a(E.l){4.l.2p()}r 1b},2e:h(B){f C=4.m;4.1k=4.l.1k();a(B.5){4.g.5=B.5}a(B.9){4.g.9=B.9}a(B.8){4.j.8=B.8}a(B.6){4.j.6=B.6}},2Y:h(D,E){f F=4.m,G=4.g,C=4.j,B=4.1u;a(D.8){D.6=(C.8/F.1a)}18{a(D.6){D.8=(C.6*F.1a)}}a(B=="x"){D.5=G.5+(C.6-D.6);D.9=1g}a(B=="z"){D.9=G.9+(C.8-D.8);D.5=G.5+(C.6-D.6)}r D},2X:h(H,I){f F=4.l,E=4.m,N=E.1N||I.1Z,M=4.1u,P=H.6&&E.28&&E.28<H.6,J=H.8&&E.27&&E.27<H.8,D=H.6&&E.1S&&E.1S>H.6,O=H.8&&E.1R&&E.1R>H.8;a(D){H.6=E.1S}a(O){H.8=E.1R}a(P){H.6=E.28}a(J){H.8=E.27}f C=4.14.5+4.15.6,L=4.g.9+4.j.8;f G=/x|z|w/.q(M),B=/z|Z|n/.q(M);a(D&&G){H.5=C-E.1S}a(P&&G){H.5=C-E.28}a(O&&B){H.9=L-E.1R}a(J&&B){H.9=L-E.27}f K=!H.6&&!H.8;a(K&&!H.5&&H.9){H.9=1g}18{a(K&&!H.9&&H.5){H.5=1g}}r H},1T:h(){f F=4.m;a(!F.1h){r}f D=F.1h,C=4.l||4.k;a(!F.1F){f B=[D.d("3O"),D.d("3N"),D.d("3M"),D.d("3L")],E=[D.d("3K"),D.d("3J"),D.d("3I"),D.d("3H")];F.1F=A.3G(B,h(G,I){f H=v(G,10)||0,J=v(E[I],10)||0;r H+J})}D.d({8:(C.8()-F.1F[0]-F.1F[2])+"1q",6:(C.6()-F.1F[1]-F.1F[3])+"1q"})},2W:h(){f C=4.k,F=4.m;4.2k=C.1k();a(F.l){4.l=4.l||A(\'<1E 2o="2n:2m;"></1E>\');f B=A.1f.26&&A.1f.2l<7,D=(B?1:0),E=(B?2:-1);4.l.1j(F.l).d({6:C.1x()+E,8:C.1w()+E,g:"1D",5:4.2k.5-D+"1q",9:4.2k.9-D+"1q",1C:++F.1C});4.l.2L("23");a(F.1Q){A.b.1Q(4.l.1c(0))}}18{4.l=C}},1e:{e:h(D,C,B){r{6:4.15.6+C}},w:h(F,C,B){f G=4.m,D=4.15,E=4.14;r{5:E.5+C,6:D.6-C}},n:h(F,C,B){f G=4.m,D=4.15,E=4.14;r{9:E.9+B,8:D.8-B}},s:h(D,C,B){r{8:4.15.8+B}},y:h(D,C,B){r A.19(4.1e.s.1n(4,24),4.1e.e.1n(4,[D,C,B]))},x:h(D,C,B){r A.19(4.1e.s.1n(4,24),4.1e.w.1n(4,[D,C,B]))},Z:h(D,C,B){r A.19(4.1e.n.1n(4,24),4.1e.e.1n(4,[D,C,B]))},z:h(D,C,B){r A.19(4.1e.n.1n(4,24),4.1e.w.1n(4,[D,C,B]))}}}));A.19(A.b.c,{3F:{3E:":2j",3D:1,3C:0,2V:1v,2i:1b,1S:10,1R:10,1a:1b,1Q:1v,2h:1v,2U:1b,1m:1b}});A.b.1z.1L("c","1B",{1H:h(I,K){f E=K.m,M=A(4).11("c"),G=M.k;f C=E.1B,F=(C 3B A)?C.1c(0):(/1P/.q(C))?G.1P().1c(0):C;a(!F){r}M.2g=A(F);a(/1l/.q(C)||C==1l){M.1O={5:0,9:0};M.21={5:0,9:0};M.1A={k:A(1l),5:0,9:0,6:A(1l).6(),8:A(1l).8()||1l.23.3A.2T}}18{M.1O=A(F).1k();M.21=A(F).g();M.22={8:A(F).2R(),6:A(F).2S()};f J=M.1O,B=M.22.8,H=M.22.6,D=(A.b.1X(F,"5")?F.3z:H),L=(A.b.1X(F)?F.2T:B);M.1A={k:F,5:J.5,9:J.9,6:D,8:L}}},o:h(H,K){f E=K.m,N=A(4).11("c"),C=N.22,J=N.1O,G=N.j,I=N.g,L=E.1N||H.1Z,B={9:0,5:0},D=N.2g;a(D[0]!=1l&&/20/.q(D.d("g"))){B=N.21}a(I.5<(E.l?J.5:B.5)){N.j.6=N.j.6+(E.l?(N.g.5-J.5):(N.g.5-B.5));a(L){N.j.8=N.j.6*E.1a}N.g.5=E.l?J.5:B.5}a(I.9<(E.l?J.9:0)){N.j.8=N.j.8+(E.l?(N.g.9-J.9):N.g.9);a(L){N.j.6=N.j.8/E.1a}N.g.9=E.l?J.9:0}f F=(E.l?N.1k.5-J.5:(N.g.5-B.5))+N.1p.6,M=(E.l?N.1k.9-J.9:N.g.9)+N.1p.8;a(F+N.j.6>=N.1A.6){N.j.6=N.1A.6-F;a(L){N.j.8=N.j.6*E.1a}}a(M+N.j.8>=N.1A.8){N.j.8=N.1A.8-M;a(L){N.j.6=N.j.8/E.1a}}},1I:h(G,J){f C=J.m,L=A(4).11("c"),H=L.g,I=L.1O,B=L.21,D=L.2g;f E=A(L.l),M=E.1k(),K=E.2S(),F=E.2R();a(C.l&&!C.1o&&/1i/.q(D.d("g"))){A(4).d({5:(M.5-I.5),9:(M.9-I.9),6:K,8:F})}a(C.l&&!C.1o&&/20/.q(D.d("g"))){A(4).d({5:B.5+(M.5-I.5),9:B.9+(M.9-I.9),6:K,8:F})}}});A.b.1z.1L("c","1d",{o:h(H,J){f D=J.m,L=A(4).11("c"),G=L.j,E=L.15,F=L.14,K=L.1u,I=D.1N||H.1Z;D.1d=1J D.1d=="2Q"?[D.1d,D.1d]:D.1d;f C=2P.2O((G.6-E.6)/(D.1d[0]||1))*(D.1d[0]||1),B=2P.2O((G.8-E.8)/(D.1d[1]||1))*(D.1d[1]||1);a(/^(y|s|e)$/.q(K)){L.j.6=E.6+C;L.j.8=E.8+B}18{a(/^(Z)$/.q(K)){L.j.6=E.6+C;L.j.8=E.8+B;L.g.9=F.9-B}18{a(/^(x)$/.q(K)){L.j.6=E.6+C;L.j.8=E.8+B;L.g.5=F.5-C}18{L.j.6=E.6+C;L.j.8=E.8+B;L.g.9=F.9-B;L.g.5=F.5-C}}}}});A.b.1z.1L("c","1o",{1I:h(I,K){f F=K.m,L=A(4).11("c");f E=F.1h,B=E&&(/1Y/i).q(E.1c(0).2f),C=B&&A.b.1X(E.1c(0),"5")?0:L.1p.8,H=B?0:L.1p.6;f D={6:(L.j.6-H),8:(L.j.8-C)},G=(v(L.k.d("5"),10)+(L.g.5-L.14.5))||1g,J=(v(L.k.d("9"),10)+(L.g.9-L.14.9))||1g;L.k.1o(A.19(D,J&&G?{9:J,5:G}:{}),{3y:F.3x||"3w",3v:F.3u||"3t",3s:h(){f M={6:v(L.k.d("6"),10),8:v(L.k.d("8"),10),9:v(L.k.d("9"),10),5:v(L.k.d("5"),10)};a(E){E.d({6:M.6,8:M.8})}L.2e(M);L.1M("1o",I)}})}});A.b.1z.1L("c","12",{1H:h(E,D){f F=D.m,B=A(4).11("c"),G=F.1h,C=B.j;a(!G){B.12=B.k.2N()}18{B.12=G.2N()}B.12.d({2M:0.25,1W:"2d",g:"1i",8:C.8,6:C.6,2c:0,5:0,9:0}).1j("b-c-12").1j(1J F.12=="3r"?F.12:"");B.12.2L(B.l)},o:h(D,C){f E=C.m,B=A(4).11("c"),F=E.1h;a(B.12){B.12.d({g:"1i",8:B.j.8,6:B.j.6})}},1I:h(D,C){f E=C.m,B=A(4).11("c"),F=E.1h;a(B.12&&B.l){B.l.1c(0).3q(B.12.1c(0))}}});A.b.1z.1L("c","17",{1H:h(E,C){f F=C.m,B=A(4).11("c"),D=h(G){A(G).1y(h(){A(4).11("c-2b",{6:v(A(4).6(),10),8:v(A(4).8(),10),5:v(A(4).d("5"),10),9:v(A(4).d("9"),10)})})};a(1J(F.17)=="2K"){a(F.17.1K){F.17=F.17[0];D(F.17)}18{A.1y(F.17,h(G,H){D(G)})}}18{D(F.17)}},o:h(F,E){f G=E.m,C=A(4).11("c"),D=C.15,I=C.14;f H={8:(C.j.8-D.8)||0,6:(C.j.6-D.6)||0,9:(C.g.9-I.9)||0,5:(C.g.5-I.5)||0},B=h(J,K){A(J).1y(h(){f N=A(4).11("c-2b"),M={},L=K&&K.1K?K:["6","8","9","5"];A.1y(L||["6","8","9","5"],h(O,Q){f P=(N[Q]||0)+(H[Q]||0);a(P&&P>=0){M[Q]=P||1g}});A(4).d(M)})};a(1J(G.17)=="2K"){A.1y(G.17,h(J,K){B(J,K)})}18{B(G.17)}},1I:h(C,B){A(4).2J("c-2b-1H")}})})(3p)',62,277,'||||this|left|width||height|top|if|ui|resizable|css||var|position|function||size|element|helper|options||resize|0px|test|return||cursor|handles|parseInt||sw|se|nw||||||||||||||||||||||||||ne||data|ghost|handle|originalPosition|originalSize|4px|alsoResize|else|extend|aspectRatio|false|get|grid|_change|browser|null|proportionallyResize|relative|addClass|offset|document|knobHandles|apply|animate|sizeDiff|px|0pt|right|bottom|axis|true|outerHeight|outerWidth|each|plugin|parentData|containment|zIndex|absolute|div|borderDif|_handles|start|stop|typeof|length|add|propagate|_aspectRatio|containerOffset|parent|disableSelection|minHeight|minWidth|_proportionallyResize|auto|knob|display|hasScroll|textarea|shiftKey|static|containerPosition|containerSize|body|arguments||msie|maxHeight|maxWidth|resizing|100|alsoresize|margin|block|_updateCache|nodeName|containerElement|preserveCursor|transparent|input|elementOffset|version|hidden|overflow|style|remove|documentScroll|is|for|wrapper|join|originalElement|autohide|match|_nodeName|knobTheme|marginBottom|marginRight|marginTop|marginLeft|1px|borderTop|borderLeft|borderRight|borderBottom|removeData|object|appendTo|opacity|clone|round|Math|number|innerHeight|innerWidth|scrollHeight|autoHide|preventDefault|_renderProxy|_respectSize|_updateRatio|triggerHandler|pageY|pageX|originalMousePosition|scrollTop|scrollLeft|opera|in|disabled|append|removeClass|hide|show|className|_renderAxis|button|select|String|constructor|class|defaultTheme|none|8px|solid|F2F2F2|background|jQuery|removeChild|string|step|swing|animateEasing|easing|slow|animateDuration|duration|scrollWidth|parentNode|instanceof|delay|distance|cancel|defaults|map|paddingLeft|paddingBottom|paddingRight|paddingTop|borderLeftWidth|borderBottomWidth|borderRightWidth|borderTopWidth|mouseStop|mouseDrag|draggable|target|mouseStart|end|find|unbind|mouseDestroy|children|destroy|call|plugins|mouseInit|hover|mouseover||continue|Left|Right|Bottom|Top|padding|trim|split|all|1000|zoom|safari|wrap|img|canvas|808080|border|fontSize|DEDEDE|proxy|init|mouse|widget'.split('|'),0,{}))
+
Index: /tags/2.0.2/template-common/lib/ui/ui.selectable.js
===================================================================
--- /tags/2.0.2/template-common/lib/ui/ui.selectable.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/ui.selectable.js	(revision 3278)
@@ -0,0 +1,264 @@
+/*
+ * jQuery UI Selectable
+ *
+ * Copyright (c) 2008 Richard D. Worth (rdworth.org)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ * 
+ * http://docs.jquery.com/UI/Selectables
+ *
+ * Depends:
+ *	ui.core.js
+ */
+(function($) {
+
+$.widget("ui.selectable", $.extend({}, $.ui.mouse, {
+	init: function() {
+		var self = this;
+		
+		this.element.addClass("ui-selectable");
+		
+		this.dragged = false;
+
+		// cache selectee children based on filter
+		var selectees;
+		this.refresh = function() {
+			selectees = $(self.options.filter, self.element[0]);
+			selectees.each(function() {
+				var $this = $(this);
+				var pos = $this.offset();
+				$.data(this, "selectable-item", {
+					element: this,
+					$element: $this,
+					left: pos.left,
+					top: pos.top,
+					right: pos.left + $this.width(),
+					bottom: pos.top + $this.height(),
+					startselected: false,
+					selected: $this.hasClass('ui-selected'),
+					selecting: $this.hasClass('ui-selecting'),
+					unselecting: $this.hasClass('ui-unselecting')
+				});
+			});
+		};
+		this.refresh();
+
+		this.selectees = selectees.addClass("ui-selectee");
+		
+		this.mouseInit();
+		
+		this.helper = $(document.createElement('div')).css({border:'1px dotted black'});
+	},
+	toggle: function() {
+		if(this.options.disabled){
+			this.enable();
+		} else {
+			this.disable();
+		}
+	},
+	destroy: function() {
+		this.element
+			.removeClass("ui-selectable ui-selectable-disabled")
+			.removeData("selectable")
+			.unbind(".selectable");
+		this.mouseDestroy();
+	},
+	mouseStart: function(e) {
+		var self = this;
+		
+		this.opos = [e.pageX, e.pageY];
+		
+		if (this.options.disabled)
+			return;
+
+		var options = this.options;
+
+		this.selectees = $(options.filter, this.element[0]);
+
+		// selectable START callback
+		this.element.triggerHandler("selectablestart", [e, {
+			"selectable": this.element[0],
+			"options": options
+		}], options.start);
+
+		$('body').append(this.helper);
+		// position helper (lasso)
+		this.helper.css({
+			"z-index": 100,
+			"position": "absolute",
+			"left": e.clientX,
+			"top": e.clientY,
+			"width": 0,
+			"height": 0
+		});
+
+		if (options.autoRefresh) {
+			this.refresh();
+		}
+
+		this.selectees.filter('.ui-selected').each(function() {
+			var selectee = $.data(this, "selectable-item");
+			selectee.startselected = true;
+			if (!e.ctrlKey) {
+				selectee.$element.removeClass('ui-selected');
+				selectee.selected = false;
+				selectee.$element.addClass('ui-unselecting');
+				selectee.unselecting = true;
+				// selectable UNSELECTING callback
+				self.element.triggerHandler("selectableunselecting", [e, {
+					selectable: self.element[0],
+					unselecting: selectee.element,
+					options: options
+				}], options.unselecting);
+			}
+		});
+		
+		var isSelectee = false;
+		$(e.target).parents().andSelf().each(function() {
+			if($.data(this, "selectable-item")) isSelectee = true;
+		});
+		return this.options.keyboard ? !isSelectee : true;
+	},
+	mouseDrag: function(e) {
+		var self = this;
+		this.dragged = true;
+		
+		if (this.options.disabled)
+			return;
+
+		var options = this.options;
+
+		var x1 = this.opos[0], y1 = this.opos[1], x2 = e.pageX, y2 = e.pageY;
+		if (x1 > x2) { var tmp = x2; x2 = x1; x1 = tmp; }
+		if (y1 > y2) { var tmp = y2; y2 = y1; y1 = tmp; }
+		this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});
+
+		this.selectees.each(function() {
+			var selectee = $.data(this, "selectable-item");
+			//prevent helper from being selected if appendTo: selectable
+			if (!selectee || selectee.element == self.element[0])
+				return;
+			var hit = false;
+			if (options.tolerance == 'touch') {
+				hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
+			} else if (options.tolerance == 'fit') {
+				hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
+			}
+
+			if (hit) {
+				// SELECT
+				if (selectee.selected) {
+					selectee.$element.removeClass('ui-selected');
+					selectee.selected = false;
+				}
+				if (selectee.unselecting) {
+					selectee.$element.removeClass('ui-unselecting');
+					selectee.unselecting = false;
+				}
+				if (!selectee.selecting) {
+					selectee.$element.addClass('ui-selecting');
+					selectee.selecting = true;
+					// selectable SELECTING callback
+					self.element.triggerHandler("selectableselecting", [e, {
+						selectable: self.element[0],
+						selecting: selectee.element,
+						options: options
+					}], options.selecting);
+				}
+			} else {
+				// UNSELECT
+				if (selectee.selecting) {
+					if (e.ctrlKey && selectee.startselected) {
+						selectee.$element.removeClass('ui-selecting');
+						selectee.selecting = false;
+						selectee.$element.addClass('ui-selected');
+						selectee.selected = true;
+					} else {
+						selectee.$element.removeClass('ui-selecting');
+						selectee.selecting = false;
+						if (selectee.startselected) {
+							selectee.$element.addClass('ui-unselecting');
+							selectee.unselecting = true;
+						}
+						// selectable UNSELECTING callback
+						self.element.triggerHandler("selectableunselecting", [e, {
+							selectable: self.element[0],
+							unselecting: selectee.element,
+							options: options
+						}], options.unselecting);
+					}
+				}
+				if (selectee.selected) {
+					if (!e.ctrlKey && !selectee.startselected) {
+						selectee.$element.removeClass('ui-selected');
+						selectee.selected = false;
+
+						selectee.$element.addClass('ui-unselecting');
+						selectee.unselecting = true;
+						// selectable UNSELECTING callback
+						self.element.triggerHandler("selectableunselecting", [e, {
+							selectable: self.element[0],
+							unselecting: selectee.element,
+							options: options
+						}], options.unselecting);
+					}
+				}
+			}
+		});
+		
+		return false;
+	},
+	mouseStop: function(e) {
+		var self = this;
+		
+		this.dragged = false;
+		
+		var options = this.options;
+
+		$('.ui-unselecting', this.element[0]).each(function() {
+			var selectee = $.data(this, "selectable-item");
+			selectee.$element.removeClass('ui-unselecting');
+			selectee.unselecting = false;
+			selectee.startselected = false;
+			self.element.triggerHandler("selectableunselected", [e, {
+				selectable: self.element[0],
+				unselected: selectee.element,
+				options: options
+			}], options.unselected);
+		});
+		$('.ui-selecting', this.element[0]).each(function() {
+			var selectee = $.data(this, "selectable-item");
+			selectee.$element.removeClass('ui-selecting').addClass('ui-selected');
+			selectee.selecting = false;
+			selectee.selected = true;
+			selectee.startselected = true;
+			self.element.triggerHandler("selectableselected", [e, {
+				selectable: self.element[0],
+				selected: selectee.element,
+				options: options
+			}], options.selected);
+		});
+		this.element.triggerHandler("selectablestop", [e, {
+			selectable: self.element[0],
+			options: this.options
+		}], this.options.stop);
+		
+		this.helper.remove();
+		
+		return false;
+	}
+}));
+
+$.extend($.ui.selectable, {
+	defaults: {
+		distance: 1,
+		delay: 0,
+		cancel: ":input",
+		appendTo: 'body',
+		autoRefresh: true,
+		filter: '*',
+		tolerance: 'touch'
+	}
+});
+
+})(jQuery);
Index: /tags/2.0.2/template-common/lib/ui/ui.selectable.packed.js
===================================================================
--- /tags/2.0.2/template-common/lib/ui/ui.selectable.packed.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/ui.selectable.packed.js	(revision 3278)
@@ -0,0 +1,2 @@
+eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)d[e(c)]=k[c]||e(c);k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(d(A){A.1M("4.5",A.V({},A.4.1L,{1K:d(){8 B=2;2.3.h("4-5");2.v=b;8 C;2.Q=d(){C=A(B.9.q,B.3[0]);C.o(d(){8 D=A(2);8 E=D.1J();A.n(2,"5-m",{3:2,$3:D,k:E.k,j:E.j,L:E.k+D.N(),y:E.j+D.M(),i:b,a:D.R("4-a"),c:D.R("4-c"),6:D.R("4-6")})})};2.Q();2.s=C.h("4-1I");2.1H();2.p=A(1G.1F("1E")).O({1D:"1C 1B 1A"})},1z:d(){7(2.9.t){2.1y()}r{2.1x()}},1w:d(){2.3.f("4-5 4-5-t").1v("5").1u(".5");2.1t()},1s:d(E){8 C=2;2.P=[E.Y,E.X];7(2.9.t){l}8 D=2.9;2.s=A(D.q,2.3[0]);2.3.g("1r",[E,{"5":2.3[0],"9":D}],D.1q);A("U").1p(2.p);2.p.O({"z-1o":1n,"1m":"1l","k":E.1k,"j":E.1j,"N":0,"M":0});7(D.T){2.Q()}2.s.q(".4-a").o(d(){8 F=A.n(2,"5-m");F.i=e;7(!E.x){F.$3.f("4-a");F.a=b;F.$3.h("4-6");F.6=e;C.3.g("w",[E,{5:C.3[0],6:F.3,9:D}],D.6)}});8 B=b;A(E.1i).1h().1g().o(d(){7(A.n(2,"5-m")){B=e}});l 2.9.1f?!B:e},1e:d(I){8 C=2;2.v=e;7(2.9.t){l}8 E=2.9;8 D=2.P[0],H=2.P[1],B=I.Y,G=I.X;7(D>B){8 F=B;B=D;D=F}7(H>G){8 F=G;G=H;H=F}2.p.O({k:D,j:H,N:B-D,M:G-H});2.s.o(d(){8 J=A.n(2,"5-m");7(!J||J.3==C.3[0]){l}8 K=b;7(E.u=="S"){K=(!(J.k>B||J.L<D||J.j>G||J.y<H))}r{7(E.u=="1d"){K=(J.k>D&&J.L<B&&J.j>H&&J.y<G)}}7(K){7(J.a){J.$3.f("4-a");J.a=b}7(J.6){J.$3.f("4-6");J.6=b}7(!J.c){J.$3.h("4-c");J.c=e;C.3.g("1c",[I,{5:C.3[0],c:J.3,9:E}],E.c)}}r{7(J.c){7(I.x&&J.i){J.$3.f("4-c");J.c=b;J.$3.h("4-a");J.a=e}r{J.$3.f("4-c");J.c=b;7(J.i){J.$3.h("4-6");J.6=e}C.3.g("w",[I,{5:C.3[0],6:J.3,9:E}],E.6)}}7(J.a){7(!I.x&&!J.i){J.$3.f("4-a");J.a=b;J.$3.h("4-6");J.6=e;C.3.g("w",[I,{5:C.3[0],6:J.3,9:E}],E.6)}}}});l b},1b:d(D){8 B=2;2.v=b;8 C=2.9;A(".4-6",2.3[0]).o(d(){8 E=A.n(2,"5-m");E.$3.f("4-6");E.6=b;E.i=b;B.3.g("1a",[D,{5:B.3[0],W:E.3,9:C}],C.W)});A(".4-c",2.3[0]).o(d(){8 E=A.n(2,"5-m");E.$3.f("4-c").h("4-a");E.c=b;E.a=e;E.i=e;B.3.g("19",[D,{5:B.3[0],a:E.3,9:C}],C.a)});2.3.g("18",[D,{5:B.3[0],9:2.9}],2.9.17);2.p.16();l b}}));A.V(A.4.5,{15:{14:1,13:0,12:":11",10:"U",T:e,q:"*",u:"S"}})})(Z)',62,111,'||this|element|ui|selectable|unselecting|if|var|options|selected|false|selecting|function|true|removeClass|triggerHandler|addClass|startselected|top|left|return|item|data|each|helper|filter|else|selectees|disabled|tolerance|dragged|selectableunselecting|ctrlKey|bottom|||||||||||||right|height|width|css|opos|refresh|hasClass|touch|autoRefresh|body|extend|unselected|pageY|pageX|jQuery|appendTo|input|cancel|delay|distance|defaults|remove|stop|selectablestop|selectableselected|selectableunselected|mouseStop|selectableselecting|fit|mouseDrag|keyboard|andSelf|parents|target|clientY|clientX|absolute|position|100|index|append|start|selectablestart|mouseStart|mouseDestroy|unbind|removeData|destroy|disable|enable|toggle|black|dotted|1px|border|div|createElement|document|mouseInit|selectee|offset|init|mouse|widget'.split('|'),0,{}))
+
Index: /tags/2.0.2/template-common/lib/ui/ui.slider.js
===================================================================
--- /tags/2.0.2/template-common/lib/ui/ui.slider.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/ui.slider.js	(revision 3278)
@@ -0,0 +1,440 @@
+/*
+ * jQuery UI Slider
+ *
+ * Copyright (c) 2008 Paul Bakaus
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ * 
+ * http://docs.jquery.com/UI/Slider
+ *
+ * Depends:
+ *	ui.core.js
+ */
+(function($) {
+
+$.fn.unwrap = $.fn.unwrap || function(expr) {
+  return this.each(function(){
+     $(this).parents(expr).eq(0).after(this).remove();
+  });
+};
+
+$.widget("ui.slider", {
+	plugins: {},
+	ui: function(e) {
+		return {
+			options: this.options,
+			handle: this.currentHandle,
+			value: this.options.axis != "both" || !this.options.axis ? Math.round(this.value(null,this.options.axis == "vertical" ? "y" : "x")) : {
+				x: Math.round(this.value(null,"x")),
+				y: Math.round(this.value(null,"y"))
+			},
+			range: this.getRange()
+		};
+	},
+	propagate: function(n,e) {
+		$.ui.plugin.call(this, n, [e, this.ui()]);
+		this.element.triggerHandler(n == "slide" ? n : "slide"+n, [e, this.ui()], this.options[n]);
+	},
+	destroy: function() {
+		
+		this.element
+			.removeClass("ui-slider ui-slider-disabled")
+			.removeData("slider")
+			.unbind(".slider");
+		
+		if(this.handle && this.handle.length) {
+			this.handle
+				.unwrap("a");
+			this.handle.each(function() {
+				$(this).data("mouse").mouseDestroy();
+			});
+		}
+		
+		this.generated && this.generated.remove();
+		
+	},
+	setData: function(key, value) {
+		$.widget.prototype.setData.apply(this, arguments);
+		if (/min|max|steps/.test(key)) {
+			this.initBoundaries();
+		}
+		
+		if(key == "range") {
+			value ? this.handle.length == 2 && this.createRange() : this.removeRange();
+		}
+		
+	},
+
+	init: function() {
+		
+		var self = this;
+		this.element.addClass("ui-slider");
+		this.initBoundaries();
+		
+		// Initialize mouse and key events for interaction
+		this.handle = $(this.options.handle, this.element);
+		if (!this.handle.length) {
+			self.handle = self.generated = $(self.options.handles || [0]).map(function() {
+				var handle = $("<div/>").addClass("ui-slider-handle").appendTo(self.element);
+				if (this.id)
+					handle.attr("id", this.id);
+				return handle[0];
+			});
+		}
+		
+		
+		var handleclass = function(el) {
+			this.element = $(el);
+			this.element.data("mouse", this);
+			this.options = self.options;
+			
+			this.element.bind("mousedown", function() {
+				if(self.currentHandle) this.blur(self.currentHandle);
+				self.focus(this,1);
+			});
+			
+			this.mouseInit();
+		};
+		
+		$.extend(handleclass.prototype, $.ui.mouse, {
+			mouseStart: function(e) { return self.start.call(self, e, this.element[0]); },
+			mouseStop: function(e) { return self.stop.call(self, e, this.element[0]); },
+			mouseDrag: function(e) { return self.drag.call(self, e, this.element[0]); },
+			mouseCapture: function() { return true; },
+			trigger: function(e) { this.mouseDown(e); }
+		});
+		
+		
+		$(this.handle)
+			.each(function() {
+				new handleclass(this);
+			})
+			.wrap('<a href="javascript:void(0)" style="outline:none;border:none;"></a>')
+			.parent()
+				.bind('focus', function(e) { self.focus(this.firstChild); })
+				.bind('blur', function(e) { self.blur(this.firstChild); })
+				.bind('keydown', function(e) { if(!self.options.noKeyboard) self.keydown(e.keyCode, this.firstChild); })
+		;
+		
+		// Bind the click to the slider itself
+		this.element.bind('mousedown.slider', function(e) {
+			self.click.apply(self, [e]);
+			self.currentHandle.data("mouse").trigger(e);
+			self.firstValue = self.firstValue + 1; //This is for always triggering the change event
+		});
+		
+		// Move the first handle to the startValue
+		$.each(this.options.handles || [], function(index, handle) {
+			self.moveTo(handle.start, index, true);
+		});
+		if (!isNaN(this.options.startValue))
+			this.moveTo(this.options.startValue, 0, true);
+
+		this.previousHandle = $(this.handle[0]); //set the previous handle to the first to allow clicking before selecting the handle
+		if(this.handle.length == 2 && this.options.range) this.createRange();
+	},
+	initBoundaries: function() {
+		
+		var element = this.element[0], o = this.options;
+		this.actualSize = { width: this.element.outerWidth() , height: this.element.outerHeight() };			
+		
+		$.extend(o, {
+			axis: o.axis || (element.offsetWidth < element.offsetHeight ? 'vertical' : 'horizontal'),
+			max: !isNaN(parseInt(o.max,10)) ? { x: parseInt(o.max, 10), y: parseInt(o.max, 10) } : ({ x: o.max && o.max.x || 100, y: o.max && o.max.y || 100 }),
+			min: !isNaN(parseInt(o.min,10)) ? { x: parseInt(o.min, 10), y: parseInt(o.min, 10) } : ({ x: o.min && o.min.x || 0, y: o.min && o.min.y || 0 })
+		});
+		//Prepare the real maxValue
+		o.realMax = {
+			x: o.max.x - o.min.x,
+			y: o.max.y - o.min.y
+		};
+		//Calculate stepping based on steps
+		o.stepping = {
+			x: o.stepping && o.stepping.x || parseInt(o.stepping, 10) || (o.steps ? o.realMax.x/(o.steps.x || parseInt(o.steps, 10) || o.realMax.x) : 0),
+			y: o.stepping && o.stepping.y || parseInt(o.stepping, 10) || (o.steps ? o.realMax.y/(o.steps.y || parseInt(o.steps, 10) || o.realMax.y) : 0)
+		};
+	},
+
+	
+	keydown: function(keyCode, handle) {
+		if(/(37|38|39|40)/.test(keyCode)) {
+			this.moveTo({
+				x: /(37|39)/.test(keyCode) ? (keyCode == 37 ? '-' : '+') + '=' + this.oneStep("x") : 0,
+				y: /(38|40)/.test(keyCode) ? (keyCode == 38 ? '-' : '+') + '=' + this.oneStep("y") : 0
+			}, handle);
+		}
+	},
+	focus: function(handle,hard) {
+		this.currentHandle = $(handle).addClass('ui-slider-handle-active');
+		if (hard)
+			this.currentHandle.parent()[0].focus();
+	},
+	blur: function(handle) {
+		$(handle).removeClass('ui-slider-handle-active');
+		if(this.currentHandle && this.currentHandle[0] == handle) { this.previousHandle = this.currentHandle; this.currentHandle = null; };
+	},
+	click: function(e) {
+		// This method is only used if:
+		// - The user didn't click a handle
+		// - The Slider is not disabled
+		// - There is a current, or previous selected handle (otherwise we wouldn't know which one to move)
+		
+		var pointer = [e.pageX,e.pageY];
+		
+		var clickedHandle = false;
+		this.handle.each(function() {
+			if(this == e.target)
+				clickedHandle = true;
+		});
+		if (clickedHandle || this.options.disabled || !(this.currentHandle || this.previousHandle))
+			return;
+
+		// If a previous handle was focussed, focus it again
+		if (!this.currentHandle && this.previousHandle)
+			this.focus(this.previousHandle, true);
+		
+		// propagate only for distance > 0, otherwise propagation is done my drag
+		this.offset = this.element.offset();
+
+		this.moveTo({
+			y: this.convertValue(e.pageY - this.offset.top - this.currentHandle[0].offsetHeight/2, "y"),
+			x: this.convertValue(e.pageX - this.offset.left - this.currentHandle[0].offsetWidth/2, "x")
+		}, null, !this.options.distance);
+	},
+	
+
+
+	createRange: function() {
+		if(this.rangeElement) return;
+		this.rangeElement = $('<div></div>')
+			.addClass('ui-slider-range')
+			.css({ position: 'absolute' })
+			.appendTo(this.element);
+		this.updateRange();
+	},
+	removeRange: function() {
+		this.rangeElement.remove();
+		this.rangeElement = null;
+	},
+	updateRange: function() {
+			var prop = this.options.axis == "vertical" ? "top" : "left";
+			var size = this.options.axis == "vertical" ? "height" : "width";
+			this.rangeElement.css(prop, (parseInt($(this.handle[0]).css(prop),10) || 0) + this.handleSize(0, this.options.axis == "vertical" ? "y" : "x")/2);
+			this.rangeElement.css(size, (parseInt($(this.handle[1]).css(prop),10) || 0) - (parseInt($(this.handle[0]).css(prop),10) || 0));
+	},
+	getRange: function() {
+		return this.rangeElement ? this.convertValue(parseInt(this.rangeElement.css(this.options.axis == "vertical" ? "height" : "width"),10), this.options.axis == "vertical" ? "y" : "x") : null;
+	},
+
+	handleIndex: function() {
+		return this.handle.index(this.currentHandle[0]);
+	},
+	value: function(handle, axis) {
+		if(this.handle.length == 1) this.currentHandle = this.handle;
+		if(!axis) axis = this.options.axis == "vertical" ? "y" : "x";
+
+		var curHandle = $(handle != undefined && handle !== null ? this.handle[handle] || handle : this.currentHandle);
+		
+		if(curHandle.data("mouse").sliderValue) {
+			return parseInt(curHandle.data("mouse").sliderValue[axis],10);
+		} else {
+			return parseInt(((parseInt(curHandle.css(axis == "x" ? "left" : "top"),10) / (this.actualSize[axis == "x" ? "width" : "height"] - this.handleSize(handle,axis))) * this.options.realMax[axis]) + this.options.min[axis],10);
+		}
+
+	},
+	convertValue: function(value,axis) {
+		return this.options.min[axis] + (value / (this.actualSize[axis == "x" ? "width" : "height"] - this.handleSize(null,axis))) * this.options.realMax[axis];
+	},
+	
+	translateValue: function(value,axis) {
+		return ((value - this.options.min[axis]) / this.options.realMax[axis]) * (this.actualSize[axis == "x" ? "width" : "height"] - this.handleSize(null,axis));
+	},
+	translateRange: function(value,axis) {
+		if (this.rangeElement) {
+			if (this.currentHandle[0] == this.handle[0] && value >= this.translateValue(this.value(1),axis))
+				value = this.translateValue(this.value(1,axis) - this.oneStep(axis), axis);
+			if (this.currentHandle[0] == this.handle[1] && value <= this.translateValue(this.value(0),axis))
+				value = this.translateValue(this.value(0,axis) + this.oneStep(axis), axis);
+		}
+		if (this.options.handles) {
+			var handle = this.options.handles[this.handleIndex()];
+			if (value < this.translateValue(handle.min,axis)) {
+				value = this.translateValue(handle.min,axis);
+			} else if (value > this.translateValue(handle.max,axis)) {
+				value = this.translateValue(handle.max,axis);
+			}
+		}
+		return value;
+	},
+	translateLimits: function(value,axis) {
+		if (value >= this.actualSize[axis == "x" ? "width" : "height"] - this.handleSize(null,axis))
+			value = this.actualSize[axis == "x" ? "width" : "height"] - this.handleSize(null,axis);
+		if (value <= 0)
+			value = 0;
+		return value;
+	},
+	handleSize: function(handle,axis) {
+		return $(handle != undefined && handle !== null ? this.handle[handle] : this.currentHandle)[0]["offset"+(axis == "x" ? "Width" : "Height")];	
+	},
+	oneStep: function(axis) {
+		return this.options.stepping[axis] || 1;
+	},
+
+
+	start: function(e, handle) {
+	
+		var o = this.options;
+		if(o.disabled) return false;
+
+		// Prepare the outer size
+		this.actualSize = { width: this.element.outerWidth() , height: this.element.outerHeight() };
+	
+		// This is a especially ugly fix for strange blur events happening on mousemove events
+		if (!this.currentHandle)
+			this.focus(this.previousHandle, true); 
+
+		this.offset = this.element.offset();
+		
+		this.handleOffset = this.currentHandle.offset();
+		this.clickOffset = { top: e.pageY - this.handleOffset.top, left: e.pageX - this.handleOffset.left };
+		
+		this.firstValue = this.value();
+		
+		this.propagate('start', e);
+		this.drag(e, handle);
+		return true;
+					
+	},
+	stop: function(e) {
+		this.propagate('stop', e);
+		if (this.firstValue != this.value())
+			this.propagate('change', e);
+		// This is a especially ugly fix for strange blur events happening on mousemove events
+		this.focus(this.currentHandle, true);
+		return false;
+	},
+	drag: function(e, handle) {
+
+		var o = this.options;
+		var position = { top: e.pageY - this.offset.top - this.clickOffset.top, left: e.pageX - this.offset.left - this.clickOffset.left};
+		if(!this.currentHandle) this.focus(this.previousHandle, true); //This is a especially ugly fix for strange blur events happening on mousemove events
+
+		position.left = this.translateLimits(position.left, "x");
+		position.top = this.translateLimits(position.top, "y");
+		
+		if (o.stepping.x) {
+			var value = this.convertValue(position.left, "x");
+			value = Math.round(value / o.stepping.x) * o.stepping.x;
+			position.left = this.translateValue(value, "x");	
+		}
+		if (o.stepping.y) {
+			var value = this.convertValue(position.top, "y");
+			value = Math.round(value / o.stepping.y) * o.stepping.y;
+			position.top = this.translateValue(value, "y");	
+		}
+		
+		position.left = this.translateRange(position.left, "x");
+		position.top = this.translateRange(position.top, "y");
+
+		if(o.axis != "vertical") this.currentHandle.css({ left: position.left });
+		if(o.axis != "horizontal") this.currentHandle.css({ top: position.top });
+		
+		//Store the slider's value
+		this.currentHandle.data("mouse").sliderValue = {
+			x: Math.round(this.convertValue(position.left, "x")) || 0,
+			y: Math.round(this.convertValue(position.top, "y")) || 0
+		};
+		
+		if (this.rangeElement)
+			this.updateRange();
+		this.propagate('slide', e);
+		return false;
+	},
+	
+	moveTo: function(value, handle, noPropagation) {
+
+		var o = this.options;
+
+		// Prepare the outer size
+		this.actualSize = { width: this.element.outerWidth() , height: this.element.outerHeight() };
+
+		//If no handle has been passed, no current handle is available and we have multiple handles, return false
+		if (handle == undefined && !this.currentHandle && this.handle.length != 1)
+			return false; 
+		
+		//If only one handle is available, use it
+		if (handle == undefined && !this.currentHandle)
+			handle = 0;
+		
+		if (handle != undefined)
+			this.currentHandle = this.previousHandle = $(this.handle[handle] || handle);
+
+
+		if(value.x !== undefined && value.y !== undefined) {
+			var x = value.x, y = value.y;
+		} else {
+			var x = value, y = value;
+		}
+
+		if(x !== undefined && x.constructor != Number) {
+			var me = /^\-\=/.test(x), pe = /^\+\=/.test(x);
+			if(me || pe) {
+				x = this.value(null, "x") + parseInt(x.replace(me ? '=' : '+=', ''), 10);
+			} else {
+				x = isNaN(parseInt(x, 10)) ? undefined : parseInt(x, 10);
+			}
+		}
+		
+		if(y !== undefined && y.constructor != Number) {
+			var me = /^\-\=/.test(y), pe = /^\+\=/.test(y);
+			if(me || pe) {
+				y = this.value(null, "y") + parseInt(y.replace(me ? '=' : '+=', ''), 10);
+			} else {
+				y = isNaN(parseInt(y, 10)) ? undefined : parseInt(y, 10);
+			}
+		}
+
+		if(o.axis != "vertical" && x !== undefined) {
+			if(o.stepping.x) x = Math.round(x / o.stepping.x) * o.stepping.x;
+			x = this.translateValue(x, "x");
+			x = this.translateLimits(x, "x");
+			x = this.translateRange(x, "x");
+
+			o.animate ? this.currentHandle.stop().animate({ left: x }, (Math.abs(parseInt(this.currentHandle.css("left")) - x)) * (!isNaN(parseInt(o.animate)) ? o.animate : 5)) : this.currentHandle.css({ left: x });
+		}
+
+		if(o.axis != "horizontal" && y !== undefined) {
+			if(o.stepping.y) y = Math.round(y / o.stepping.y) * o.stepping.y;
+			y = this.translateValue(y, "y");
+			y = this.translateLimits(y, "y");
+			y = this.translateRange(y, "y");
+			o.animate ? this.currentHandle.stop().animate({ top: y }, (Math.abs(parseInt(this.currentHandle.css("top")) - y)) * (!isNaN(parseInt(o.animate)) ? o.animate : 5)) : this.currentHandle.css({ top: y });
+		}
+		
+		if (this.rangeElement)
+			this.updateRange();
+			
+		//Store the slider's value
+		this.currentHandle.data("mouse").sliderValue = {
+			x: Math.round(this.convertValue(x, "x")) || 0,
+			y: Math.round(this.convertValue(y, "y")) || 0
+		};
+	
+		if (!noPropagation) {
+			this.propagate('start', null);
+			this.propagate('stop', null);
+			this.propagate('change', null);
+			this.propagate("slide", null);
+		}
+	}
+});
+
+$.ui.slider.getter = "value";
+
+$.ui.slider.defaults = {
+	handle: ".ui-slider-handle",
+	distance: 1,
+	animate: false
+};
+
+})(jQuery);
Index: /tags/2.0.2/template-common/lib/ui/ui.slider.packed.js
===================================================================
--- /tags/2.0.2/template-common/lib/ui/ui.slider.packed.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/ui.slider.packed.js	(revision 3278)
@@ -0,0 +1,2 @@
+eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)d[e(c)]=k[c]||e(c);k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(6(A){A.25.1C=A.25.1C||6(B){c 3.18(6(){A(3).2J(B).2I(0).2H(3).1s()})};A.24("j.m",{2G:{},j:6(B){c{8:3.8,9:3.7,n:3.8.l!="2F"||!3.8.l?p.t(3.n(i,3.8.l=="w"?"y":"x")):{x:p.t(3.n(i,"x")),y:p.t(3.n(i,"y"))},1h:3.1K()}},M:6(C,B){A.j.2E.1k(3,C,[B,3.j()]);3.d.2D(C=="1a"?C:"1a"+C,[B,3.j()],3.8[C])},2C:6(){3.d.1R("j-m j-m-1r").2B("m").2A(".m");4(3.9&&3.9.11){3.9.1C("a");3.9.18(6(){A(3).U("P").2z()})}3.1B&&3.1B.1s()},23:6(B,C){A.24.22.23.1Z(3,2y);4(/k|s|X/.Q(B)){3.1y()}4(B=="1h"){C?3.9.11==2&&3.1u():3.1L()}},2x:6(){h B=3;3.d.1i("j-m");3.1y();3.9=A(3.8.9,3.d);4(!3.9.11){B.9=B.1B=A(B.8.1g||[0]).2w(6(){h D=A("<1t/>").1i("j-m-9").1M(B.d);4(3.1A){D.2v("1A",3.1A)}c D[0]})}h C=6(D){3.d=A(D);3.d.U("P",3);3.8=B.8;3.d.19("20",6(){4(B.7){3.1j(B.7)}B.O(3,1)});3.2u()};A.1W(C.22,A.j.P,{2t:6(D){c B.12.1k(B,D,3.d[0])},2s:6(D){c B.Z.1k(B,D,3.d[0])},2r:6(D){c B.1p.1k(B,D,3.d[0])},2q:6(){c N},1Y:6(D){3.2p(D)}});A(3.9).18(6(){2o C(3)}).2n(\'<a 2m="2l:2k(0)" 2j="2i:21;2h:21;"></a>\').1S().19("O",6(D){B.O(3.1z)}).19("1j",6(D){B.1j(3.1z)}).19("1x",6(D){4(!B.8.2g){B.1x(D.2f,3.1z)}});3.d.19("20.m",6(D){B.1P.1Z(B,[D]);B.7.U("P").1Y(D);B.1f=B.1f+1});A.18(3.8.1g||[],6(D,E){B.16(E.12,D,N)});4(!V(3.8.1X)){3.16(3.8.1X,0,N)}3.R=A(3.9[0]);4(3.9.11==2&&3.8.1h){3.1u()}},1y:6(){h B=3.d[0],C=3.8;3.S={J:3.d.1n(),z:3.d.1m()};A.1W(C,{l:C.l||(B.1N<B.1O?"w":"1l"),s:!V(b(C.s,10))?{x:b(C.s,10),y:b(C.s,10)}:({x:C.s&&C.s.x||1V,y:C.s&&C.s.y||1V}),k:!V(b(C.k,10))?{x:b(C.k,10),y:b(C.k,10)}:({x:C.k&&C.k.x||0,y:C.k&&C.k.y||0})});C.T={x:C.s.x-C.k.x,y:C.s.y-C.k.y};C.f={x:C.f&&C.f.x||b(C.f,10)||(C.X?C.T.x/(C.X.x||b(C.X,10)||C.T.x):0),y:C.f&&C.f.y||b(C.f,10)||(C.X?C.T.y/(C.X.y||b(C.X,10)||C.T.y):0)}},1x:6(C,B){4(/(1w|1v|1U|1T)/.Q(C)){3.16({x:/(1w|1U)/.Q(C)?(C==1w?"-":"+")+"="+3.17("x"):0,y:/(1v|1T)/.Q(C)?(C==1v?"-":"+")+"="+3.17("y"):0},B)}},O:6(B,C){3.7=A(B).1i("j-m-9-1Q");4(C){3.7.1S()[0].O()}},1j:6(B){A(B).1R("j-m-9-1Q");4(3.7&&3.7[0]==B){3.R=3.7;3.7=i}},1P:6(C){h D=[C.1d,C.1e];h B=Y;3.9.18(6(){4(3==C.2e){B=N}});4(B||3.8.1r||!(3.7||3.R)){c}4(!3.7&&3.R){3.O(3.R,N)}3.K=3.d.K();3.16({y:3.v(C.1e-3.K.e-3.7[0].1O/2,"y"),x:3.v(C.1d-3.K.g-3.7[0].1N/2,"x")},i,!3.8.1D)},1u:6(){4(3.u){c}3.u=A("<1t></1t>").1i("j-m-1h").o({2d:"2c"}).1M(3.d);3.1c()},1L:6(){3.u.1s();3.u=i},1c:6(){h C=3.8.l=="w"?"e":"g";h B=3.8.l=="w"?"z":"J";3.u.o(C,(b(A(3.9[0]).o(C),10)||0)+3.W(0,3.8.l=="w"?"y":"x")/2);3.u.o(B,(b(A(3.9[1]).o(C),10)||0)-(b(A(3.9[0]).o(C),10)||0))},1K:6(){c 3.u?3.v(b(3.u.o(3.8.l=="w"?"z":"J"),10),3.8.l=="w"?"y":"x"):i},1J:6(){c 3.9.2b(3.7[0])},n:6(D,B){4(3.9.11==1){3.7=3.9}4(!B){B=3.8.l=="w"?"y":"x"}h C=A(D!=r&&D!==i?3.9[D]||D:3.7);4(C.U("P").1b){c b(C.U("P").1b[B],10)}15{c b(((b(C.o(B=="x"?"g":"e"),10)/(3.S[B=="x"?"J":"z"]-3.W(D,B)))*3.8.T[B])+3.8.k[B],10)}},v:6(C,B){c 3.8.k[B]+(C/(3.S[B=="x"?"J":"z"]-3.W(i,B)))*3.8.T[B]},q:6(C,B){c((C-3.8.k[B])/3.8.T[B])*(3.S[B=="x"?"J":"z"]-3.W(i,B))},13:6(D,B){4(3.u){4(3.7[0]==3.9[0]&&D>=3.q(3.n(1),B)){D=3.q(3.n(1,B)-3.17(B),B)}4(3.7[0]==3.9[1]&&D<=3.q(3.n(0),B)){D=3.q(3.n(0,B)+3.17(B),B)}}4(3.8.1g){h C=3.8.1g[3.1J()];4(D<3.q(C.k,B)){D=3.q(C.k,B)}15{4(D>3.q(C.s,B)){D=3.q(C.s,B)}}}c D},14:6(C,B){4(C>=3.S[B=="x"?"J":"z"]-3.W(i,B)){C=3.S[B=="x"?"J":"z"]-3.W(i,B)}4(C<=0){C=0}c C},W:6(C,B){c A(C!=r&&C!==i?3.9[C]:3.7)[0]["K"+(B=="x"?"2a":"29")]},17:6(B){c 3.8.f[B]||1},12:6(C,B){h D=3.8;4(D.1r){c Y}3.S={J:3.d.1n(),z:3.d.1m()};4(!3.7){3.O(3.R,N)}3.K=3.d.K();3.1q=3.7.K();3.1o={e:C.1e-3.1q.e,g:C.1d-3.1q.g};3.1f=3.n();3.M("12",C);3.1p(C,B);c N},Z:6(B){3.M("Z",B);4(3.1f!=3.n()){3.M("1E",B)}3.O(3.7,N);c Y},1p:6(E,D){h F=3.8;h B={e:E.1e-3.K.e-3.1o.e,g:E.1d-3.K.g-3.1o.g};4(!3.7){3.O(3.R,N)}B.g=3.14(B.g,"x");B.e=3.14(B.e,"y");4(F.f.x){h C=3.v(B.g,"x");C=p.t(C/F.f.x)*F.f.x;B.g=3.q(C,"x")}4(F.f.y){h C=3.v(B.e,"y");C=p.t(C/F.f.y)*F.f.y;B.e=3.q(C,"y")}B.g=3.13(B.g,"x");B.e=3.13(B.e,"y");4(F.l!="w"){3.7.o({g:B.g})}4(F.l!="1l"){3.7.o({e:B.e})}3.7.U("P").1b={x:p.t(3.v(B.g,"x"))||0,y:p.t(3.v(B.e,"y"))||0};4(3.u){3.1c()}3.M("1a",E);c Y},16:6(F,E,G){h H=3.8;3.S={J:3.d.1n(),z:3.d.1m()};4(E==r&&!3.7&&3.9.11!=1){c Y}4(E==r&&!3.7){E=0}4(E!=r){3.7=3.R=A(3.9[E]||E)}4(F.x!==r&&F.y!==r){h B=F.x,I=F.y}15{h B=F,I=F}4(B!==r&&B.1I!=1H){h D=/^\\-\\=/.Q(B),C=/^\\+\\=/.Q(B);4(D||C){B=3.n(i,"x")+b(B.1G(D?"=":"+=",""),10)}15{B=V(b(B,10))?r:b(B,10)}}4(I!==r&&I.1I!=1H){h D=/^\\-\\=/.Q(I),C=/^\\+\\=/.Q(I);4(D||C){I=3.n(i,"y")+b(I.1G(D?"=":"+=",""),10)}15{I=V(b(I,10))?r:b(I,10)}}4(H.l!="w"&&B!==r){4(H.f.x){B=p.t(B/H.f.x)*H.f.x}B=3.q(B,"x");B=3.14(B,"x");B=3.13(B,"x");H.L?3.7.Z().L({g:B},(p.1F(b(3.7.o("g"))-B))*(!V(b(H.L))?H.L:5)):3.7.o({g:B})}4(H.l!="1l"&&I!==r){4(H.f.y){I=p.t(I/H.f.y)*H.f.y}I=3.q(I,"y");I=3.14(I,"y");I=3.13(I,"y");H.L?3.7.Z().L({e:I},(p.1F(b(3.7.o("e"))-I))*(!V(b(H.L))?H.L:5)):3.7.o({e:I})}4(3.u){3.1c()}3.7.U("P").1b={x:p.t(3.v(B,"x"))||0,y:p.t(3.v(I,"y"))||0};4(!G){3.M("12",i);3.M("Z",i);3.M("1E",i);3.M("1a",i)}}});A.j.m.28="n";A.j.m.27={9:".j-m-9",1D:1,L:Y}})(26)',62,170,'|||this|if||function|currentHandle|options|handle||parseInt|return|element|top|stepping|left|var|null|ui|min|axis|slider|value|css|Math|translateValue|undefined|max|round|rangeElement|convertValue|vertical|||height||||||||||width|offset|animate|propagate|true|focus|mouse|test|previousHandle|actualSize|realMax|data|isNaN|handleSize|steps|false|stop||length|start|translateRange|translateLimits|else|moveTo|oneStep|each|bind|slide|sliderValue|updateRange|pageX|pageY|firstValue|handles|range|addClass|blur|call|horizontal|outerHeight|outerWidth|clickOffset|drag|handleOffset|disabled|remove|div|createRange|38|37|keydown|initBoundaries|firstChild|id|generated|unwrap|distance|change|abs|replace|Number|constructor|handleIndex|getRange|removeRange|appendTo|offsetWidth|offsetHeight|click|active|removeClass|parent|40|39|100|extend|startValue|trigger|apply|mousedown|none|prototype|setData|widget|fn|jQuery|defaults|getter|Height|Width|index|absolute|position|target|keyCode|noKeyboard|border|outline|style|void|javascript|href|wrap|new|mouseDown|mouseCapture|mouseDrag|mouseStop|mouseStart|mouseInit|attr|map|init|arguments|mouseDestroy|unbind|removeData|destroy|triggerHandler|plugin|both|plugins|after|eq|parents'.split('|'),0,{}))
+
Index: /tags/2.0.2/template-common/lib/ui/ui.sortable.js
===================================================================
--- /tags/2.0.2/template-common/lib/ui/ui.sortable.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/ui.sortable.js	(revision 3278)
@@ -0,0 +1,743 @@
+/*
+ * jQuery UI Sortable
+ *
+ * Copyright (c) 2008 Paul Bakaus
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ * 
+ * http://docs.jquery.com/UI/Sortables
+ *
+ * Depends:
+ *	ui.core.js
+ */
+(function($) {
+
+function contains(a, b) { 
+    var safari2 = $.browser.safari && $.browser.version < 522; 
+    if (a.contains && !safari2) { 
+        return a.contains(b); 
+    } 
+    if (a.compareDocumentPosition) 
+        return !!(a.compareDocumentPosition(b) & 16); 
+    while (b = b.parentNode) 
+          if (b == a) return true; 
+    return false; 
+};
+
+$.widget("ui.sortable", $.extend({}, $.ui.mouse, {
+	init: function() {
+
+		var o = this.options;
+		this.containerCache = {};
+		this.element.addClass("ui-sortable");
+	
+		//Get the items
+		this.refresh();
+
+		//Let's determine if the items are floating
+		this.floating = this.items.length ? (/left|right/).test(this.items[0].item.css('float')) : false;
+		
+		//Let's determine the parent's offset
+		if(!(/(relative|absolute|fixed)/).test(this.element.css('position'))) this.element.css('position', 'relative');
+		this.offset = this.element.offset();
+
+		//Initialize mouse events for interaction
+		this.mouseInit();
+		
+	},
+	plugins: {},
+	ui: function(inst) {
+		return {
+			helper: (inst || this)["helper"],
+			placeholder: (inst || this)["placeholder"] || $([]),
+			position: (inst || this)["position"],
+			absolutePosition: (inst || this)["positionAbs"],
+			options: this.options,
+			element: this.element,
+			item: (inst || this)["currentItem"],
+			sender: inst ? inst.element : null
+		};		
+	},
+	propagate: function(n,e,inst, noPropagation) {
+		$.ui.plugin.call(this, n, [e, this.ui(inst)]);
+		if(!noPropagation) this.element.triggerHandler(n == "sort" ? n : "sort"+n, [e, this.ui(inst)], this.options[n]);
+	},
+	serialize: function(o) {
+
+		var items = ($.isFunction(this.options.items) ? this.options.items.call(this.element) : $(this.options.items, this.element)).not('.ui-sortable-helper'); //Only the items of the sortable itself
+		var str = []; o = o || {};
+		
+		items.each(function() {
+			var res = ($(this).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
+			if(res) str.push((o.key || res[1])+'[]='+(o.key && o.expression ? res[1] : res[2]));
+		});
+		
+		return str.join('&');
+		
+	},
+	toArray: function(attr) {
+		
+		var items = ($.isFunction(this.options.items) ? this.options.items.call(this.element) : $(this.options.items, this.element)).not('.ui-sortable-helper'); //Only the items of the sortable itself
+		var ret = [];
+
+		items.each(function() { ret.push($(this).attr(attr || 'id')); });
+		return ret;
+		
+	},
+	/* Be careful with the following core functions */
+	intersectsWith: function(item) {
+		
+		var x1 = this.positionAbs.left, x2 = x1 + this.helperProportions.width,
+		y1 = this.positionAbs.top, y2 = y1 + this.helperProportions.height;
+		var l = item.left, r = l + item.width, 
+		t = item.top, b = t + item.height;
+
+		if(this.options.tolerance == "pointer" || this.options.forcePointerForContainers || (this.options.tolerance == "guess" && this.helperProportions[this.floating ? 'width' : 'height'] > item[this.floating ? 'width' : 'height'])) {
+			return (y1 + this.offset.click.top > t && y1 + this.offset.click.top < b && x1 + this.offset.click.left > l && x1 + this.offset.click.left < r);
+		} else {
+		
+			return (l < x1 + (this.helperProportions.width / 2) // Right Half
+				&& x2 - (this.helperProportions.width / 2) < r // Left Half
+				&& t < y1 + (this.helperProportions.height / 2) // Bottom Half
+				&& y2 - (this.helperProportions.height / 2) < b ); // Top Half
+		
+		}
+		
+	},
+	intersectsWithEdge: function(item) {	
+		var x1 = this.positionAbs.left, x2 = x1 + this.helperProportions.width,
+			y1 = this.positionAbs.top, y2 = y1 + this.helperProportions.height;
+		var l = item.left, r = l + item.width, 
+			t = item.top, b = t + item.height;
+
+		if(this.options.tolerance == "pointer" || (this.options.tolerance == "guess" && this.helperProportions[this.floating ? 'width' : 'height'] > item[this.floating ? 'width' : 'height'])) {
+
+			if(!(y1 + this.offset.click.top > t && y1 + this.offset.click.top < b && x1 + this.offset.click.left > l && x1 + this.offset.click.left < r)) return false;
+			
+			if(this.floating) {
+				if(x1 + this.offset.click.left > l && x1 + this.offset.click.left < l + item.width/2) return 2;
+				if(x1 + this.offset.click.left > l+item.width/2 && x1 + this.offset.click.left < r) return 1;
+			} else {
+				if(y1 + this.offset.click.top > t && y1 + this.offset.click.top < t + item.height/2) return 2;
+				if(y1 + this.offset.click.top > t+item.height/2 && y1 + this.offset.click.top < b) return 1;
+			}
+
+		} else {
+		
+			if (!(l < x1 + (this.helperProportions.width / 2) // Right Half
+				&& x2 - (this.helperProportions.width / 2) < r // Left Half
+				&& t < y1 + (this.helperProportions.height / 2) // Bottom Half
+				&& y2 - (this.helperProportions.height / 2) < b )) return false; // Top Half
+			
+			if(this.floating) {
+				if(x2 > l && x1 < l) return 2; //Crosses left edge
+				if(x1 < r && x2 > r) return 1; //Crosses right edge
+			} else {
+				if(y2 > t && y1 < t) return 1; //Crosses top edge
+				if(y1 < b && y2 > b) return 2; //Crosses bottom edge
+			}
+		
+		}
+		
+		return false;
+		
+	},
+	refresh: function() {
+		this.refreshItems();
+		this.refreshPositions();
+	},
+	refreshItems: function() {
+		
+		this.items = [];
+		this.containers = [this];
+		var items = this.items;
+		var self = this;
+		var queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element), this]];
+	
+		if(this.options.connectWith) {
+			for (var i = this.options.connectWith.length - 1; i >= 0; i--){
+				var cur = $(this.options.connectWith[i]);
+				for (var j = cur.length - 1; j >= 0; j--){
+					var inst = $.data(cur[j], 'sortable');
+					if(inst && !inst.options.disabled) {
+						queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element), inst]);
+						this.containers.push(inst);
+					}
+				};
+			};
+		}
+
+		for (var i = queries.length - 1; i >= 0; i--){
+			queries[i][0].each(function() {
+				$.data(this, 'sortable-item', queries[i][1]); // Data for target checking (mouse manager)
+				items.push({
+					item: $(this),
+					instance: queries[i][1],
+					width: 0, height: 0,
+					left: 0, top: 0
+				});
+			});
+		};
+
+	},
+	refreshPositions: function(fast) {
+
+		//This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
+		if(this.offsetParent) {
+			var po = this.offsetParent.offset();
+			this.offset.parent = { top: po.top + this.offsetParentBorders.top, left: po.left + this.offsetParentBorders.left };
+		}
+
+		for (var i = this.items.length - 1; i >= 0; i--){		
+			
+			//We ignore calculating positions of all connected containers when we're not over them
+			if(this.items[i].instance != this.currentContainer && this.currentContainer && this.items[i].item[0] != this.currentItem[0])
+				continue;
+				
+			var t = this.options.toleranceElement ? $(this.options.toleranceElement, this.items[i].item) : this.items[i].item;
+			
+			if(!fast) {
+				this.items[i].width = t[0].offsetWidth;
+				this.items[i].height = t[0].offsetHeight;
+			}
+			
+			var p = t.offset();
+			this.items[i].left = p.left;
+			this.items[i].top = p.top;
+			
+		};
+
+		if(this.options.custom && this.options.custom.refreshContainers) {
+			this.options.custom.refreshContainers.call(this);
+		} else {
+			for (var i = this.containers.length - 1; i >= 0; i--){
+				var p =this.containers[i].element.offset();
+				this.containers[i].containerCache.left = p.left;
+				this.containers[i].containerCache.top = p.top;
+				this.containers[i].containerCache.width	= this.containers[i].element.outerWidth();
+				this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
+			};
+		}
+
+	},
+	destroy: function() {
+		this.element
+			.removeClass("ui-sortable ui-sortable-disabled")
+			.removeData("sortable")
+			.unbind(".sortable");
+		this.mouseDestroy();
+		
+		for ( var i = this.items.length - 1; i >= 0; i-- )
+			this.items[i].item.removeData("sortable-item");
+	},
+	createPlaceholder: function(that) {
+		
+		var self = that || this, o = self.options;
+
+		if(o.placeholder.constructor == String) {
+			var className = o.placeholder;
+			o.placeholder = {
+				element: function() {
+					return $('<div></div>').addClass(className)[0];
+				},
+				update: function(i, p) {
+					p.css(i.offset()).css({ width: i.outerWidth(), height: i.outerHeight() });
+				}
+			};
+		}
+		
+		self.placeholder = $(o.placeholder.element.call(self.element, self.currentItem)).appendTo('body').css({ position: 'absolute' });
+		o.placeholder.update.call(self.element, self.currentItem, self.placeholder);
+	},
+	contactContainers: function(e) {
+		for (var i = this.containers.length - 1; i >= 0; i--){
+
+			if(this.intersectsWith(this.containers[i].containerCache)) {
+				if(!this.containers[i].containerCache.over) {
+					
+
+					if(this.currentContainer != this.containers[i]) {
+						
+						//When entering a new container, we will find the item with the least distance and append our item near it
+						var dist = 10000; var itemWithLeastDistance = null; var base = this.positionAbs[this.containers[i].floating ? 'left' : 'top'];
+						for (var j = this.items.length - 1; j >= 0; j--) {
+							if(!contains(this.containers[i].element[0], this.items[j].item[0])) continue;
+							var cur = this.items[j][this.containers[i].floating ? 'left' : 'top'];
+							if(Math.abs(cur - base) < dist) {
+								dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j];
+							}
+						}
+						
+						if(!itemWithLeastDistance && !this.options.dropOnEmpty) //Check if dropOnEmpty is enabled
+							continue;
+						
+						//We also need to exchange the placeholder
+						if(this.placeholder) this.placeholder.remove();
+						if(this.containers[i].options.placeholder) {
+							this.containers[i].createPlaceholder(this);
+						} else {
+							this.placeholder = null;;
+						}
+						
+						this.currentContainer = this.containers[i];
+						itemWithLeastDistance ? this.rearrange(e, itemWithLeastDistance, null, true) : this.rearrange(e, null, this.containers[i].element, true);
+						this.propagate("change", e); //Call plugins and callbacks
+						this.containers[i].propagate("change", e, this); //Call plugins and callbacks
+
+					}
+					
+					this.containers[i].propagate("over", e, this);
+					this.containers[i].containerCache.over = 1;
+				}
+			} else {
+				if(this.containers[i].containerCache.over) {
+					this.containers[i].propagate("out", e, this);
+					this.containers[i].containerCache.over = 0;
+				}
+			}
+			
+		};			
+	},
+	mouseCapture: function(e, overrideHandle) {
+	
+		if(this.options.disabled || this.options.type == 'static') return false;
+
+		//We have to refresh the items data once first
+		this.refreshItems();
+
+		//Find out if the clicked node (or one of its parents) is a actual item in this.items
+		var currentItem = null, self = this, nodes = $(e.target).parents().each(function() {	
+			if($.data(this, 'sortable-item') == self) {
+				currentItem = $(this);
+				return false;
+			}
+		});
+		if($.data(e.target, 'sortable-item') == self) currentItem = $(e.target);
+
+		if(!currentItem) return false;
+		if(this.options.handle && !overrideHandle) {
+			var validHandle = false;
+			
+			$(this.options.handle, currentItem).find("*").andSelf().each(function() { if(this == e.target) validHandle = true; });
+			if(!validHandle) return false;
+		}
+			
+		this.currentItem = currentItem;
+		return true;	
+			
+	},
+	mouseStart: function(e, overrideHandle, noActivation) {
+
+		var o = this.options;
+		this.currentContainer = this;
+
+		//We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
+		this.refreshPositions();
+
+		//Create and append the visible helper			
+		this.helper = typeof o.helper == 'function' ? $(o.helper.apply(this.element[0], [e, this.currentItem])) : this.currentItem.clone();
+		if (!this.helper.parents('body').length) $(o.appendTo != 'parent' ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(this.helper[0]); //Add the helper to the DOM if that didn't happen already
+		this.helper.css({ position: 'absolute', clear: 'both' }).addClass('ui-sortable-helper'); //Position it absolutely and add a helper class
+
+		/*
+		 * - Position generation -
+		 * This block generates everything position related - it's the core of draggables.
+		 */
+
+		this.margins = {																				//Cache the margins
+			left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
+			top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
+		};		
+	
+		this.offset = this.currentItem.offset();														//The element's absolute position on the page
+		this.offset = {																					//Substract the margins from the element's absolute offset
+			top: this.offset.top - this.margins.top,
+			left: this.offset.left - this.margins.left
+		};
+		
+		this.offset.click = {																			//Where the click happened, relative to the element
+			left: e.pageX - this.offset.left,
+			top: e.pageY - this.offset.top
+		};
+		
+		this.offsetParent = this.helper.offsetParent();													//Get the offsetParent and cache its position
+		var po = this.offsetParent.offset();			
+
+		this.offsetParentBorders = {
+			top: (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
+			left: (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
+		};
+		this.offset.parent = {																			//Store its position plus border
+			top: po.top + this.offsetParentBorders.top,
+			left: po.left + this.offsetParentBorders.left
+		};
+	
+		this.originalPosition = this.generatePosition(e);												//Generate the original position
+		this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };  //Cache the former DOM position
+		
+		//If o.placeholder is used, create a new element at the given position with the class
+		this.helperProportions = { width: this.helper.outerWidth(), height: this.helper.outerHeight() };//Cache the helper size
+		if(o.placeholder) this.createPlaceholder();
+		
+		//Call plugins and callbacks
+		this.propagate("start", e);
+		this.helperProportions = { width: this.helper.outerWidth(), height: this.helper.outerHeight() };//Recache the helper size
+		
+		if(o.cursorAt) {
+			if(o.cursorAt.left != undefined) this.offset.click.left = o.cursorAt.left;
+			if(o.cursorAt.right != undefined) this.offset.click.left = this.helperProportions.width - o.cursorAt.right;
+			if(o.cursorAt.top != undefined) this.offset.click.top = o.cursorAt.top;
+			if(o.cursorAt.bottom != undefined) this.offset.click.top = this.helperProportions.height - o.cursorAt.bottom;
+		}
+
+		/*
+		 * - Position constraining -
+		 * Here we prepare position constraining like grid and containment.
+		 */	
+		
+		if(o.containment) {
+			if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
+			if(o.containment == 'document' || o.containment == 'window') this.containment = [
+				0 - this.offset.parent.left,
+				0 - this.offset.parent.top,
+				$(o.containment == 'document' ? document : window).width() - this.offset.parent.left - this.helperProportions.width - this.margins.left - (parseInt(this.element.css("marginRight"),10) || 0),
+				($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.offset.parent.top - this.helperProportions.height - this.margins.top - (parseInt(this.element.css("marginBottom"),10) || 0)
+			];
+
+			if(!(/^(document|window|parent)$/).test(o.containment)) {
+				var ce = $(o.containment)[0];
+				var co = $(o.containment).offset();
+				
+				this.containment = [
+					co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) - this.offset.parent.left,
+					co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) - this.offset.parent.top,
+					co.left+Math.max(ce.scrollWidth,ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - this.offset.parent.left - this.helperProportions.width - this.margins.left - (parseInt(this.currentItem.css("marginRight"),10) || 0),
+					co.top+Math.max(ce.scrollHeight,ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - this.offset.parent.top - this.helperProportions.height - this.margins.top - (parseInt(this.currentItem.css("marginBottom"),10) || 0)
+				];
+			}
+		}
+
+		//Set the original element visibility to hidden to still fill out the white space
+		if(this.options.placeholder != 'clone')
+			this.currentItem.css('visibility', 'hidden');
+		
+		//Post 'activate' events to possible containers
+		if(!noActivation) {
+			 for (var i = this.containers.length - 1; i >= 0; i--) { this.containers[i].propagate("activate", e, this); }
+		}
+		
+		//Prepare possible droppables
+		if($.ui.ddmanager) $.ui.ddmanager.current = this;
+		if ($.ui.ddmanager && !o.dropBehaviour) $.ui.ddmanager.prepareOffsets(this, e);
+
+		this.dragging = true;
+
+		this.mouseDrag(e); //Execute the drag once - this causes the helper not to be visible before getting its correct position
+		return true;
+
+
+	},
+	convertPositionTo: function(d, pos) {
+		if(!pos) pos = this.position;
+		var mod = d == "absolute" ? 1 : -1;
+		return {
+			top: (
+				pos.top																	// the calculated relative position
+				+ this.offset.parent.top * mod											// The offsetParent's offset without borders (offset + border)
+				- (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop) * mod	// The offsetParent's scroll position
+				+ this.margins.top * mod												//Add the margin (you don't want the margin counting in intersection methods)
+			),
+			left: (
+				pos.left																// the calculated relative position
+				+ this.offset.parent.left * mod											// The offsetParent's offset without borders (offset + border)
+				- (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft) * mod	// The offsetParent's scroll position
+				+ this.margins.left * mod												//Add the margin (you don't want the margin counting in intersection methods)
+			)
+		};
+	},
+	generatePosition: function(e) {
+		
+		var o = this.options;
+		var position = {
+			top: (
+				e.pageY																	// The absolute mouse position
+				- this.offset.click.top													// Click offset (relative to the element)
+				- this.offset.parent.top												// The offsetParent's offset without borders (offset + border)
+				+ (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop)	// The offsetParent's scroll position, not if the element is fixed
+			),
+			left: (
+				e.pageX																	// The absolute mouse position
+				- this.offset.click.left												// Click offset (relative to the element)
+				- this.offset.parent.left												// The offsetParent's offset without borders (offset + border)
+				+ (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft)	// The offsetParent's scroll position, not if the element is fixed
+			)
+		};
+		
+		if(!this.originalPosition) return position;										//If we are not dragging yet, we won't check for options
+		
+		/*
+		 * - Position constraining -
+		 * Constrain the position to a mix of grid, containment.
+		 */
+		if(this.containment) {
+			if(position.left < this.containment[0]) position.left = this.containment[0];
+			if(position.top < this.containment[1]) position.top = this.containment[1];
+			if(position.left > this.containment[2]) position.left = this.containment[2];
+			if(position.top > this.containment[3]) position.top = this.containment[3];
+		}
+		
+		if(o.grid) {
+			var top = this.originalPosition.top + Math.round((position.top - this.originalPosition.top) / o.grid[1]) * o.grid[1];
+			position.top = this.containment ? (!(top < this.containment[1] || top > this.containment[3]) ? top : (!(top < this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
+			
+			var left = this.originalPosition.left + Math.round((position.left - this.originalPosition.left) / o.grid[0]) * o.grid[0];
+			position.left = this.containment ? (!(left < this.containment[0] || left > this.containment[2]) ? left : (!(left < this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
+		}
+		
+		return position;
+	},
+	mouseDrag: function(e) {
+
+		//Compute the helpers position
+		this.position = this.generatePosition(e);
+		this.positionAbs = this.convertPositionTo("absolute");
+
+		//Call the internal plugins
+		$.ui.plugin.call(this, "sort", [e, this.ui()]);
+		
+		//Regenerate the absolute position used for position checks
+		this.positionAbs = this.convertPositionTo("absolute");
+		
+		//Set the helper's position
+		this.helper[0].style.left = this.position.left+'px';
+		this.helper[0].style.top = this.position.top+'px';
+
+		//Rearrange
+		for (var i = this.items.length - 1; i >= 0; i--) {
+			var intersection = this.intersectsWithEdge(this.items[i]);
+			if(!intersection) continue;
+			
+			if(this.items[i].item[0] != this.currentItem[0] //cannot intersect with itself
+				&&	this.currentItem[intersection == 1 ? "next" : "prev"]()[0] != this.items[i].item[0] //no useless actions that have been done before
+				&&	!contains(this.currentItem[0], this.items[i].item[0]) //no action if the item moved is the parent of the item checked
+				&& (this.options.type == 'semi-dynamic' ? !contains(this.element[0], this.items[i].item[0]) : true)
+			) {
+				
+				this.direction = intersection == 1 ? "down" : "up";
+				this.rearrange(e, this.items[i]);
+				this.propagate("change", e); //Call plugins and callbacks
+				break;
+			}
+		}
+		
+		//Post events to containers
+		this.contactContainers(e);
+		
+		//Interconnect with droppables
+		if($.ui.ddmanager) $.ui.ddmanager.drag(this, e);
+
+		//Call callbacks
+		this.element.triggerHandler("sort", [e, this.ui()], this.options["sort"]);
+
+		return false;
+		
+	},
+	rearrange: function(e, i, a, hardRefresh) {
+		a ? a[0].appendChild(this.currentItem[0]) : i.item[0].parentNode.insertBefore(this.currentItem[0], (this.direction == 'down' ? i.item[0] : i.item[0].nextSibling));
+		
+		//Various things done here to improve the performance:
+		// 1. we create a setTimeout, that calls refreshPositions
+		// 2. on the instance, we have a counter variable, that get's higher after every append
+		// 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
+		// 4. this lets only the last addition to the timeout stack through
+		this.counter = this.counter ? ++this.counter : 1;
+		var self = this, counter = this.counter;
+
+		window.setTimeout(function() {
+			if(counter == self.counter) self.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
+		},0);
+		
+		if(this.options.placeholder)
+			this.options.placeholder.update.call(this.element, this.currentItem, this.placeholder);
+	},
+	mouseStop: function(e, noPropagation) {
+
+		//If we are using droppables, inform the manager about the drop
+		if ($.ui.ddmanager && !this.options.dropBehaviour)
+			$.ui.ddmanager.drop(this, e);
+			
+		if(this.options.revert) {
+			var self = this;
+			var cur = self.currentItem.offset();
+
+			//Also animate the placeholder if we have one
+			if(self.placeholder) self.placeholder.animate({ opacity: 'hide' }, (parseInt(this.options.revert, 10) || 500)-50);
+
+			$(this.helper).animate({
+				left: cur.left - this.offset.parent.left - self.margins.left + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft),
+				top: cur.top - this.offset.parent.top - self.margins.top + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop)
+			}, parseInt(this.options.revert, 10) || 500, function() {
+				self.clear(e);
+			});
+		} else {
+			this.clear(e, noPropagation);
+		}
+
+		return false;
+		
+	},
+	clear: function(e, noPropagation) {
+
+		if(this.domPosition.prev != this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent != this.currentItem.parent()[0]) this.propagate("update", e, null, noPropagation); //Trigger update callback if the DOM position has changed
+		if(!contains(this.element[0], this.currentItem[0])) { //Node was moved out of the current element
+			this.propagate("remove", e, null, noPropagation);
+			for (var i = this.containers.length - 1; i >= 0; i--){
+				if(contains(this.containers[i].element[0], this.currentItem[0])) {
+					this.containers[i].propagate("update", e, this, noPropagation);
+					this.containers[i].propagate("receive", e, this, noPropagation);
+				}
+			};
+		};
+		
+		//Post events to containers
+		for (var i = this.containers.length - 1; i >= 0; i--){
+			this.containers[i].propagate("deactivate", e, this, noPropagation);
+			if(this.containers[i].containerCache.over) {
+				this.containers[i].propagate("out", e, this);
+				this.containers[i].containerCache.over = 0;
+			}
+		}
+		
+		this.dragging = false;
+		if(this.cancelHelperRemoval) {
+			this.propagate("stop", e, null, noPropagation);
+			return false;
+		}
+		
+		$(this.currentItem).css('visibility', '');
+		if(this.placeholder) this.placeholder.remove();
+		this.helper.remove(); this.helper = null;
+		this.propagate("stop", e, null, noPropagation);
+		
+		return true;
+		
+	}
+}));
+
+$.extend($.ui.sortable, {
+	getter: "serialize toArray",
+	defaults: {
+		helper: "clone",
+		tolerance: "guess",
+		distance: 1,
+		delay: 0,
+		scroll: true,
+		scrollSensitivity: 20,
+		scrollSpeed: 20,
+		cancel: ":input",
+		items: '> *',
+		zIndex: 1000,
+		dropOnEmpty: true,
+		appendTo: "parent"
+	}
+});
+
+/*
+ * Sortable Extensions
+ */
+
+$.ui.plugin.add("sortable", "cursor", {
+	start: function(e, ui) {
+		var t = $('body');
+		if (t.css("cursor")) ui.options._cursor = t.css("cursor");
+		t.css("cursor", ui.options.cursor);
+	},
+	stop: function(e, ui) {
+		if (ui.options._cursor) $('body').css("cursor", ui.options._cursor);
+	}
+});
+
+$.ui.plugin.add("sortable", "zIndex", {
+	start: function(e, ui) {
+		var t = ui.helper;
+		if(t.css("zIndex")) ui.options._zIndex = t.css("zIndex");
+		t.css('zIndex', ui.options.zIndex);
+	},
+	stop: function(e, ui) {
+		if(ui.options._zIndex) $(ui.helper).css('zIndex', ui.options._zIndex);
+	}
+});
+
+$.ui.plugin.add("sortable", "opacity", {
+	start: function(e, ui) {
+		var t = ui.helper;
+		if(t.css("opacity")) ui.options._opacity = t.css("opacity");
+		t.css('opacity', ui.options.opacity);
+	},
+	stop: function(e, ui) {
+		if(ui.options._opacity) $(ui.helper).css('opacity', ui.options._opacity);
+	}
+});
+
+$.ui.plugin.add("sortable", "scroll", {
+	start: function(e, ui) {
+		var o = ui.options;
+		var i = $(this).data("sortable");
+	
+		i.overflowY = function(el) {
+			do { if(/auto|scroll/.test(el.css('overflow')) || (/auto|scroll/).test(el.css('overflow-y'))) return el; el = el.parent(); } while (el[0].parentNode);
+			return $(document);
+		}(i.currentItem);
+		i.overflowX = function(el) {
+			do { if(/auto|scroll/.test(el.css('overflow')) || (/auto|scroll/).test(el.css('overflow-x'))) return el; el = el.parent(); } while (el[0].parentNode);
+			return $(document);
+		}(i.currentItem);
+		
+		if(i.overflowY[0] != document && i.overflowY[0].tagName != 'HTML') i.overflowYOffset = i.overflowY.offset();
+		if(i.overflowX[0] != document && i.overflowX[0].tagName != 'HTML') i.overflowXOffset = i.overflowX.offset();
+		
+	},
+	sort: function(e, ui) {
+		
+		var o = ui.options;
+		var i = $(this).data("sortable");
+		
+		if(i.overflowY[0] != document && i.overflowY[0].tagName != 'HTML') {
+			if((i.overflowYOffset.top + i.overflowY[0].offsetHeight) - e.pageY < o.scrollSensitivity)
+				i.overflowY[0].scrollTop = i.overflowY[0].scrollTop + o.scrollSpeed;
+			if(e.pageY - i.overflowYOffset.top < o.scrollSensitivity)
+				i.overflowY[0].scrollTop = i.overflowY[0].scrollTop - o.scrollSpeed;
+		} else {
+			if(e.pageY - $(document).scrollTop() < o.scrollSensitivity)
+				$(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
+			if($(window).height() - (e.pageY - $(document).scrollTop()) < o.scrollSensitivity)
+				$(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
+		}
+		
+		if(i.overflowX[0] != document && i.overflowX[0].tagName != 'HTML') {
+			if((i.overflowXOffset.left + i.overflowX[0].offsetWidth) - e.pageX < o.scrollSensitivity)
+				i.overflowX[0].scrollLeft = i.overflowX[0].scrollLeft + o.scrollSpeed;
+			if(e.pageX - i.overflowXOffset.left < o.scrollSensitivity)
+				i.overflowX[0].scrollLeft = i.overflowX[0].scrollLeft - o.scrollSpeed;
+		} else {
+			if(e.pageX - $(document).scrollLeft() < o.scrollSensitivity)
+				$(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
+			if($(window).width() - (e.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
+				$(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
+		}
+		
+	}
+});
+
+$.ui.plugin.add("sortable", "axis", {
+	sort: function(e, ui) {
+		
+		var i = $(this).data("sortable");
+		
+		if(ui.options.axis == "y") i.position.left = i.originalPosition.left;
+		if(ui.options.axis == "x") i.position.top = i.originalPosition.top;
+		
+	}
+});
+
+})(jQuery);
Index: /tags/2.0.2/template-common/lib/ui/ui.sortable.packed.js
===================================================================
--- /tags/2.0.2/template-common/lib/ui/ui.sortable.packed.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/ui.sortable.packed.js	(revision 3278)
@@ -0,0 +1,2 @@
+eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)d[e(c)]=k[c]||e(c);k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(b(B){b A(E,D){9 C=B.2Y.3Z&&B.2Y.3Y<3X;5(E.2X&&!C){d E.2X(D)}5(E.2W){d!!(E.2W(D)&16)}1T(D=D.1d){5(D==E){d V}}d w}B.3W("j.p",B.2j({},B.j.3V,{3U:b(){9 C=4.8;4.Q={};4.g.2a("j-p");4.2P();4.14=4.c.z?(/6|28/).1e(4.c[0].t.f("3T")):w;5(!(/(2V|1m|3S)/).1e(4.g.f("O"))){4.g.f("O","2V")}4.a=4.g.a();4.3R()},3Q:{},j:b(C){d{l:(C||4)["l"],r:(C||4)["r"]||B([]),O:(C||4)["O"],3P:(C||4)["18"],8:4.8,g:4.g,t:(C||4)["i"],3O:C?C.g:P}},v:b(F,E,C,D){B.j.1b.Y(4,F,[E,4.j(C)]);5(!D){4.g.2t(F=="1a"?F:"1a"+F,[E,4.j(C)],4.8[F])}},2i:b(E){9 C=(B.1N(4.8.c)?4.8.c.Y(4.g):B(4.8.c,4.g)).21(".j-p-l");9 D=[];E=E||{};C.1x(b(){9 F=(B(4).2S(E.3N||"2R")||"").3M(E.2T||(/(.+)[-=3L](.+)/));5(F){D.1y((E.2U||F[1])+"[]="+(E.2U&&E.2T?F[1]:F[2]))}});d D.3K("&")},2h:b(C){9 D=(B.1N(4.8.c)?4.8.c.Y(4.g):B(4.8.c,4.g)).21(".j-p-l");9 E=[];D.1x(b(){E.1y(B(4).2S(C||"2R"))});d E},2J:b(J){9 E=4.18.6,D=E+4.s.n,I=4.18.7,H=I+4.s.o;9 F=J.6,C=F+J.n,K=J.7,G=K+J.o;5(4.8.1r=="2Q"||4.8.3J||(4.8.1r=="1X"&&4.s[4.14?"n":"o"]>J[4.14?"n":"o"])){d(I+4.a.q.7>K&&I+4.a.q.7<G&&E+4.a.q.6>F&&E+4.a.q.6<C)}X{d(F<E+(4.s.n/2)&&D-(4.s.n/2)<C&&K<I+(4.s.o/2)&&H-(4.s.o/2)<G)}},2w:b(J){9 E=4.18.6,D=E+4.s.n,I=4.18.7,H=I+4.s.o;9 F=J.6,C=F+J.n,K=J.7,G=K+J.o;5(4.8.1r=="2Q"||(4.8.1r=="1X"&&4.s[4.14?"n":"o"]>J[4.14?"n":"o"])){5(!(I+4.a.q.7>K&&I+4.a.q.7<G&&E+4.a.q.6>F&&E+4.a.q.6<C)){d w}5(4.14){5(E+4.a.q.6>F&&E+4.a.q.6<F+J.n/2){d 2}5(E+4.a.q.6>F+J.n/2&&E+4.a.q.6<C){d 1}}X{5(I+4.a.q.7>K&&I+4.a.q.7<K+J.o/2){d 2}5(I+4.a.q.7>K+J.o/2&&I+4.a.q.7<G){d 1}}}X{5(!(F<E+(4.s.n/2)&&D-(4.s.n/2)<C&&K<I+(4.s.o/2)&&H-(4.s.o/2)<G)){d w}5(4.14){5(D>F&&E<F){d 2}5(E<C&&D>C){d 1}}X{5(H>K&&I<K){d 1}5(I<G&&H>G){d 2}}}d w},2P:b(){4.2b();4.1G()},2b:b(){4.c=[];4.e=[4];9 D=4.c;9 C=4;9 F=[[B.1N(4.8.c)?4.8.c.Y(4.g,P,{8:4.8,t:4.i}):B(4.8.c,4.g),4]];5(4.8.2e){R(9 G=4.8.2e.z-1;G>=0;G--){9 I=B(4.8.2e[G]);R(9 E=I.z-1;E>=0;E--){9 H=B.19(I[E],"p");5(H&&!H.8.2c){F.1y([B.1N(H.8.c)?H.8.c.Y(H.g):B(H.8.c,H.g),H]);4.e.1y(H)}}}}R(9 G=F.z-1;G>=0;G--){F[G][0].1x(b(){B.19(4,"p-t",F[G][1]);D.1y({t:B(4),2O:F[G][1],n:0,o:0,6:0,7:0})})}},1G:b(D){5(4.u){9 C=4.u.a();4.a.m={7:C.7+4.1v.7,6:C.6+4.1v.6}}R(9 F=4.c.z-1;F>=0;F--){5(4.c[F].2O!=4.1w&&4.1w&&4.c[F].t[0]!=4.i[0]){1I}9 E=4.8.2N?B(4.8.2N,4.c[F].t):4.c[F].t;5(!D){4.c[F].n=E[0].1Q;4.c[F].o=E[0].1S}9 G=E.a();4.c[F].6=G.6;4.c[F].7=G.7}5(4.8.2d&&4.8.2d.2M){4.8.2d.2M.Y(4)}X{R(9 F=4.e.z-1;F>=0;F--){9 G=4.e[F].g.a();4.e[F].Q.6=G.6;4.e[F].Q.7=G.7;4.e[F].Q.n=4.e[F].g.1L();4.e[F].Q.o=4.e[F].g.1K()}}},3I:b(){4.g.3H("j-p j-p-2c").2L("p").3G(".p");4.3F();R(9 C=4.c.z-1;C>=0;C--){4.c[C].t.2L("p-t")}},29:b(E){9 C=E||4,F=C.8;5(F.r.3E==3D){9 D=F.r;F.r={g:b(){d B("<2K></2K>").2a(D)[0]},1s:b(G,H){H.f(G.a()).f({n:G.1L(),o:G.1K()})}}}C.r=B(F.r.g.Y(C.g,C.i)).1D("U").f({O:"1m"});F.r.1s.Y(C.g,C.i,C.r)},2u:b(F){R(9 D=4.e.z-1;D>=0;D--){5(4.2J(4.e[D].Q)){5(!4.e[D].Q.1h){5(4.1w!=4.e[D]){9 I=3C;9 H=P;9 E=4.18[4.e[D].14?"6":"7"];R(9 C=4.c.z-1;C>=0;C--){5(!A(4.e[D].g[0],4.c[C].t[0])){1I}9 G=4.c[C][4.e[D].14?"6":"7"];5(1n.2I(G-E)<I){I=1n.2I(G-E);H=4.c[C]}}5(!H&&!4.8.2g){1I}5(4.r){4.r.1E()}5(4.e[D].8.r){4.e[D].29(4)}X{4.r=P}4.1w=4.e[D];H?4.1H(F,H,P,V):4.1H(F,P,4.e[D].g,V);4.v("23",F);4.e[D].v("23",F,4)}4.e[D].v("1h",F,4);4.e[D].Q.1h=1}}X{5(4.e[D].Q.1h){4.e[D].v("2m",F,4);4.e[D].Q.1h=0}}}},3B:b(G,F){5(4.8.2c||4.8.2v=="3A"){d w}4.2b();9 E=P,D=4,C=B(G.1M).2G().1x(b(){5(B.19(4,"p-t")==D){E=B(4);d w}});5(B.19(G.1M,"p-t")==D){E=B(G.1M)}5(!E){d w}5(4.8.2H&&!F){9 H=w;B(4.8.2H,E).3z("*").3y().1x(b(){5(4==G.1M){H=V}});5(!H){d w}}4.i=E;d V},3x:b(H,F,C){9 J=4.8;4.1w=4;4.1G();4.l=3w J.l=="b"?B(J.l.3v(4.g[0],[H,4.i])):4.i.1Y();5(!4.l.2G("U").z){B(J.1D!="m"?J.1D:4.i[0].1d)[0].2s(4.l[0])}4.l.f({O:"1m",1F:"3u"}).2a("j-p-l");4.W={6:(L(4.i.f("3t"),10)||0),7:(L(4.i.f("3s"),10)||0)};4.a=4.i.a();4.a={7:4.a.7-4.W.7,6:4.a.6-4.W.6};4.a.q={6:H.1i-4.a.6,7:H.1j-4.a.7};4.u=4.l.u();9 D=4.u.a();4.1v={7:(L(4.u.f("26"),10)||0),6:(L(4.u.f("27"),10)||0)};4.a.m={7:D.7+4.1v.7,6:D.6+4.1v.6};4.15=4.25(H);4.1Z={1t:4.i.1t()[0],m:4.i.m()[0]};4.s={n:4.l.1L(),o:4.l.1K()};5(J.r){4.29()}4.v("1p",H);4.s={n:4.l.1L(),o:4.l.1K()};5(J.13){5(J.13.6!=1J){4.a.q.6=J.13.6}5(J.13.28!=1J){4.a.q.6=4.s.n-J.13.28}5(J.13.7!=1J){4.a.q.7=J.13.7}5(J.13.2F!=1J){4.a.q.7=4.s.o-J.13.2F}}5(J.k){5(J.k=="m"){J.k=4.l[0].1d}5(J.k=="h"||J.k=="1c"){4.k=[0-4.a.m.6,0-4.a.m.7,B(J.k=="h"?h:1c).n()-4.a.m.6-4.s.n-4.W.6-(L(4.g.f("2E"),10)||0),(B(J.k=="h"?h:1c).o()||h.U.1d.2C)-4.a.m.7-4.s.o-4.W.7-(L(4.g.f("2B"),10)||0)]}5(!(/^(h|1c|m)$/).1e(J.k)){9 G=B(J.k)[0];9 I=B(J.k).a();4.k=[I.6+(L(B(G).f("27"),10)||0)-4.a.m.6,I.7+(L(B(G).f("26"),10)||0)-4.a.m.7,I.6+1n.2D(G.3r,G.1Q)-(L(B(G).f("27"),10)||0)-4.a.m.6-4.s.n-4.W.6-(L(4.i.f("2E"),10)||0),I.7+1n.2D(G.2C,G.1S)-(L(B(G).f("26"),10)||0)-4.a.m.7-4.s.o-4.W.7-(L(4.i.f("2B"),10)||0)]}}5(4.8.r!="1Y"){4.i.f("2k","3q")}5(!C){R(9 E=4.e.z-1;E>=0;E--){4.e[E].v("3p",H,4)}}5(B.j.17){B.j.17.3o=4}5(B.j.17&&!J.2p){B.j.17.3n(4,H)}4.2l=V;4.2z(H);d V},24:b(D,E){5(!E){E=4.O}9 C=D=="1m"?1:-1;d{7:(E.7+4.a.m.7*C-(4.u[0]==h.U?0:4.u[0].N)*C+4.W.7*C),6:(E.6+4.a.m.6*C-(4.u[0]==h.U?0:4.u[0].M)*C+4.W.6*C)}},25:b(F){9 G=4.8;9 C={7:(F.1j-4.a.q.7-4.a.m.7+(4.u[0]==h.U?0:4.u[0].N)),6:(F.1i-4.a.q.6-4.a.m.6+(4.u[0]==h.U?0:4.u[0].M))};5(!4.15){d C}5(4.k){5(C.6<4.k[0]){C.6=4.k[0]}5(C.7<4.k[1]){C.7=4.k[1]}5(C.6>4.k[2]){C.6=4.k[2]}5(C.7>4.k[3]){C.7=4.k[3]}}5(G.12){9 E=4.15.7+1n.2A((C.7-4.15.7)/G.12[1])*G.12[1];C.7=4.k?(!(E<4.k[1]||E>4.k[3])?E:(!(E<4.k[1])?E-G.12[1]:E+G.12[1])):E;9 D=4.15.6+1n.2A((C.6-4.15.6)/G.12[0])*G.12[0];C.6=4.k?(!(D<4.k[0]||D>4.k[2])?D:(!(D<4.k[0])?D-G.12[0]:D+G.12[0])):D}d C},2z:b(D){4.O=4.25(D);4.18=4.24("1m");B.j.1b.Y(4,"1a",[D,4.j()]);4.18=4.24("1m");4.l[0].2y.6=4.O.6+"2x";4.l[0].2y.7=4.O.7+"2x";R(9 C=4.c.z-1;C>=0;C--){9 E=4.2w(4.c[C]);5(!E){1I}5(4.c[C].t[0]!=4.i[0]&&4.i[E==1?"3m":"1t"]()[0]!=4.c[C].t[0]&&!A(4.i[0],4.c[C].t[0])&&(4.8.2v=="3l-3k"?!A(4.g[0],4.c[C].t[0]):V)){4.2r=E==1?"2q":"3j";4.1H(D,4.c[C]);4.v("23",D);3i}}4.2u(D);5(B.j.17){B.j.17.3h(4,D)}4.g.2t("1a",[D,4.j()],4.8["1a"]);d w},1H:b(H,G,D,F){D?D[0].2s(4.i[0]):G.t[0].1d.3g(4.i[0],(4.2r=="2q"?G.t[0]:G.t[0].3f));4.1u=4.1u?++4.1u:1;9 E=4,C=4.1u;1c.3e(b(){5(C==E.1u){E.1G(!F)}},0);5(4.8.r){4.8.r.1s.Y(4.g,4.i,4.r)}},3d:b(E,D){5(B.j.17&&!4.8.2p){B.j.17.3c(4,E)}5(4.8.22){9 C=4;9 F=C.i.a();5(C.r){C.r.2o({1f:"3b"},(L(4.8.22,10)||2n)-3a)}B(4.l).2o({6:F.6-4.a.m.6-C.W.6+(4.u[0]==h.U?0:4.u[0].M),7:F.7-4.a.m.7-C.W.7+(4.u[0]==h.U?0:4.u[0].N)},L(4.8.22,10)||2n,b(){C.1F(E)})}X{4.1F(E,D)}d w},1F:b(E,D){5(4.1Z.1t!=4.i.1t().21(".j-p-l")[0]||4.1Z.m!=4.i.m()[0]){4.v("1s",E,P,D)}5(!A(4.g[0],4.i[0])){4.v("1E",E,P,D);R(9 C=4.e.z-1;C>=0;C--){5(A(4.e[C].g[0],4.i[0])){4.e[C].v("1s",E,4,D);4.e[C].v("39",E,4,D)}}}R(9 C=4.e.z-1;C>=0;C--){4.e[C].v("38",E,4,D);5(4.e[C].Q.1h){4.e[C].v("2m",E,4);4.e[C].Q.1h=0}}4.2l=w;5(4.37){4.v("1q",E,P,D);d w}B(4.i).f("2k","");5(4.r){4.r.1E()}4.l.1E();4.l=P;4.v("1q",E,P,D);d V}}));B.2j(B.j.p,{36:"2i 2h",35:{l:"1Y",1r:"1X",34:1,33:0,1k:V,11:20,Z:20,32:":31",c:"> *",1g:30,2g:V,1D:"m"}});B.j.1b.1o("p","1l",{1p:b(E,D){9 C=B("U");5(C.f("1l")){D.8.1W=C.f("1l")}C.f("1l",D.8.1l)},1q:b(D,C){5(C.8.1W){B("U").f("1l",C.8.1W)}}});B.j.1b.1o("p","1g",{1p:b(E,D){9 C=D.l;5(C.f("1g")){D.8.1V=C.f("1g")}C.f("1g",D.8.1g)},1q:b(D,C){5(C.8.1V){B(C.l).f("1g",C.8.1V)}}});B.j.1b.1o("p","1f",{1p:b(E,D){9 C=D.l;5(C.f("1f")){D.8.1U=C.f("1f")}C.f("1f",D.8.1f)},1q:b(D,C){5(C.8.1U){B(C.l).f("1f",C.8.1U)}}});B.j.1b.1o("p","1k",{1p:b(E,D){9 F=D.8;9 C=B(4).19("p");C.T=b(G){2f{5(/1C|1k/.1e(G.f("1B"))||(/1C|1k/).1e(G.f("1B-y"))){d G}G=G.m()}1T(G[0].1d);d B(h)}(C.i);C.S=b(G){2f{5(/1C|1k/.1e(G.f("1B"))||(/1C|1k/).1e(G.f("1B-x"))){d G}G=G.m()}1T(G[0].1d);d B(h)}(C.i);5(C.T[0]!=h&&C.T[0].1A!="1z"){C.1R=C.T.a()}5(C.S[0]!=h&&C.S[0].1A!="1z"){C.1P=C.S.a()}},1a:b(E,D){9 F=D.8;9 C=B(4).19("p");5(C.T[0]!=h&&C.T[0].1A!="1z"){5((C.1R.7+C.T[0].1S)-E.1j<F.11){C.T[0].N=C.T[0].N+F.Z}5(E.1j-C.1R.7<F.11){C.T[0].N=C.T[0].N-F.Z}}X{5(E.1j-B(h).N()<F.11){B(h).N(B(h).N()-F.Z)}5(B(1c).o()-(E.1j-B(h).N())<F.11){B(h).N(B(h).N()+F.Z)}}5(C.S[0]!=h&&C.S[0].1A!="1z"){5((C.1P.6+C.S[0].1Q)-E.1i<F.11){C.S[0].M=C.S[0].M+F.Z}5(E.1i-C.1P.6<F.11){C.S[0].M=C.S[0].M-F.Z}}X{5(E.1i-B(h).M()<F.11){B(h).M(B(h).M()-F.Z)}5(B(1c).n()-(E.1i-B(h).M())<F.11){B(h).M(B(h).M()+F.Z)}}}});B.j.1b.1o("p","1O",{1a:b(E,D){9 C=B(4).19("p");5(D.8.1O=="y"){C.O.6=C.15.6}5(D.8.1O=="x"){C.O.7=C.15.7}}})})(2Z)',62,248,'||||this|if|left|top|options|var|offset|function|items|return|containers|css|element|document|currentItem|ui|containment|helper|parent|width|height|sortable|click|placeholder|helperProportions|item|offsetParent|propagate|false|||length||||||||||||parseInt|scrollLeft|scrollTop|position|null|containerCache|for|overflowX|overflowY|body|true|margins|else|call|scrollSpeed||scrollSensitivity|grid|cursorAt|floating|originalPosition||ddmanager|positionAbs|data|sort|plugin|window|parentNode|test|opacity|zIndex|over|pageX|pageY|scroll|cursor|absolute|Math|add|start|stop|tolerance|update|prev|counter|offsetParentBorders|currentContainer|each|push|HTML|tagName|overflow|auto|appendTo|remove|clear|refreshPositions|rearrange|continue|undefined|outerHeight|outerWidth|target|isFunction|axis|overflowXOffset|offsetWidth|overflowYOffset|offsetHeight|while|_opacity|_zIndex|_cursor|guess|clone|domPosition||not|revert|change|convertPositionTo|generatePosition|borderTopWidth|borderLeftWidth|right|createPlaceholder|addClass|refreshItems|disabled|custom|connectWith|do|dropOnEmpty|toArray|serialize|extend|visibility|dragging|out|500|animate|dropBehaviour|down|direction|appendChild|triggerHandler|contactContainers|type|intersectsWithEdge|px|style|mouseDrag|round|marginBottom|scrollHeight|max|marginRight|bottom|parents|handle|abs|intersectsWith|div|removeData|refreshContainers|toleranceElement|instance|refresh|pointer|id|attr|expression|key|relative|compareDocumentPosition|contains|browser|jQuery|1000|input|cancel|delay|distance|defaults|getter|cancelHelperRemoval|deactivate|receive|50|hide|drop|mouseStop|setTimeout|nextSibling|insertBefore|drag|break|up|dynamic|semi|next|prepareOffsets|current|activate|hidden|scrollWidth|marginTop|marginLeft|both|apply|typeof|mouseStart|andSelf|find|static|mouseCapture|10000|String|constructor|mouseDestroy|unbind|removeClass|destroy|forcePointerForContainers|join|_|match|attribute|sender|absolutePosition|plugins|mouseInit|fixed|float|init|mouse|widget|522|version|safari'.split('|'),0,{}))
+
Index: /tags/2.0.2/template-common/lib/ui/ui.tabs.js
===================================================================
--- /tags/2.0.2/template-common/lib/ui/ui.tabs.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/ui.tabs.js	(revision 3278)
@@ -0,0 +1,599 @@
+/*
+ * jQuery UI Tabs
+ *
+ * Copyright (c) 2007, 2008 Klaus Hartl (stilbuero.de)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Tabs
+ *
+ * Depends:
+ *	ui.core.js
+ */
+(function($) {
+
+$.widget("ui.tabs", {
+	init: function() {
+		this.options.event += '.tabs'; // namespace event
+		
+		// create tabs
+		this.tabify(true);
+	},
+	setData: function(key, value) {
+		if ((/^selected/).test(key))
+			this.select(value);
+		else {
+			this.options[key] = value;
+			this.tabify();
+		}
+	},
+	length: function() {
+		return this.$tabs.length;
+	},
+	tabId: function(a) {
+		return a.title && a.title.replace(/\s/g, '_').replace(/[^A-Za-z0-9\-_:\.]/g, '')
+			|| this.options.idPrefix + $.data(a);
+	},
+	ui: function(tab, panel) {
+		return {
+			options: this.options,
+			tab: tab,
+			panel: panel,
+			index: this.$tabs.index(tab)
+		};
+	},
+	tabify: function(init) {
+
+		this.$lis = $('li:has(a[href])', this.element);
+		this.$tabs = this.$lis.map(function() { return $('a', this)[0]; });
+		this.$panels = $([]);
+
+		var self = this, o = this.options;
+
+		this.$tabs.each(function(i, a) {
+			// inline tab
+			if (a.hash && a.hash.replace('#', '')) // Safari 2 reports '#' for an empty hash
+				self.$panels = self.$panels.add(a.hash);
+			// remote tab
+			else if ($(a).attr('href') != '#') { // prevent loading the page itself if href is just "#"
+				$.data(a, 'href.tabs', a.href); // required for restore on destroy
+				$.data(a, 'load.tabs', a.href); // mutable
+				var id = self.tabId(a);
+				a.href = '#' + id;
+				var $panel = $('#' + id);
+				if (!$panel.length) {
+					$panel = $(o.panelTemplate).attr('id', id).addClass(o.panelClass)
+						.insertAfter( self.$panels[i - 1] || self.element );
+					$panel.data('destroy.tabs', true);
+				}
+				self.$panels = self.$panels.add( $panel );
+			}
+			// invalid tab href
+			else
+				o.disabled.push(i + 1);
+		});
+
+		if (init) {
+
+			// attach necessary classes for styling if not present
+			this.element.addClass(o.navClass);
+			this.$panels.each(function() {
+				var $this = $(this);
+				$this.addClass(o.panelClass);
+			});
+
+			// Selected tab
+			// use "selected" option or try to retrieve:
+			// 1. from fragment identifier in url
+			// 2. from cookie
+			// 3. from selected class attribute on <li>
+			if (o.selected === undefined) {
+				if (location.hash) {
+					this.$tabs.each(function(i, a) {
+						if (a.hash == location.hash) {
+							o.selected = i;
+							// prevent page scroll to fragment
+							if ($.browser.msie || $.browser.opera) { // && !o.remote
+								var $toShow = $(location.hash), toShowId = $toShow.attr('id');
+								$toShow.attr('id', '');
+								setTimeout(function() {
+									$toShow.attr('id', toShowId); // restore id
+								}, 500);
+							}
+							scrollTo(0, 0);
+							return false; // break
+						}
+					});
+				}
+				else if (o.cookie) {
+					var index = parseInt($.cookie('ui-tabs' + $.data(self.element)),10);
+					if (index && self.$tabs[index])
+						o.selected = index;
+				}
+				else if (self.$lis.filter('.' + o.selectedClass).length)
+					o.selected = self.$lis.index( self.$lis.filter('.' + o.selectedClass)[0] );
+			}
+			o.selected = o.selected === null || o.selected !== undefined ? o.selected : 0; // first tab selected by default
+
+			// Take disabling tabs via class attribute from HTML
+			// into account and update option properly.
+			// A selected tab cannot become disabled.
+			o.disabled = $.unique(o.disabled.concat(
+				$.map(this.$lis.filter('.' + o.disabledClass),
+					function(n, i) { return self.$lis.index(n); } )
+			)).sort();
+			if ($.inArray(o.selected, o.disabled) != -1)
+				o.disabled.splice($.inArray(o.selected, o.disabled), 1);
+			
+			// highlight selected tab
+			this.$panels.addClass(o.hideClass);
+			this.$lis.removeClass(o.selectedClass);
+			if (o.selected !== null) {
+				this.$panels.eq(o.selected).show().removeClass(o.hideClass); // use show and remove class to show in any case no matter how it has been hidden before
+				this.$lis.eq(o.selected).addClass(o.selectedClass);
+				
+				// seems to be expected behavior that the show callback is fired
+				var onShow = function() {
+					$(self.element).triggerHandler('tabsshow',
+						[self.fakeEvent('tabsshow'), self.ui(self.$tabs[o.selected], self.$panels[o.selected])], o.show);
+				}; 
+
+				// load if remote tab
+				if ($.data(this.$tabs[o.selected], 'load.tabs'))
+					this.load(o.selected, onShow);
+				// just trigger show event
+				else
+					onShow();
+				
+			}
+			
+			// clean up to avoid memory leaks in certain versions of IE 6
+			$(window).bind('unload', function() {
+				self.$tabs.unbind('.tabs');
+				self.$lis = self.$tabs = self.$panels = null;
+			});
+
+		}
+
+		// disable tabs
+		for (var i = 0, li; li = this.$lis[i]; i++)
+			$(li)[$.inArray(i, o.disabled) != -1 && !$(li).hasClass(o.selectedClass) ? 'addClass' : 'removeClass'](o.disabledClass);
+
+		// reset cache if switching from cached to not cached
+		if (o.cache === false)
+			this.$tabs.removeData('cache.tabs');
+		
+		// set up animations
+		var hideFx, showFx, baseFx = { 'min-width': 0, duration: 1 }, baseDuration = 'normal';
+		if (o.fx && o.fx.constructor == Array)
+			hideFx = o.fx[0] || baseFx, showFx = o.fx[1] || baseFx;
+		else
+			hideFx = showFx = o.fx || baseFx;
+
+		// reset some styles to maintain print style sheets etc.
+		var resetCSS = { display: '', overflow: '', height: '' };
+		if (!$.browser.msie) // not in IE to prevent ClearType font issue
+			resetCSS.opacity = '';
+
+		// Hide a tab, animation prevents browser scrolling to fragment,
+		// $show is optional.
+		function hideTab(clicked, $hide, $show) {
+			$hide.animate(hideFx, hideFx.duration || baseDuration, function() { //
+				$hide.addClass(o.hideClass).css(resetCSS); // maintain flexible height and accessibility in print etc.
+				if ($.browser.msie && hideFx.opacity)
+					$hide[0].style.filter = '';
+				if ($show)
+					showTab(clicked, $show, $hide);
+			});
+		}
+
+		// Show a tab, animation prevents browser scrolling to fragment,
+		// $hide is optional.
+		function showTab(clicked, $show, $hide) {
+			if (showFx === baseFx)
+				$show.css('display', 'block'); // prevent occasionally occuring flicker in Firefox cause by gap between showing and hiding the tab panels
+			$show.animate(showFx, showFx.duration || baseDuration, function() {
+				$show.removeClass(o.hideClass).css(resetCSS); // maintain flexible height and accessibility in print etc.
+				if ($.browser.msie && showFx.opacity)
+					$show[0].style.filter = '';
+
+				// callback
+				$(self.element).triggerHandler('tabsshow',
+					[self.fakeEvent('tabsshow'), self.ui(clicked, $show[0])], o.show);
+
+			});
+		}
+
+		// switch a tab
+		function switchTab(clicked, $li, $hide, $show) {
+			/*if (o.bookmarkable && trueClick) { // add to history only if true click occured, not a triggered click
+				$.ajaxHistory.update(clicked.hash);
+			}*/
+			$li.addClass(o.selectedClass)
+				.siblings().removeClass(o.selectedClass);
+			hideTab(clicked, $hide, $show);
+		}
+
+		// attach tab event handler, unbind to avoid duplicates from former tabifying...
+		this.$tabs.unbind('.tabs').bind(o.event, function() {
+
+			//var trueClick = e.clientX; // add to history only if true click occured, not a triggered click
+			var $li = $(this).parents('li:eq(0)'),
+				$hide = self.$panels.filter(':visible'),
+				$show = $(this.hash);
+
+			// If tab is already selected and not unselectable or tab disabled or 
+			// or is already loading or click callback returns false stop here.
+			// Check if click handler returns false last so that it is not executed
+			// for a disabled or loading tab!
+			if (($li.hasClass(o.selectedClass) && !o.unselect)
+				|| $li.hasClass(o.disabledClass) 
+				|| $(this).hasClass(o.loadingClass)
+				|| $(self.element).triggerHandler('tabsselect', [self.fakeEvent('tabsselect'), self.ui(this, $show[0])], o.select) === false
+				) {
+				this.blur();
+				return false;
+			}
+
+			self.options.selected = self.$tabs.index(this);
+
+			// if tab may be closed
+			if (o.unselect) {
+				if ($li.hasClass(o.selectedClass)) {
+					self.options.selected = null;
+					$li.removeClass(o.selectedClass);
+					self.$panels.stop();
+					hideTab(this, $hide);
+					this.blur();
+					return false;
+				} else if (!$hide.length) {
+					self.$panels.stop();
+					var a = this;
+					self.load(self.$tabs.index(this), function() {
+						$li.addClass(o.selectedClass).addClass(o.unselectClass);
+						showTab(a, $show);
+					});
+					this.blur();
+					return false;
+				}
+			}
+
+			if (o.cookie)
+				$.cookie('ui-tabs' + $.data(self.element), self.options.selected, o.cookie);
+
+			// stop possibly running animations
+			self.$panels.stop();
+
+			// show new tab
+			if ($show.length) {
+
+				// prevent scrollbar scrolling to 0 and than back in IE7, happens only if bookmarking/history is enabled
+				/*if ($.browser.msie && o.bookmarkable) {
+					var showId = this.hash.replace('#', '');
+					$show.attr('id', '');
+					setTimeout(function() {
+						$show.attr('id', showId); // restore id
+					}, 0);
+				}*/
+
+				var a = this;
+				self.load(self.$tabs.index(this), $hide.length ? 
+					function() {
+						switchTab(a, $li, $hide, $show);
+					} :
+					function() {
+						$li.addClass(o.selectedClass);
+						showTab(a, $show);
+					}
+				);
+
+				// Set scrollbar to saved position - need to use timeout with 0 to prevent browser scroll to target of hash
+				/*var scrollX = window.pageXOffset || document.documentElement && document.documentElement.scrollLeft || document.body.scrollLeft || 0;
+				var scrollY = window.pageYOffset || document.documentElement && document.documentElement.scrollTop || document.body.scrollTop || 0;
+				setTimeout(function() {
+					scrollTo(scrollX, scrollY);
+				}, 0);*/
+
+			} else
+				throw 'jQuery UI Tabs: Mismatching fragment identifier.';
+
+			// Prevent IE from keeping other link focussed when using the back button
+			// and remove dotted border from clicked link. This is controlled in modern
+			// browsers via CSS, also blur removes focus from address bar in Firefox
+			// which can become a usability and annoying problem with tabsRotate.
+			if ($.browser.msie)
+				this.blur();
+
+			//return o.bookmarkable && !!trueClick; // convert trueClick == undefined to Boolean required in IE
+			return false;
+
+		});
+
+		// disable click if event is configured to something else
+		if (!(/^click/).test(o.event))
+			this.$tabs.bind('click.tabs', function() { return false; });
+
+	},
+	add: function(url, label, index) {
+		if (index == undefined) 
+			index = this.$tabs.length; // append by default
+
+		var o = this.options;
+		var $li = $(o.tabTemplate.replace(/#\{href\}/g, url).replace(/#\{label\}/g, label));
+		$li.data('destroy.tabs', true);
+
+		var id = url.indexOf('#') == 0 ? url.replace('#', '') : this.tabId( $('a:first-child', $li)[0] );
+
+		// try to find an existing element before creating a new one
+		var $panel = $('#' + id);
+		if (!$panel.length) {
+			$panel = $(o.panelTemplate).attr('id', id)
+				.addClass(o.hideClass)
+				.data('destroy.tabs', true);
+		}
+		$panel.addClass(o.panelClass);
+		if (index >= this.$lis.length) {
+			$li.appendTo(this.element);
+			$panel.appendTo(this.element[0].parentNode);
+		} else {
+			$li.insertBefore(this.$lis[index]);
+			$panel.insertBefore(this.$panels[index]);
+		}
+		
+		o.disabled = $.map(o.disabled,
+			function(n, i) { return n >= index ? ++n : n });
+			
+		this.tabify();
+
+		if (this.$tabs.length == 1) {
+			$li.addClass(o.selectedClass);
+			$panel.removeClass(o.hideClass);
+			var href = $.data(this.$tabs[0], 'load.tabs');
+			if (href)
+				this.load(index, href);
+		}
+
+		// callback
+		this.element.triggerHandler('tabsadd',
+			[this.fakeEvent('tabsadd'), this.ui(this.$tabs[index], this.$panels[index])], o.add
+		);
+	},
+	remove: function(index) {
+		var o = this.options, $li = this.$lis.eq(index).remove(),
+			$panel = this.$panels.eq(index).remove();
+
+		// If selected tab was removed focus tab to the right or
+		// in case the last tab was removed the tab to the left.
+		if ($li.hasClass(o.selectedClass) && this.$tabs.length > 1)
+			this.select(index + (index + 1 < this.$tabs.length ? 1 : -1));
+
+		o.disabled = $.map($.grep(o.disabled, function(n, i) { return n != index; }),
+			function(n, i) { return n >= index ? --n : n });
+
+		this.tabify();
+
+		// callback
+		this.element.triggerHandler('tabsremove',
+			[this.fakeEvent('tabsremove'), this.ui($li.find('a')[0], $panel[0])], o.remove
+		);
+	},
+	enable: function(index) {
+		var o = this.options;
+		if ($.inArray(index, o.disabled) == -1)
+			return;
+			
+		var $li = this.$lis.eq(index).removeClass(o.disabledClass);
+		if ($.browser.safari) { // fix disappearing tab (that used opacity indicating disabling) after enabling in Safari 2...
+			$li.css('display', 'inline-block');
+			setTimeout(function() {
+				$li.css('display', 'block');
+			}, 0);
+		}
+
+		o.disabled = $.grep(o.disabled, function(n, i) { return n != index; });
+
+		// callback
+		this.element.triggerHandler('tabsenable',
+			[this.fakeEvent('tabsenable'), this.ui(this.$tabs[index], this.$panels[index])], o.enable
+		);
+
+	},
+	disable: function(index) {
+		var self = this, o = this.options;
+		if (index != o.selected) { // cannot disable already selected tab
+			this.$lis.eq(index).addClass(o.disabledClass);
+
+			o.disabled.push(index);
+			o.disabled.sort();
+
+			// callback
+			this.element.triggerHandler('tabsdisable',
+				[this.fakeEvent('tabsdisable'), this.ui(this.$tabs[index], this.$panels[index])], o.disable
+			);
+		}
+	},
+	select: function(index) {
+		if (typeof index == 'string')
+			index = this.$tabs.index( this.$tabs.filter('[href$=' + index + ']')[0] );
+		this.$tabs.eq(index).trigger(this.options.event);
+	},
+	load: function(index, callback) { // callback is for internal usage only
+		
+		var self = this, o = this.options, $a = this.$tabs.eq(index), a = $a[0],
+				bypassCache = callback == undefined || callback === false, url = $a.data('load.tabs');
+
+		callback = callback || function() {};
+		
+		// no remote or from cache - just finish with callback
+		if (!url || !bypassCache && $.data(a, 'cache.tabs')) {
+			callback();
+			return;
+		}
+
+		// load remote from here on
+		
+		var inner = function(parent) {
+			var $parent = $(parent), $inner = $parent.find('*:last');
+			return $inner.length && $inner.is(':not(img)') && $inner || $parent;
+		};
+		var cleanup = function() {
+			self.$tabs.filter('.' + o.loadingClass).removeClass(o.loadingClass)
+						.each(function() {
+							if (o.spinner)
+								inner(this).parent().html(inner(this).data('label.tabs'));
+						});
+			self.xhr = null;
+		};
+		
+		if (o.spinner) {
+			var label = inner(a).html();
+			inner(a).wrapInner('<em></em>')
+				.find('em').data('label.tabs', label).html(o.spinner);
+		}
+
+		var ajaxOptions = $.extend({}, o.ajaxOptions, {
+			url: url,
+			success: function(r, s) {
+				$(a.hash).html(r);
+				cleanup();
+				
+				if (o.cache)
+					$.data(a, 'cache.tabs', true); // if loaded once do not load them again
+
+				// callbacks
+				$(self.element).triggerHandler('tabsload',
+					[self.fakeEvent('tabsload'), self.ui(self.$tabs[index], self.$panels[index])], o.load
+				);
+				o.ajaxOptions.success && o.ajaxOptions.success(r, s);
+				
+				// This callback is required because the switch has to take
+				// place after loading has completed. Call last in order to 
+				// fire load before show callback...
+				callback();
+			}
+		});
+		if (this.xhr) {
+			// terminate pending requests from other tabs and restore tab label
+			this.xhr.abort();
+			cleanup();
+		}
+		$a.addClass(o.loadingClass);
+		setTimeout(function() { // timeout is again required in IE, "wait" for id being restored
+			self.xhr = $.ajax(ajaxOptions);
+		}, 0);
+
+	},
+	url: function(index, url) {
+		this.$tabs.eq(index).removeData('cache.tabs').data('load.tabs', url);
+	},
+	destroy: function() {
+		var o = this.options;
+		this.element.unbind('.tabs')
+			.removeClass(o.navClass).removeData('tabs');
+		this.$tabs.each(function() {
+			var href = $.data(this, 'href.tabs');
+			if (href)
+				this.href = href;
+			var $this = $(this).unbind('.tabs');
+			$.each(['href', 'load', 'cache'], function(i, prefix) {
+				$this.removeData(prefix + '.tabs');
+			});
+		});
+		this.$lis.add(this.$panels).each(function() {
+			if ($.data(this, 'destroy.tabs'))
+				$(this).remove();
+			else
+				$(this).removeClass([o.selectedClass, o.unselectClass,
+					o.disabledClass, o.panelClass, o.hideClass].join(' '));
+		});
+	},
+	fakeEvent: function(type) {
+		return $.event.fix({
+			type: type,
+			target: this.element[0]
+		});
+	}
+});
+
+$.ui.tabs.defaults = {
+	// basic setup
+	unselect: false,
+	event: 'click',
+	disabled: [],
+	cookie: null, // e.g. { expires: 7, path: '/', domain: 'jquery.com', secure: true }
+	// TODO history: false,
+
+	// Ajax
+	spinner: 'Loading&#8230;',
+	cache: false,
+	idPrefix: 'ui-tabs-',
+	ajaxOptions: {},
+
+	// animations
+	fx: null, // e.g. { height: 'toggle', opacity: 'toggle', duration: 200 }
+
+	// templates
+	tabTemplate: '<li><a href="#{href}"><span>#{label}</span></a></li>',
+	panelTemplate: '<div></div>',
+
+	// CSS classes
+	navClass: 'ui-tabs-nav',
+	selectedClass: 'ui-tabs-selected',
+	unselectClass: 'ui-tabs-unselect',
+	disabledClass: 'ui-tabs-disabled',
+	panelClass: 'ui-tabs-panel',
+	hideClass: 'ui-tabs-hide',
+	loadingClass: 'ui-tabs-loading'
+};
+
+$.ui.tabs.getter = "length";
+
+/*
+ * Tabs Extensions
+ */
+
+/*
+ * Rotate
+ */
+$.extend($.ui.tabs.prototype, {
+	rotation: null,
+	rotate: function(ms, continuing) {
+		
+		continuing = continuing || false;
+		
+		var self = this, t = this.options.selected;
+		
+		function start() {
+			self.rotation = setInterval(function() {
+				t = ++t < self.$tabs.length ? t : 0;
+				self.select(t);
+			}, ms); 
+		}
+		
+		function stop(e) {
+			if (!e || e.clientX) { // only in case of a true click
+				clearInterval(self.rotation);
+			}
+		}
+		
+		// start interval
+		if (ms) {
+			start();
+			if (!continuing)
+				this.$tabs.bind(this.options.event, stop);
+			else
+				this.$tabs.bind(this.options.event, function() {
+					stop();
+					t = self.options.selected;
+					start();
+				});
+		}
+		// stop interval
+		else {
+			stop();
+			this.$tabs.unbind(this.options.event, stop);
+		}
+	}
+});
+
+})(jQuery);
Index: /tags/2.0.2/template-common/lib/ui/ui.tabs.packed.js
===================================================================
--- /tags/2.0.2/template-common/lib/ui/ui.tabs.packed.js	(revision 3278)
+++ /tags/2.0.2/template-common/lib/ui/ui.tabs.packed.js	(revision 3278)
@@ -0,0 +1,2 @@
+eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)d[e(c)]=k[c]||e(c);k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(4(A){A.3g("8.3",{3f:4(){2.c.t+=".3";2.1f(1d)},3e:4(B,C){5((/^7/).26(B)){2.17(C)}m{2.c[B]=C;2.1f()}},j:4(){d 2.$3.j},1G:4(B){d B.2b&&B.2b.14(/\\s/g,"2a").14(/[^A-3d-3c-9\\-2a:\\.]/g,"")||2.c.1S+A.f(B)},8:4(C,B){d{c:2.c,3b:C,1O:B,V:2.$3.V(C)}},1f:4(O){2.$i=A("1j:3a(a[n])",2.h);2.$3=2.$i.1t(4(){d A("a",2)[0]});2.$b=A([]);6 P=2,D=2.c;2.$3.X(4(R,Q){5(Q.v&&Q.v.14("#","")){P.$b=P.$b.1c(Q.v)}m{5(A(Q).13("n")!="#"){A.f(Q,"n.3",Q.n);A.f(Q,"p.3",Q.n);6 T=P.1G(Q);Q.n="#"+T;6 S=A("#"+T);5(!S.j){S=A(D.1z).13("1g",T).l(D.19).39(P.$b[R-1]||P.h);S.f("1b.3",1d)}P.$b=P.$b.1c(S)}m{D.e.1Y(R+1)}}});5(O){2.h.l(D.1y);2.$b.X(4(){6 Q=A(2);Q.l(D.19)});5(D.7===1q){5(1L.v){2.$3.X(4(S,Q){5(Q.v==1L.v){D.7=S;5(A.Y.1h||A.Y.38){6 R=A(1L.v),T=R.13("1g");R.13("1g","");1B(4(){R.13("1g",T)},37)}36(0,0);d o}})}m{5(D.11){6 J=35(A.11("8-3"+A.f(P.h)),10);5(J&&P.$3[J]){D.7=J}}m{5(P.$i.U("."+D.k).j){D.7=P.$i.V(P.$i.U("."+D.k)[0])}}}}D.7=D.7===w||D.7!==1q?D.7:0;D.e=A.34(D.e.33(A.1t(2.$i.U("."+D.W),4(R,Q){d P.$i.V(R)}))).1X();5(A.1s(D.7,D.e)!=-1){D.e.32(A.1s(D.7,D.e),1)}2.$b.l(D.x);2.$i.q(D.k);5(D.7!==w){2.$b.r(D.7).1I().q(D.x);2.$i.r(D.7).l(D.k);6 K=4(){A(P.h).z("1v",[P.u("1v"),P.8(P.$3[D.7],P.$b[D.7])],D.1I)};5(A.f(2.$3[D.7],"p.3")){2.p(D.7,K)}m{K()}}A(31).16("30",4(){P.$3.15(".3");P.$i=P.$3=P.$b=w})}2Z(6 G=0,N;N=2.$i[G];G++){A(N)[A.1s(G,D.e)!=-1&&!A(N).12(D.k)?"l":"q"](D.W)}5(D.y===o){2.$3.1n("y.3")}6 C,I,B={"2Y-2X":0,1K:1},E="2W";5(D.Z&&D.Z.2V==2U){C=D.Z[0]||B,I=D.Z[1]||B}m{C=I=D.Z||B}6 H={1r:"",2T:"",2S:""};5(!A.Y.1h){H.1J=""}4 M(R,Q,S){Q.29(C,C.1K||E,4(){Q.l(D.x).1e(H);5(A.Y.1h&&C.1J){Q[0].28.U=""}5(S){L(R,S,Q)}})}4 L(R,S,Q){5(I===B){S.1e("1r","1F")}S.29(I,I.1K||E,4(){S.q(D.x).1e(H);5(A.Y.1h&&I.1J){S[0].28.U=""}A(P.h).z("1v",[P.u("1v"),P.8(R,S[0])],D.1I)})}4 F(R,T,Q,S){T.l(D.k).2R().q(D.k);M(R,Q,S)}2.$3.15(".3").16(D.t,4(){6 T=A(2).2Q("1j:r(0)"),Q=P.$b.U(":2P"),S=A(2.v);5((T.12(D.k)&&!D.1i)||T.12(D.W)||A(2).12(D.18)||A(P.h).z("27",[P.u("27"),P.8(2,S[0])],D.17)===o){2.1u();d o}P.c.7=P.$3.V(2);5(D.1i){5(T.12(D.k)){P.c.7=w;T.q(D.k);P.$b.1H();M(2,Q);2.1u();d o}m{5(!Q.j){P.$b.1H();6 R=2;P.p(P.$3.V(2),4(){T.l(D.k).l(D.1x);L(R,S)});2.1u();d o}}}5(D.11){A.11("8-3"+A.f(P.h),P.c.7,D.11)}P.$b.1H();5(S.j){6 R=2;P.p(P.$3.V(2),Q.j?4(){F(R,T,Q,S)}:4(){T.l(D.k);L(R,S)})}m{2O"1M 2N 2M: 2L 2K 2J."}5(A.Y.1h){2.1u()}d o});5(!(/^1A/).26(D.t)){2.$3.16("1A.3",4(){d o})}},1c:4(E,D,C){5(C==1q){C=2.$3.j}6 G=2.c;6 I=A(G.1R.14(/#\\{n\\}/g,E).14(/#\\{1k\\}/g,D));I.f("1b.3",1d);6 H=E.2I("#")==0?E.14("#",""):2.1G(A("a:2H-2G",I)[0]);6 F=A("#"+H);5(!F.j){F=A(G.1z).13("1g",H).l(G.x).f("1b.3",1d)}F.l(G.19);5(C>=2.$i.j){I.25(2.h);F.25(2.h[0].2F)}m{I.24(2.$i[C]);F.24(2.$b[C])}G.e=A.1t(G.e,4(K,J){d K>=C?++K:K});2.1f();5(2.$3.j==1){I.l(G.k);F.q(G.x);6 B=A.f(2.$3[0],"p.3");5(B){2.p(C,B)}}2.h.z("23",[2.u("23"),2.8(2.$3[C],2.$b[C])],G.1c)},1a:4(B){6 D=2.c,E=2.$i.r(B).1a(),C=2.$b.r(B).1a();5(E.12(D.k)&&2.$3.j>1){2.17(B+(B+1<2.$3.j?1:-1))}D.e=A.1t(A.21(D.e,4(G,F){d G!=B}),4(G,F){d G>=B?--G:G});2.1f();2.h.z("22",[2.u("22"),2.8(E.1E("a")[0],C[0])],D.1a)},1Z:4(B){6 C=2.c;5(A.1s(B,C.e)==-1){d}6 D=2.$i.r(B).q(C.W);5(A.Y.2E){D.1e("1r","2D-1F");1B(4(){D.1e("1r","1F")},0)}C.e=A.21(C.e,4(F,E){d F!=B});2.h.z("20",[2.u("20"),2.8(2.$3[B],2.$b[B])],C.1Z)},1V:4(C){6 B=2,D=2.c;5(C!=D.7){2.$i.r(C).l(D.W);D.e.1Y(C);D.e.1X();2.h.z("1W",[2.u("1W"),2.8(2.$3[C],2.$b[C])],D.1V)}},17:4(B){5(2C B=="2B"){B=2.$3.V(2.$3.U("[n$="+B+"]")[0])}2.$3.r(B).2A(2.c.t)},p:4(G,K){6 L=2,D=2.c,E=2.$3.r(G),J=E[0],H=K==1q||K===o,B=E.f("p.3");K=K||4(){};5(!B||!H&&A.f(J,"y.3")){K();d}6 M=4(N){6 O=A(N),P=O.1E("*:2z");d P.j&&P.2y(":2x(2w)")&&P||O};6 C=4(){L.$3.U("."+D.18).q(D.18).X(4(){5(D.1m){M(2).2v().1p(M(2).f("1k.3"))}});L.1o=w};5(D.1m){6 I=M(J).1p();M(J).2u("<1D></1D>").1E("1D").f("1k.3",I).1p(D.1m)}6 F=A.1N({},D.1l,{1T:B,1C:4(O,N){A(J.v).1p(O);C();5(D.y){A.f(J,"y.3",1d)}A(L.h).z("1U",[L.u("1U"),L.8(L.$3[G],L.$b[G])],D.p);D.1l.1C&&D.1l.1C(O,N);K()}});5(2.1o){2.1o.2t();C()}E.l(D.18);1B(4(){L.1o=A.2s(F)},0)},1T:4(C,B){2.$3.r(C).1n("y.3").f("p.3",B)},1b:4(){6 B=2.c;2.h.15(".3").q(B.1y).1n("3");2.$3.X(4(){6 C=A.f(2,"n.3");5(C){2.n=C}6 D=A(2).15(".3");A.X(["n","p","y"],4(E,F){D.1n(F+".3")})});2.$i.1c(2.$b).X(4(){5(A.f(2,"1b.3")){A(2).1a()}m{A(2).q([B.k,B.1x,B.W,B.19,B.x].2r(" "))}})},u:4(B){d A.t.2q({2p:B,2o:2.h[0]})}});A.8.3.2n={1i:o,t:"1A",e:[],11:w,1m:"2m&#2l;",y:o,1S:"8-3-",1l:{},Z:w,1R:\'<1j><a n="#{n}"><1Q>#{1k}</1Q></a></1j>\',1z:"<1P></1P>",1y:"8-3-2k",k:"8-3-7",1x:"8-3-1i",W:"8-3-e",19:"8-3-1O",x:"8-3-2j",18:"8-3-2i"};A.8.3.2h="j";A.1N(A.8.3.2g,{1w:w,2f:4(C,F){F=F||o;6 B=2,E=2.c.7;4 G(){B.1w=2e(4(){E=++E<B.$3.j?E:0;B.17(E)},C)}4 D(H){5(!H||H.2d){2c(B.1w)}}5(C){G();5(!F){2.$3.16(2.c.t,D)}m{2.$3.16(2.c.t,4(){D();E=B.c.7;G()})}}m{D();2.$3.15(2.c.t,D)}}})})(1M)',62,203,'||this|tabs|function|if|var|selected|ui|||panels|options|return|disabled|data||element|lis|length|selectedClass|addClass|else|href|false|load|removeClass|eq||event|fakeEvent|hash|null|hideClass|cache|triggerHandler|||||||||||||||||||||filter|index|disabledClass|each|browser|fx||cookie|hasClass|attr|replace|unbind|bind|select|loadingClass|panelClass|remove|destroy|add|true|css|tabify|id|msie|unselect|li|label|ajaxOptions|spinner|removeData|xhr|html|undefined|display|inArray|map|blur|tabsshow|rotation|unselectClass|navClass|panelTemplate|click|setTimeout|success|em|find|block|tabId|stop|show|opacity|duration|location|jQuery|extend|panel|div|span|tabTemplate|idPrefix|url|tabsload|disable|tabsdisable|sort|push|enable|tabsenable|grep|tabsremove|tabsadd|insertBefore|appendTo|test|tabsselect|style|animate|_|title|clearInterval|clientX|setInterval|rotate|prototype|getter|loading|hide|nav|8230|Loading|defaults|target|type|fix|join|ajax|abort|wrapInner|parent|img|not|is|last|trigger|string|typeof|inline|safari|parentNode|child|first|indexOf|identifier|fragment|Mismatching|Tabs|UI|throw|visible|parents|siblings|height|overflow|Array|constructor|normal|width|min|for|unload|window|splice|concat|unique|parseInt|scrollTo|500|opera|insertAfter|has|tab|z0|Za|setData|init|widget'.split('|'),0,{}))
+
Index: /tags/2.0.2/template-common/pngfix.js
===================================================================
--- /tags/2.0.2/template-common/pngfix.js	(revision 3278)
+++ /tags/2.0.2/template-common/pngfix.js	(revision 3278)
@@ -0,0 +1,37 @@
+
+// Correctly handle PNG transparency in Win IE 5.5 or higher.
+// http://homepage.ntlworld.com/bobosola. Updated 02-March-2004
+// 15-Jully-2006 : chrisaga use \" instead of ' in imgTitle
+//		 : to fix ' display in tooltips
+//		 : keep the alt attribute
+
+function correctPNG() 
+   {
+   for(var i=0; i<document.images.length; i++)
+      {
+      var img = document.images[i]
+      if (img.className == "button" || img.className == "icon")
+          {
+	  var imgName = img.src.toUpperCase()
+	  if (imgName.substring(imgName.length-3, imgName.length) == "PNG")
+	     {
+		 var imgID = (img.id) ? "id='" + img.id + "' " : ""
+		 var imgClass = (img.className) ? "class='" + img.className + "' " : ""
+		 //var imgTitle = (img.title) ? "title=\"" + img.title + "\" " : "alt=\"" + img.alt + "\" "
+		 var imgTitle = (img.title) ? "title=\"" + img.title + "\" " : "";
+		 imgTitle = imgTitle + (img.alt) ? "title=\"" + img.alt + "\" " : "";
+		 var imgStyle = "display:inline-block;" + img.style.cssText 
+		 if (img.align == "left") imgStyle = "float:left;" + imgStyle
+		 if (img.align == "right") imgStyle = "float:right;" + imgStyle
+		 if (img.parentElement.href) imgStyle = "cursor:hand;" + imgStyle		
+		 var strNewHTML = "<span " + imgID + imgClass + imgTitle
+		 + " style=\"" + "width:" + img.width + "px; height:" + img.height + "px;" + imgStyle + ";"
+	     + "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader"
+		 + "(src=\'" + img.src + "\', sizingMethod='scale');\"></span>" 
+		 img.outerHTML = strNewHTML
+		 i = i-1
+	     }
+          }
+      }
+   }
+window.attachEvent("onload", correctPNG);
Index: /tags/2.0.2/template-common/scripts.js
===================================================================
--- /tags/2.0.2/template-common/scripts.js	(revision 3278)
+++ /tags/2.0.2/template-common/scripts.js	(revision 3278)
@@ -0,0 +1,194 @@
+function SelectAll( formulaire )
+{
+var len = formulaire.elements.length;
+var i=0;
+for( i = 0; i < len; i++)
+{
+	if ( formulaire.elements[i].type=='checkbox'
+		&& formulaire.elements[i].name != 'copie')
+	{
+		formulaire.elements[i].checked = true;
+	}
+}
+}
+
+function DeselectAll( formulaire )
+{
+var len = formulaire.elements.length;
+var i=0;
+for( i = 0; i < len; i++)
+{
+	if ( formulaire.elements[i].type=='checkbox'
+		&& formulaire.elements[i].name != 'copie')
+	{
+	formulaire.elements[i].checked = false;
+	}
+}
+}
+
+function Inverser( formulaire )
+{
+var len = formulaire.elements.length;
+var i=0;
+for( i=0; i<len; i++)
+{
+	if ( formulaire.elements[i].type=='checkbox'
+		&& formulaire.elements[i].name != 'copie')
+	{
+	formulaire.elements[i].checked = !formulaire.elements[i].checked;
+	}
+}
+}
+
+function phpWGOpenWindow(theURL,winName,features)
+{
+	img = new Image();
+	img.src = theURL;
+	if (img.complete)
+	{
+		var width=img.width +40;
+		var height=img.height +40;
+	}
+	else
+	{
+		var width=640;
+		var height=480;
+		img.onload = resizeWindowToFit;
+	}
+	newWin = window.open(theURL,winName,features+',left=2,top=1,width=' + width + ',height=' + height);
+}
+
+function resizeWindowToFit()
+{
+	newWin.resizeTo( img.width+50, img.height+100);
+}
+
+function popuphelp(url)
+{
+	window.open( url, 'dc_popup',
+		'alwaysRaised=yes,dependent=yes,toolbar=no,height=420,width=500,menubar=no,resizable=yes,scrollbars=yes,status=no'
+	);
+}
+
+
+
+Function.prototype.pwgBind = function() {
+	var __method = this, object = arguments[0], args = new Array();
+	for (var i=1; i<arguments.length; i++)
+		args[i-1] = arguments[i];
+	return function() { return __method.apply(object, args); }
+}
+
+function PwgWS(urlRoot)
+{
+	this.urlRoot = urlRoot;
+	this.options = {
+		method: "GET",
+		async:  true,
+		onFailure: null,
+		onSuccess: null
+	};
+};
+
+function blockToggleDisplay(headerId, contentId)
+{
+  var revHeader = document.getElementById(headerId);
+  var revContent = document.getElementById(contentId);
+
+  if (revContent.style.display == 'none')
+  {
+    revContent.style.display = 'block';
+    revHeader.className = 'instructionBlockHeaderExpanded';
+  }
+  else
+  {
+    revContent.style.display = 'none';
+    revHeader.className = 'instructionBlockHeaderCollapsed';
+  }
+}
+
+
+PwgWS.prototype = {
+
+	callService : function(method, parameters, options)
+	{
+		if (options)
+		{
+			for (var property in options)
+				this.options[property] = options[property];
+		}
+		try { this.transport = new XMLHttpRequest();}
+		catch(e) {
+			try { this.transport = new ActiveXObject('Msxml2.XMLHTTP'); }
+			catch(e) {
+				try { this.transport = new ActiveXObject('Microsoft.XMLHTTP'); }
+				catch (e){
+					dispatchError(0, "Cannot create request object");
+				}
+			}
+		}
+		this.transport.onreadystatechange = this.onStateChange.pwgBind(this);
+
+		var url = this.urlRoot;
+		url += "ws.php?format=json&method="+method;
+		if (parameters)
+		{
+			for (var property in parameters)
+			{
+				if ( typeof parameters[property] == 'object' && parameters[property])
+				{
+					for (var i=0; i<parameters[property].length; i++)
+						url += "&"+property+"[]="+encodeURIComponent(parameters[property][i]);
+				}
+				else
+					url += "&"+property+"="+encodeURIComponent(parameters[property]);
+			}
+		}
+		this.transport.open(this.options.method, url, this.options.async);
+		this.transport.send(null);
+	},
+
+	onStateChange: function() {
+		var readyState = this.transport.readyState;
+		if (readyState == 4)
+			this.respondToReadyState(this.transport.readyState);
+	},
+
+	dispatchError: function( httpCode, text )
+	{
+		!this.options.onFailure || this.options.onFailure( httpCode, text);
+	},
+
+	respondToReadyState: function(readyState)
+	{
+		var transport = this.transport;
+		if (readyState==4 && transport.status == 200)
+		{
+			var resp;
+			try {
+				eval('resp = ' + transport.responseText);
+			}
+			catch (e) {
+				this.dispatchError( 200, e.message + '\n' + transport.responseText.substr(0,512) );
+			}
+			if (resp!=null)
+			{
+				if (resp.stat==null)
+					this.dispatchError( 200, "Invalid response" );
+				else if (resp.stat=='ok')
+				{
+					if (this.options.onSuccess) this.options.onSuccess( resp.result );
+				}
+				else
+					this.dispatchError( 200, resp.err + " " + resp.message);
+			}
+		}
+		if (readyState==4 && transport.status != 200)
+			this.dispatchError( transport.status, transport.statusText );
+	},
+
+
+	transport: null,
+	urlRoot: null,
+	options: {}
+}
Index: /tags/2.0.2/template-common/tooltipfix.htc
===================================================================
--- /tags/2.0.2/template-common/tooltipfix.htc	(revision 3278)
+++ /tags/2.0.2/template-common/tooltipfix.htc	(revision 3278)
@@ -0,0 +1,31 @@
+<public:attach event="onmouseover" onevent="montrer()" />
+<public:attach event="onmouseout"  onevent="cacher()" />
+
+<script langage=javascript>
+var thisImg = this;
+var thisTitle = this.title;
+var thisAlt = this.alt;
+var thisA = this.parentNode;
+var aTitle = thisA.title;
+
+function montrer()
+{
+  if (aTitle)
+  {
+    thisAlt=thisImg.alt;
+    thisImg.alt=aTitle;
+    thisImg.title=aTitle;
+  }
+  return;
+}
+
+function cacher() {
+  if (thisAlt)
+  {
+    thisImg.alt=thisAlt;
+    thisImg.title=thisTitle;
+  }
+  return;
+}
+</script>
+
Index: /tags/2.0.2/template-extension/distributed/samples/my-picture.tpl
===================================================================
--- /tags/2.0.2/template-extension/distributed/samples/my-picture.tpl	(revision 3278)
+++ /tags/2.0.2/template-extension/distributed/samples/my-picture.tpl	(revision 3278)
@@ -0,0 +1,107 @@
+{* $Id$ *}
+
+{if isset($errors)}
+<div class="errors">
+  <ul>
+    {foreach from=$errors item=error}
+    <li>{$error}</li>
+    {/foreach}
+  </ul>
+</div>
+{/if}
+
+{if isset($infos)}
+<div class="infos">
+  <ul>
+    {foreach from=$infos item=info}
+    <li>{$info}</li>
+    {/foreach}
+  </ul>
+</div>
+{/if}
+
+<div id="imageHeaderBar">
+  <div class="browsePath">
+    <a href="{$U_HOME}" rel="home">{'home'|@translate}</a>
+    {if !$IS_HOME}{$LEVEL_SEPARATOR}{$SECTION_TITLE}{/if}
+    {$LEVEL_SEPARATOR}{$current.TITLE}
+  </div>
+  <div class="imageNumber">{$PHOTO}</div>
+  {if $SHOW_PICTURE_NAME_ON_TITLE }
+  <h2>{$current.TITLE}</h2>
+  {/if}
+</div>
+
+{if !empty($PLUGIN_PICTURE_BEFORE)}{$PLUGIN_PICTURE_BEFORE}{/if}
+<div id="imageToolBar">
+  <div class="randomButtons">
+    {if isset($U_SLIDESHOW_START) }
+      <a href="{$U_SLIDESHOW_START}" title="{'slideshow'|@translate}" rel="nofollow"><img src="{$ROOT_URL}{$themeconf.icon_dir}/start_slideshow.png" class="button" alt="{'slideshow'|@translate}"></a>
+    {/if}
+    {if isset($U_SLIDESHOW_STOP) }
+      <a href="{$U_SLIDESHOW_STOP}" title="{'slideshow_stop'|@translate}" rel="nofollow"><img src="{$ROOT_URL}{$themeconf.icon_dir}/stop_slideshow.png" class="button" alt="{'slideshow_stop'|@translate}"></a>
+    {/if}
+      <a href="{$U_METADATA}" title="{'picture_show_metadata'|@translate}" rel="nofollow"><img src="{$ROOT_URL}{$themeconf.icon_dir}/metadata.png" class="button" alt="metadata" /></a>
+    {if isset($current.U_DOWNLOAD) }
+      <a href="{$current.U_DOWNLOAD}" title="{'download_hint'|@translate}"><img src="{$ROOT_URL}{$themeconf.icon_dir}/save.png" class="button" alt="{'download'|@translate}"></a>
+    {/if}
+    {if isset($PLUGIN_PICTURE_ACTIONS)}{$PLUGIN_PICTURE_ACTIONS}{/if}
+    {if isset($favorite) }
+      <a href="{$favorite.U_FAVORITE}" title="{$favorite.FAVORITE_HINT}"><img src="{$favorite.FAVORITE_IMG}" class="button" alt="favorite" title="{$favorite.FAVORITE_HINT}"></a>
+    {/if}
+    {if !empty($U_SET_AS_REPRESENTATIVE) }
+      <a href="{$U_SET_AS_REPRESENTATIVE}" title="{'set as category representative'|@translate}"><img src="{$ROOT_URL}{$themeconf.icon_dir}/representative.png" class="button" alt="{'representative'|@translate}"></a>
+    {/if}
+    {if isset($U_ADMIN) }
+      <a href="{$U_ADMIN}" title="{'link_info_image'|@translate}"><img src="{$ROOT_URL}{$themeconf.icon_dir}/preferences.png" class="button" alt="{'edit'|@translate}"></a>
+    {/if}
+    {if isset($U_CADDIE) }{*caddie management BEGIN*}
+<script type="text/javascript">
+{literal}function addToCadie(aElement, rootUrl, id)
+{
+if (aElement.disabled) return;
+aElement.disabled=true; 
+var y = new PwgWS(rootUrl);
+
+y.callService(
+  "pwg.caddie.add", {image_id: id} ,
+  {
+    onFailure: function(num, text) { alert(num + " " + text); document.location=aElement.href; },
+    onSuccess: function(result) { aElement.disabled = false; }
+  }
+  );
+}{/literal}
+</script>
+      <a href="{$U_CADDIE}" onclick="addToCadie(this, '{$ROOT_URL|@escape:'javascript'}', {$current.id}); return false;" title="{'add to caddie'|@translate}"><img src="{$ROOT_URL}{$themeconf.icon_dir}/caddie_add.png" class="button" alt="{'caddie'|@translate}"></a>
+    {/if}{*caddie management END*}
+  </div>
+  {include file='picture_nav_buttons.tpl'|@get_extent:'picture_nav_buttons'}
+</div> <!-- imageToolBar -->
+
+<div id="theImage">
+{$ELEMENT_CONTENT}
+
+{if isset($COMMENT_IMG)}
+<p>{$COMMENT_IMG}</p>
+{/if}
+
+{if isset($U_SLIDESHOW_STOP) }
+<p>
+  [ <a href="{$U_SLIDESHOW_STOP}">{'slideshow_stop'|@translate}</a> ]
+</p>
+{/if}
+
+</div>
+
+{if isset($previous) }
+<a class="navThumb" id="linkPrev" href="{$previous.U_IMG}" title="{'previous_page'|@translate} : {$previous.TITLE}" rel="prev">
+  <img src="{$previous.THUMB_SRC}" alt="{$previous.TITLE}">
+</a>
+{/if}
+{if isset($next) }
+<a class="navThumb" id="linkNext" href="{$next.U_IMG}" title="{'next_page'|@translate} : {$next.TITLE}" rel="next">
+  <img src="{$next.THUMB_SRC}" alt="{$next.TITLE}">
+</a>
+{/if}
+
+{if !empty($PLUGIN_PICTURE_AFTER)}{$PLUGIN_PICTURE_AFTER}{/if}
Index: /tags/2.0.2/template-extension/distributed/samples/my-thumbnails.tpl
===================================================================
--- /tags/2.0.2/template-extension/distributed/samples/my-thumbnails.tpl	(revision 3278)
+++ /tags/2.0.2/template-extension/distributed/samples/my-thumbnails.tpl	(revision 3278)
@@ -0,0 +1,36 @@
+{* $Id$ *}
+<!-- This is a sample of template extensions -->
+{if !empty($thumbnails)}
+<ul class="thumbnails">
+{foreach from=$thumbnails item=thumbnail}
+	<li>
+	<span class="wrap1">
+		<span class="wrap2">
+		<a href="{$thumbnail.URL}">
+			<img class="thumbnail" src="{$thumbnail.TN_SRC}" alt="{$thumbnail.TN_ALT}" title="{$thumbnail.TN_TITLE}" />
+		</a>
+		</span>
+		<span class="thumbLegend" style="color:#F36;">
+    &copy; 2008 Piwigo<br />
+		{if !empty($thumbnail.NAME)}{$thumbnail.NAME}{/if}
+		{if !empty($thumbnail.ICON_TS)}{$thumbnail.ICON_TS}{/if}
+
+		{if isset($thumbnail.NB_COMMENTS)}
+		<span class="{if 0==$thumbnail.NB_COMMENTS}zero {/if}nb-comments">
+		<br />
+		{$pwg->l10n_dec('%d comment', '%d comments',$thumbnail.NB_COMMENTS)}
+		</span>
+		{/if}
+
+		{if isset($thumbnail.NB_HITS)}
+		<span class="{if 0==$thumbnail.NB_HITS}zero {/if}nb-hits">
+		<br />
+		{$pwg->l10n_dec('%d hit', '%d hits',$thumbnail.NB_HITS)}
+		</span>
+		{/if}
+		</span>
+	</span>
+	</li>
+{/foreach}
+</ul>
+{/if}
Index: /tags/2.0.2/template-extension/distributed/samples/my-thumbnails2.css
===================================================================
--- /tags/2.0.2/template-extension/distributed/samples/my-thumbnails2.css	(revision 3278)
+++ /tags/2.0.2/template-extension/distributed/samples/my-thumbnails2.css	(revision 3278)
@@ -0,0 +1,14 @@
+/* $Id$ */
+.thumbLegend { padding: 0 6px; color: #666; font-style:italic; font-size: 7px; }
+.fld1 { width: 96px; min-width: 96px; padding: 0; 
+margin: 5px; display: inline;}
+.lap2 { display: block; padding: 4px 15px 10px 15px; border: 0;}
+.fld1:hover { background-color: #000; }
+.fld1 a:hover { border:0; }
+.thumbnail { margin: 2px auto; }
+/* Advanced hacks for IE 7 */
+*+html .thumbnail { display: inline; margin: 0 auto; }
+*+html .lap2 span { position: relative; top: 50%; margin: 0 auto; }
+*+html .lap2 { display: inline; position: relative; top: 0%; }
+*+html .fld1 { width: auto; padding: 6px 0 6px 0; margin-top: 0px;}
+*+html .thumbLegend { font-size: 10px; }
Index: /tags/2.0.2/template-extension/distributed/samples/my-thumbnails2.tpl
===================================================================
--- /tags/2.0.2/template-extension/distributed/samples/my-thumbnails2.tpl	(revision 3278)
+++ /tags/2.0.2/template-extension/distributed/samples/my-thumbnails2.tpl	(revision 3278)
@@ -0,0 +1,19 @@
+{* $Id$ *}
+<!-- This is a sample of template extensions -->
+{if !empty($thumbnails)}
+{html_head}<link rel="stylesheet" type="text/css" href="./template-extension/distributed/samples/my-thumbnails2.css">{/html_head}
+<ul class="thumbnails">
+{foreach from=$thumbnails item=thumbnail}
+	<li>
+	<fieldset class="fld1">
+		<legend class="thumbLegend">
+		{if !empty($thumbnail.NAME)}{$thumbnail.NAME}{/if}
+		</legend>
+		<a href="{$thumbnail.URL}" class="lap2">
+			<span><img class="thumbnail" src="{$thumbnail.TN_SRC}" alt="{$thumbnail.TN_ALT}" title="{$thumbnail.TN_TITLE}" /></span>
+		</a>
+  </fieldset>
+	</li>
+{/foreach}
+</ul>
+{/if}
Index: /tags/2.0.2/template-extension/distributed/samples/titling_categories.tpl
===================================================================
--- /tags/2.0.2/template-extension/distributed/samples/titling_categories.tpl	(revision 3278)
+++ /tags/2.0.2/template-extension/distributed/samples/titling_categories.tpl	(revision 3278)
@@ -0,0 +1,50 @@
+{* 
+
+   Copied from mainpage_categories.tpl 
+
+*}
+{if !empty($category_thumbnails)}
+  {html_head}
+<style media="screen,handheld,projection,tv" type="text/css">
+#content ul.thumbnailCategories li {ldelim} width:100%; z-index: 55; position: relative;}
+#Titling h3 {ldelim} margin:11px 0 -13px; padding:0 3px 0 20px; text-align:left; z-index: 99; position: relative;}
+#Titling h3 a {ldelim} background-color: #222; padding: 0 10px; }
+#content ul.thumbnailCategories .unbordered {ldelim} width:49%; float:left; margin:0 0 0 5px; }
+.content div.thumbnailCategory div.description p.dates {ldelim} margin: 0 45px 0 20px; }
+#content .thumbnailCategory div.description .text {ldelim} margin: 0; padding: 0 4px; text-align: justify; }
+p.Nb_images {ldelim} text-align: left; color: #444; }
+/* hacks */
+*+html #Titling h3, * html #Titling h3 {ldelim} font-weight: normal;} /* IE browsers */
+</style>
+  {/html_head}
+  <ul class="thumbnailCategories" id="Titling"> {*                   1st difference: Titling/thumbnail *}
+    {foreach from=$category_thumbnails item=cat}
+    <div class="unbordered"> {*                                                   W3C HTML non conform *}
+    <h3> {*                                               2nd difference: h3 is outside of description *}
+      <a href="{$cat.URL}">{$cat.NAME}</a>{$cat.ICON_TS}
+    </h3>
+    <li>
+      <div class="thumbnailCategory">
+       <div class="illustration">
+          <a href="{$cat.URL}">
+            <img src="{$cat.TN_SRC}" alt="{$cat.ALT}" 
+            title="{'hint_category'|@translate}">
+          </a>
+        </div>
+        <div class="description">
+  				{if isset($cat.INFO_DATES) }
+    				<p class="dates">{$cat.INFO_DATES}</p>
+  				{/if}
+          <div class="text">
+          <p class="Nb_images">{$cat.CAPTION_NB_IMAGES}</p>
+    				{if not empty($cat.DESCRIPTION)}
+    				<p>{$cat.DESCRIPTION}</p>
+    				{/if}
+          </div>
+        </div>
+      </div>
+    </li>
+    </div>    
+    {/foreach}
+  </ul>
+{/if}
Index: /tags/2.0.2/template-extension/index.php
===================================================================
--- /tags/2.0.2/template-extension/index.php	(revision 3278)
+++ /tags/2.0.2/template-extension/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/template-extension/yoga/index.php
===================================================================
--- /tags/2.0.2/template-extension/yoga/index.php	(revision 3278)
+++ /tags/2.0.2/template-extension/yoga/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/template-extension/yoga/local/README
===================================================================
--- /tags/2.0.2/template-extension/yoga/local/README	(revision 3278)
+++ /tags/2.0.2/template-extension/yoga/local/README	(revision 3278)
@@ -0,0 +1,19 @@
+If you want to make some template customization without building a brand new
+template, you should use this directory to store yur customized version of the
+official template files rather than editing them on place.
+Doing this, they won't be lost during the next upgrade.
+
+For example, if you want your own header file just copy 
+"template/yoga/header.tpl" to this directory with whatever, but significant,
+filename you want.
+Then edit "include/page_header.php" and replace the line :
+  $template->set_filenames(array('header'=>'header.tpl'));
+by
+  $template->set_filenames(array('header'=>'../../template-extension/yoga/local/header.tpl'));
+Or whatever new filename you gave instead of header.tpl
+
+In future version of PWG, you probably won't have to edit the php code, but
+a parameter table instead.
+
+Feel free to ask in the forum for further assistance :
+http://piwigo.org/forum
Index: /tags/2.0.2/template-extension/yoga/local/index.php
===================================================================
--- /tags/2.0.2/template-extension/yoga/local/index.php	(revision 3278)
+++ /tags/2.0.2/template-extension/yoga/local/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/template/index.php
===================================================================
--- /tags/2.0.2/template/index.php	(revision 3278)
+++ /tags/2.0.2/template/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/template/yoga/about.tpl
===================================================================
--- /tags/2.0.2/template/yoga/about.tpl	(revision 3278)
+++ /tags/2.0.2/template/yoga/about.tpl	(revision 3278)
@@ -0,0 +1,19 @@
+{* $Id$ *}
+<div id="content" class="content">
+  <div class="titrePage">
+    <ul class="categoryActions">
+      <li>
+        <a href="{$U_HOME}" title="{'return to homepage'|@translate}">
+          <img src="{$themeconf.icon_dir}/home.png" class="button" alt="{'home'|@translate}"/>
+        </a>
+      </li>
+    </ul>
+    <h2>{'About'|@translate}</h2>
+  </div>
+  <ul>
+  {$ABOUT_MESSAGE}
+  {if isset($THEME_ABOUT) }
+  <li>{$THEME_ABOUT}</li>
+  {/if}
+  </ul>
+</div>
Index: /tags/2.0.2/template/yoga/calendar_navbar.tpl
===================================================================
--- /tags/2.0.2/template/yoga/calendar_navbar.tpl	(revision 3278)
+++ /tags/2.0.2/template/yoga/calendar_navbar.tpl	(revision 3278)
@@ -0,0 +1,13 @@
+
+{foreach from=$datas item=data}
+  <span class="{$data.classname}">
+  {if isset($data.url) and $data.url!=""}
+  <a href="{$data.url}">{$data.label}</a>
+  {else}
+  {$data.label}
+  {/if}
+  {if isset($data.nb_images) and $data.nb_images!=""}
+  ({$data.nb_images})
+  {/if}
+  </span>
+{/foreach}
Index: /tags/2.0.2/template/yoga/comment_list.tpl
===================================================================
--- /tags/2.0.2/template/yoga/comment_list.tpl	(revision 3278)
+++ /tags/2.0.2/template/yoga/comment_list.tpl	(revision 3278)
@@ -0,0 +1,41 @@
+{* $Id$ *}
+<ul class="thumbnailCategories">
+{foreach from=$comments item=comment name=comment_loop}
+<li>
+	<div class="thumbnailCategory {if $smarty.foreach.comment_loop.index is odd}odd{else}even{/if}">
+    {if isset($comment.TN_SRC)}
+    <div class="illustration">
+      <a href="{$comment.U_PICTURE}">
+        <img src="{$comment.TN_SRC}" alt="{$comment.ALT}" />
+      </a>
+    </div>
+    {/if}
+    <div class="description">
+      {if isset($comment.U_DELETE) or isset($comment.U_VALIDATE) }
+      <ul class="actions" style="float:right">
+        {if isset($comment.U_DELETE)}
+        <li>
+          <a href="{$comment.U_DELETE}" title="{'delete this comment'|@translate}">
+            <img src="{$ROOT_URL}{$themeconf.icon_dir}/delete.png" class="button" alt="[delete]" />
+          </a>
+        </li>
+        {/if}
+        {if isset($comment.U_VALIDATE)}
+        <li>
+          <a href="{$comment.U_VALIDATE}" title="validate this comment">
+            <img src="{$ROOT_URL}{$themeconf.icon_dir}/validate_s.png" class="button" alt="[validate]" />
+          </a>
+        </li>
+        {/if}
+      </ul>
+      {/if}
+      <span class="author">{$comment.AUTHOR}</span> - <span class="date">{$comment.DATE}</span>
+      <blockquote>{$comment.CONTENT}</blockquote>
+    </div>
+  </div>
+</li>
+{if isset($comment_separator)}
+<hr/>
+{/if}
+{/foreach}
+</ul>
Index: /tags/2.0.2/template/yoga/comments.tpl
===================================================================
--- /tags/2.0.2/template/yoga/comments.tpl	(revision 3278)
+++ /tags/2.0.2/template/yoga/comments.tpl	(revision 3278)
@@ -0,0 +1,77 @@
+{* $Id$ *}
+<div id="content" class="content">
+
+  <div class="titrePage">
+    <ul class="categoryActions">
+      <li><a href="{$U_HOME}" title="{'return to homepage'|@translate}"><img src="{$themeconf.icon_dir}/home.png" class="button" alt="{'home'|@translate}"/></a></li>
+    </ul>
+    <h2>{'User comments'|@translate}</h2>
+  </div>
+
+<form class="filter" action="{$F_ACTION}" method="get">
+
+  <fieldset>
+    <legend>{'Filter'|@translate}</legend>
+
+    <label>{'Keyword'|@translate}<input type="text" name="keyword" value="{$F_KEYWORD}" /></label>
+
+    <label>{'Author'|@translate}<input type="text" name="author" value="{$F_AUTHOR}" /></label>
+
+    <label>
+      {'Category'|@translate}
+      <select name="cat">
+        <option value="0">------------</option>
+        {html_options options=$categories selected=$categories_selected}
+      </select>
+    </label>
+
+    <label>
+      {'Since'|@translate}
+      <select name="since">
+        {html_options options=$since_options selected=$since_options_selected}
+      </select>
+    </label>
+
+  </fieldset>
+
+  <fieldset>
+
+    <legend>{'Display'|@translate}</legend>
+
+    <label>
+      {'Sort by'|@translate}
+      <select name="sort_by">
+        {html_options options=$sort_by_options selected=$sort_by_options_selected}
+      </select>
+    </label>
+
+    <label>
+      {'Sort order'|@translate}
+      <select name="sort_order">
+        {html_options options=$sort_order_options selected=$sort_order_options_selected}
+      </select>
+    </label>
+
+    <label>
+      {'Number of items'|@translate}
+      <select name="items_number">
+        {html_options options=$item_number_options selected=$item_number_options_selected}
+      </select>
+    </label>
+
+  </fieldset>
+
+  <p><input class="submit" type="submit" value="{'Filter and display'|@translate}"></p>
+
+</form>
+
+<div class="navigationBar">{$NAVBAR}</div>
+
+{if isset($comments)}
+<div id="comments">
+	{include file='comment_list.tpl'}
+</div>
+{/if}
+
+</div> <!-- content -->
+
Index: /tags/2.0.2/template/yoga/content.css
===================================================================
--- /tags/2.0.2/template/yoga/content.css	(revision 3278)
+++ /tags/2.0.2/template/yoga/content.css	(revision 3278)
@@ -0,0 +1,198 @@
+/* $Id$ */
+.content {
+	margin-right: 1em;
+	margin-bottom: 1em; /* when it's longer than menu bar */
+}
+
+BODY#theCommentsPage .content,
+BODY#theUploadPage .content,
+BODY#theRegisterPage .content,
+BODY#theIdentificationPage .content,
+BODY#theProfilePage .content,
+BODY#theSearchPage .content,
+BODY#theAboutPage .content,
+BODY#thePopuphelpPage .content,
+BODY#thePasswordPage .content,
+BODY#theNotificationPage .content,
+BODY#theTagsPage .content,
+BODY#theNBMPage .content
+{
+	margin: 1em;
+}
+
+.content H2 { margin-bottom: 3px;} /*<- for IE otherwise calendar select is displaced to middle of page*/
+
+.content .navigationBar, .content .additional_info, .content .calendarBar {
+	margin: 8px 4px;
+	text-align: center;
+}
+
+.content .pageNumberSelected {
+	font-style: italic;
+	font-weight: bold;
+}
+
+.content .additional_info {
+	font-size: 110%;
+}
+
+
+/* actions */
+UL.categoryActions {
+	margin: 0 2px;
+	width: auto;
+	padding: 0;
+	text-indent: 0;
+	list-style: none;
+	text-align: center;
+}
+
+.content DIV.titrePage UL.categoryActions {
+	float: right;
+	text-align: center;
+}
+
+.content DIV.titrePage {
+	padding: 0 0 3px;
+}
+
+.content UL.categoryActions LI {
+	display: inline;
+}
+
+.content UL.categoryActions A IMG, UL.categoryActions A {
+	border: none;
+	margin-bottom: -5px;
+}
+
+/* begin chronology/calendar elements*/
+.content DIV.calendarViews {
+	display: block;
+	float: right;
+	margin: 2px 0 0;
+}
+
+SPAN.calItem, SPAN.calItemEmpty {
+	font-weight: bold;
+	margin: 0 1px;
+}
+
+SPAN.calItem A { border:0 }
+
+.content DIV.calendarCalBar {
+	margin: 10px 10px;
+	text-align: left;
+}
+
+SPAN.calCalHead {
+	font-weight: bold;
+	font-size: 110%;
+	margin: 0 2px;
+}
+
+SPAN.calCal { margin: 0 2px; }
+
+/* nice looking month calendar*/
+TABLE.calMonth {
+	border: none;
+	border-collapse: collapse;
+	margin-bottom: 10px;	/*<-IE ignores this */
+}
+
+TD.calDayCellFull, TD.calDayCellEmpty, TD.calDayCellBlank {
+	vertical-align: top;
+  font-weight: bold;
+  font-size: 18px;
+}
+
+TD.calDayHead {
+  font-weight: bold;
+  font-size: 12px;
+	text-align: center;
+}
+
+DIV.calImg {
+	overflow: hidden;
+	vertical-align: bottom;
+	z-index: 1;
+	position: relative; /*<- this required by IE*/
+}
+
+.calImg img {
+	position: relative;
+	border: 0;
+}
+
+.calBackDate {
+	padding-left: 4px;
+	padding-top: 0px;
+	z-index: 2;
+	position: absolute;
+	vertical-align: top;
+	color: #000;
+}
+
+.calForeDate {
+	padding-left: 5px;
+	padding-top: 1px;
+	z-index: 3;
+	position: absolute;
+	vertical-align: top;
+	color: #fff;
+}
+
+/* Category thumbnails on main page, CSS code inspired from MOD subcatify */
+.content UL.thumbnailCategories {
+	margin: 0;
+	padding: 0;
+	list-style: none;
+	overflow: hidden;
+	width: 100%;
+}
+
+.content UL.thumbnailCategories LI {
+	margin:0;
+	padding:0;
+	float:left;
+}
+
+.content DIV.thumbnailCategory {
+	display:block;
+	padding: 2px 0px 0px 2px;
+	margin: 5px;
+}
+
+.content DIV.thumbnailCategory DIV.description {
+	font-size: 90%;
+	overflow: auto;
+	/*width: inherit;*/
+}
+
+.content DIV.thumbnailCategory DIV.description H3 {
+	text-align: left;
+	background: transparent;
+	margin: 0;
+	padding: 0.1em;
+	font-size: 120%;
+}
+
+.content DIV.thumbnailCategory DIV.description P {
+	margin: 0;
+}
+
+.content DIV.thumbnailCategory DIV.illustration {
+	text-align: left;
+	margin: 2px 0 0 2px;
+	float: left;
+}
+
+
+/* User comments */
+DIV#comments {
+	padding-left: 5px;
+	padding-right: 5px;
+}
+
+DIV#comments DIV.description {
+	font-size: 100%;
+}
Index: /tags/2.0.2/template/yoga/default-colors.css
===================================================================
--- /tags/2.0.2/template/yoga/default-colors.css	(revision 3278)
+++ /tags/2.0.2/template/yoga/default-colors.css	(revision 3278)
@@ -0,0 +1,110 @@
+/* $Id$ */
+
+/* others */
+
+#imageToolBar * {
+	background: inherit;
+}
+
+/* So that non-links are slightly greyed out */
+.content .navigationBar, SPAN.calItemEmpty, TD.calDayCellEmpty {
+	color: #b0b0b0;
+}
+
+/* Tables & forms */
+
+/* IE <= 6 is so bad with this that you can't merge with the following rule */
+INPUT[type="text"], INPUT[type="password"], INPUT[type="button"],
+INPUT[type="submit"], INPUT[type="reset"], INPUT[type="file"] {
+	color:black;
+	background-color: #d3d3d3;	/* lightgrey */
+}
+
+INPUT.text, INPUT.password, INPUT.button,
+INPUT.submit, INPUT.reset, INPUT.file,
+SELECT, TEXTAREA {
+	color:black;
+	background-color: #d3d3d3;	/* lightgrey */
+}
+
+INPUT:focus, SELECT:focus, TEXTAREA:focus, INPUT.focus, FORM .focus {
+	background-color: #f5f5f5;	/* whitesmoke */
+}
+
+/* some theme set a border on INPUT  which is not pretty for radio/checkbox */
+INPUT[type="radio"], INPUT[type="checkbox"] {
+	border: none;	/* <= Opera needs this */
+}
+
+INPUT.radio, INPUT.checkbox {
+	border: none;	/* <= IE6 needs this */
+}
+
+/* rate buttons displayed like links */
+INPUT.rateButton, INPUT.rateButtonSelected, INPUT.rateButtonStarFull, INPUT.rateButtonStarEmpty {
+	color:inherit;
+	background-color:transparent !important;	/* Konqueror doesn't accept transparent here */
+}
+
+.errors { /* Errors display */
+	color: red;
+	background-color: #ffe1e1;
+	font-weight: bold;
+	margin: 5px;
+	border: 1px solid red;
+	background-image: url(icon/admin/errors.png);
+	background-repeat: no-repeat;
+	background-position: top right;
+	padding: 10px 50px 10px 10px;
+}
+
+/**
+ * Informations box in administration
+ */
+.infos {
+	color: #002000;
+	background-color: #98fb98; /* palegreen */
+	background-image: url(icon/admin/infos.png);
+	background-repeat: no-repeat;
+	background-position: top right;
+	margin: 5px;
+	padding: 10px 50px 10px 10px;
+}
+
+/**
+ * Header message like upgrade or adviser mode
+ */
+.header_msgs {
+	text-align:center;
+	font-weight: bold;
+	color:#696969;	/* dimgray */
+	background-color: #d3d3d3;
+	margin: 1px;
+	padding: 1px;
+}
+
+/**
+ * Header notes box in public/administration
+ */
+.header_notes {
+	border: 1px solid #aaaaaa; /* border color and style */
+	text-align: center;
+	background-image: url(icon/note.png);
+	background-repeat: no-repeat;
+	background-position: top left;
+	font-weight: bold;
+	margin: 14px;
+	padding: 5px 00px 0px 0px;
+}
+
+LEGEND {
+	font-style: italic;
+}
+
+/*calendar*/
+SPAN.calItem, SPAN.calItemEmpty, 
+TD.calDayCellEmpty, TD.calDayCellFull {
+	border: 1px solid gray;
+}
+
+
Index: /tags/2.0.2/template/yoga/default-layout.css
===================================================================
--- /tags/2.0.2/template/yoga/default-layout.css	(revision 3278)
+++ /tags/2.0.2/template/yoga/default-layout.css	(revision 3278)
@@ -0,0 +1,275 @@
+/* $Id$ */
+BODY {
+	margin: 5px;
+	padding: 0;
+	font-size: 0.8em;
+	font-family: Arial,Helvetica,sans-serif;
+}
+
+
+H1 {
+	text-align: center;
+	font-size: 150%;
+	font-weight: bold;
+	padding: 0;
+	margin: 0.5em 0 1em 0;
+}
+
+H2 {
+	margin: 0;
+	padding: 5px 0.5em 5px 0.5em;
+	text-align: left;
+	font-size: 120%;
+}
+
+A {
+	text-decoration:none;
+	border-bottom: 1px dotted #005e89;
+}
+A:hover {
+	border-bottom: 1px solid #858460;
+}
+
+IMG {
+	border: none;
+}
+
+HR.separation {
+	visibility: hidden;
+	clear: both;
+}
+
+#copyright {
+	clear: both;
+	font-size: 83%;
+	text-align: center;
+	margin: 0 0 10px 0;
+}
+
+INPUT, SELECT {
+	margin: 0;
+	font-size: 1em;	/* <= some browsers don't set it correctly */
+}
+
+TABLE {	/* horizontaly centered */
+	margin-left: auto;
+	margin-right: auto;
+}
+
+
+FORM { padding: 0; margin: 0; }
+
+FORM P {
+	text-align: center;
+	margin-top: 2em;
+	margin-bottom: 2em;
+}
+
+FORM FIELDSET P {
+	margin-top: 1em;
+	margin-bottom: 0;
+}
+
+SELECT.categoryList {
+	height: 20em;
+	width: 500px;
+}
+
+
+/**
+ * Filter forms are displayed label by label with the input (or select...)
+ * below the label. Use an UL to make a group (radiobox for instance).
+ * Use a SPAN to group objects in line
+ */
+FIELDSET {
+	padding: 1em;
+	margin: 1em;
+	overflow: hidden; /* <- makes Opera happy */
+}
+
+FORM.filter FIELDSET UL {
+  margin: 0;
+}
+FORM.filter FIELDSET UL,
+FORM.filter FIELDSET LABEL {
+	display: block;
+	float: left;
+	margin-right: 1em;
+	padding: 0;
+}
+
+FORM.filter FIELDSET LI {
+	list-style: none;
+	margin-bottom: 0.5em;
+}
+
+FORM.filter FIELDSET LI LABEL {
+	display: inline;
+	float: none;
+}
+
+FORM.filter FIELDSET UL.tagSelection LABEL {
+	display: inline;
+	float: none;
+	margin-right:0.5em;/*reduce from above*/
+}
+
+/* cannot use FIELDSET>LABEL because of IE<=6 */
+FORM.filter FIELDSET LABEL INPUT,
+FORM.filter FIELDSET LABEL SELECT,
+FORM.filter FIELDSET LABEL SPAN,
+FORM.filter FIELDSET LABEL TEXTAREA {
+  display: block;
+  margin: 0.5em 0;
+}
+FORM.filter FIELDSET * LABEL INPUT,
+FORM.filter FIELDSET * LABEL SELECT,
+FORM.filter FIELDSET * LABEL TEXTAREA,
+FORM.filter FIELDSET LABEL SPAN INPUT,
+FORM.filter FIELDSET LABEL SPAN SELECT,
+FORM.filter FIELDSET LABEL SPAN TEXTAREA {
+	display: inline;
+	vertical-align: top;
+	margin: 0 0.5em 0 0;
+}
+
+FORM.filter FIELDSET UL.tagSelection LI LABEL INPUT {
+	margin-right:0;
+}
+
+/* following declaration is important to avoid strange FF behaviour */
+FORM.filter FIELDSET LABEL SPAN SELECT {
+	margin: 0;
+}
+
+FORM.filter FIELDSET P
+{
+	clear: left;
+	display: block;
+}
+
+FORM.filter INPUT[type="submit"] {
+	margin-top: 1em;
+}
+
+FORM.properties UL {
+	list-style-type: none;
+	margin: 0;
+	padding: 0;
+}
+
+FORM.properties LI {
+	margin-bottom: 0.5em;
+	padding: 0;
+	line-height: 1.8em;
+	clear: left;
+}
+
+FORM.properties SPAN.property {
+	font-weight: bold;
+	float: left;
+	width: 50%;
+	text-align: right;
+	margin: 0;
+	padding: 0 0.5em 0 0;
+}
+
+/* button tools */
+UL.actions {
+	text-indent: 0;
+	list-style: none;
+}
+UL.actions LI {
+	display: inline;
+}
+UL.actions A, UL.actions IMG {
+	border: none;
+}
+
+UL.tagSelection {
+	width: 99%;
+	margin: 1em 0 1em 0;
+	padding: 0;
+}
+
+UL.tagSelection LI {
+	display: inline;
+	white-space: nowrap;
+}
+
+#fullTagCloud {
+	font-size: 120%;
+	text-align: justify;
+	padding: 0;
+	margin: 1em 2em 1em 2em;
+}
+
+#fullTagCloud SPAN {
+	white-space: nowrap;
+	margin: 0 2px;
+}
+
+
+.tagLevel5 { font-size: 150%; }
+.tagLevel4 { font-size: 140%; }
+.tagLevel3 { font-size: 120%; }
+.tagLevel2 { font-size: 100%; }
+.tagLevel1 { font-size: 90%; }
+
+
+/* Popup help page */
+BODY#thePopuphelpPage #copyright {
+	display: none;
+}
+
+#theNotificationPage p { padding: 0.5em; }
+BODY#thePopuphelpPage .content P {
+	text-align: justify;
+	padding: 0.5em;
+}
+
+BODY#thePopuphelpPage .content OL LI,
+BODY#thePopuphelpPage .content UL LI
+{
+	margin-bottom: 0.5em;
+}
+
+TR.tagLine {
+	border-bottom: 1px solid #ddd;
+}
+TD.nbEntries {
+	text-align: right;
+	font-style: italic;
+	font-size: 90%;
+}
+
+FIELDSET.tagLetter {
+	border: 1px solid #d3d3d3;
+	width: 200px;
+	margin: 0.5em;
+	padding: 10px;
+}
+
+LEGEND.tagLetterLegend {
+	border: 1px solid #d3d3d3;
+	font-size:120%;
+	font-weight: bold;
+	padding: 0 5px;
+	font-style: normal;
+}
+
+TABLE.tagLetterContent {
+	width:100%;
+	font-size:80%;
+	border-collapse : collapse;
+}
+
+#theHeader {text-align: center;}
+
+#theNotificationPage DL,
+#thePopuphelpPage DL { margin: 0 25px 25px; }
+.content #comments UL.thumbnailCategories LI { width:99%; }
+/* jQuery datepicker */
+IMG.ui-datepicker-trigger {
+	cursor : pointer;
+}
Index: /tags/2.0.2/template/yoga/fix-ie5-ie6.css
===================================================================
--- /tags/2.0.2/template/yoga/fix-ie5-ie6.css	(revision 3278)
+++ /tags/2.0.2/template/yoga/fix-ie5-ie6.css	(revision 3278)
@@ -0,0 +1,43 @@
+/* $Id$ */
+/* Issues in IE from 5 to 6 only not to be used with IE7 */
+
+/* fix IE with another layout for thumbnails */
+.content UL.thumbnails SPAN.wrap2 {
+  display: block;
+  position: relative;
+  text-align: left;
+}
+.content UL.thumbnails SPAN.wrap2 A,
+.content UL.thumbnails SPAN.wrap2 SPAN {
+  overflow: visible;
+  position: absolute;
+  top: 50%;
+  text-align: center;
+}
+
+.content UL.thumbnails IMG.thumbnail {
+  position: relative;
+  top: -50%;
+  /*\*//*/
+    margin-top: -40%;
+  /**/
+}
+
+/* to avoid vanishing objects in IE6 */
+H1, #theHeader {
+  width: 100%;	/* <- useless but seems to make IE6 happy */
+}
+.content {
+  height: 1em;	/* for IE6 it's like min-height */
+}
+
+/* fix category thumbnails on main page */
+.content UL.thumbnailCategories {
+  width: 99%;	/* buggy IE box model */
+}
+
+
+/* fix quickconnect layout */
+FORM#quickconnect FIELDSET {
+  width: 99%;	/* correct an ugly 1 or 2 px misalignement with IE */
+}
Index: /tags/2.0.2/template/yoga/fix-ie7.css
===================================================================
--- /tags/2.0.2/template/yoga/fix-ie7.css	(revision 3278)
+++ /tags/2.0.2/template/yoga/fix-ie7.css	(revision 3278)
@@ -0,0 +1,22 @@
+/* $Id$ */
+/* fix IE with another layout for thumbnails */
+
+.content UL.thumbnails SPAN.wrap2 {
+  display: block;
+  position: relative;
+  text-align: left;
+}
+.content UL.thumbnails SPAN.wrap2 A,
+.content UL.thumbnails SPAN.wrap2 SPAN {
+  overflow: visible;
+  position: absolute;
+  top: 50%;
+  text-align: center;
+}
+
+.content UL.thumbnails IMG.thumbnail {
+  position: relative;
+  top: -50%;   
+  margin-top: 2%;
+}
+
Index: /tags/2.0.2/template/yoga/fix-khtml.css
===================================================================
--- /tags/2.0.2/template/yoga/fix-khtml.css	(revision 3278)
+++ /tags/2.0.2/template/yoga/fix-khtml.css	(revision 3278)
@@ -0,0 +1,18 @@
+/* $Id$ */
+/* Issue in Safari/Konqueror only                                                 */
+/* If H2 has a 0 margin-top categoryActions doesn't float right but overwrites H2 */
+.content>DIV.titrePage>H2 {
+    margin: 1px 0 0 0;	/* add an arbitrary margin-top */
+}
+
+.content>div.titrePage {
+    position: relative;
+    top: -1px;		/* move the container up by the same amount */
+    margin-bottom: 5px; 
+}
+
+#menubar #menuTagCloud SPAN
+{
+  display: inline-block;/* required for Safari 3.1 - otherwise overflows on the right */
+}
+
Index: /tags/2.0.2/template/yoga/footer.tpl
===================================================================
--- /tags/2.0.2/template/yoga/footer.tpl	(revision 3278)
+++ /tags/2.0.2/template/yoga/footer.tpl	(revision 3278)
@@ -0,0 +1,36 @@
+{* $Id$ *}
+<div id="copyright">
+ <a name="EoP"></a> <!-- End of Page -->
+ {if isset($debug.TIME) }
+ {'generation_time'|@translate} {$debug.TIME} ({$debug.NB_QUERIES} {'sql_queries_in'|@translate} {$debug.SQL_TIME}) -
+ {/if}
+
+ {* Please, do not remove this copyright. If you really want to,
+      contact us on http://piwigo.org to find a solution on how
+      to show the origin of the script...
+  *}
+
+  {'powered_by'|@translate}
+  <a href="{$PHPWG_URL}" class="Piwigo">
+  <span class="Piwigo">Piwigo</span></a>
+  {$VERSION}
+  {if isset($CONTACT_MAIL)}
+  - {'send_mail'|@translate}
+  <a href="mailto:{$CONTACT_MAIL}?subject={'title_send_mail'|@translate|@escape:url}">{'Webmaster'|@translate}</a>
+  {/if}
+
+
+{if isset($footer_elements)}
+{foreach from=$footer_elements item=v}
+{$v}
+{/foreach}
+{/if}
+</div> <!-- the_page -->
+{if isset($debug.QUERIES_LIST)}
+<div id="debug">
+{$debug.QUERIES_LIST}
+</div>
+{/if}
+</div> <!-- copyright -->
+</body>
+</html>
Index: /tags/2.0.2/template/yoga/header.tpl
===================================================================
--- /tags/2.0.2/template/yoga/header.tpl	(revision 3278)
+++ /tags/2.0.2/template/yoga/header.tpl	(revision 3278)
@@ -0,0 +1,92 @@
+{* $Id$ *}
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="{$lang_info.code}" dir="{$lang_info.direction}">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset={$CONTENT_ENCODING}">
+<meta name="generator" content="Piwigo (aka PWG), see piwigo.org">
+{if isset($meta_ref) } 
+{if isset($INFO_AUTHOR)}
+<meta name="author" content="{$INFO_AUTHOR|@replace:'"':' '}">
+{/if}
+{if isset($related_tags)}
+<meta name="keywords" content="{foreach from=$related_tags item=tag name=tag_loop}{if !$smarty.foreach.tag_loop.first}, {/if}{$tag.name}{/foreach}">
+{/if}
+{if isset($COMMENT_IMG)}
+<meta name="description" content="{$COMMENT_IMG|@strip_tags:false|@replace:'"':' '}{if isset($INFO_FILE)} - {$INFO_FILE}{/if}">
+{else}
+<meta name="description" content="{$PAGE_TITLE}{if isset($INFO_FILE)} - {$INFO_FILE}{/if}">
+{/if}
+{/if}
+
+{if (isset($REVERSE) and $REVERSE and $PAGE_TITLE == l10n('home'))}
+<title>{$GALLERY_TITLE} | {$PAGE_TITLE}</title>{else}
+<title>{$PAGE_TITLE} | {$GALLERY_TITLE}</title>{/if}
+<link rel="shortcut icon" type="image/x-icon" href="{$ROOT_URL}template-common/favicon.ico">
+
+<link rel="start" title="{'home'|@translate}" href="{$U_HOME}" >
+<link rel="search" title="{'Search'|@translate}" href="{$ROOT_URL}search.php" >
+{if isset($first.U_IMG)   }<link rel="first" title="{'first_page'|@translate}" href="{$first.U_IMG}" >{/if}
+{if isset($previous.U_IMG)}<link rel="prev" title="{'previous_page'|@translate}" href="{$previous.U_IMG}" >{/if}
+{if isset($next.U_IMG)    }<link rel="next" title="{'next_page'|@translate}" href="{$next.U_IMG}" >{/if}
+{if isset($last.U_IMG)    }<link rel="last" title="{'last_page'|@translate}" href="{$last.U_IMG}" >{/if}
+{if isset($U_UP)          }<link rel="up" title="{'thumbnails'|@translate}" href="{$U_UP}" >{/if}
+
+<link rel="stylesheet" type="text/css" href="{$ROOT_URL}template/{$themeconf.template}/layout.css">
+{* the next css is used to fix khtml (Konqueror/Safari) issue the "text/nonsense" prevents gecko based browsers to load it *}
+<link rel="stylesheet" type="text/nonsense" href="{$ROOT_URL}template/{$themeconf.template}/fix-khtml.css">
+<!--[if lt IE 7]>
+	<link rel="stylesheet" type="text/css" href="{$ROOT_URL}template/{$themeconf.template}/fix-ie5-ie6.css">
+<![endif]-->
+<!--[if IE 7]>
+	<link rel="stylesheet" type="text/css" href="{$ROOT_URL}template/{$themeconf.template}/fix-ie7.css">
+<![endif]-->
+<!--[if !IE]> <-->
+	<link rel="stylesheet" href="{$ROOT_URL}template/{$themeconf.template}/not-ie.css" type="text/css">
+<!--> <![endif]-->
+<link rel="stylesheet" type="text/css" media="print" href="{$ROOT_URL}template/{$themeconf.template}/print.css">
+<link rel="stylesheet" type="text/css" href="{$ROOT_URL}template/{$themeconf.template}/theme/{$themeconf.theme}/theme.css">
+{$themeconf.local_head}
+{if isset($U_PREFETCH)          }<link rel="prefetch" href="{$U_PREFETCH}">{/if}
+
+{if not empty($page_refresh)    }<meta http-equiv="refresh" content="{$page_refresh.TIME};url={$page_refresh.U_REFRESH}">{/if}
+
+<script type="text/javascript" src="{$ROOT_URL}template-common/scripts.js"></script>
+<!--[if lt IE 7]>
+<style>
+	{* only because we need {$ROOT_URL} otherwise use fix-ie5-ie6.css *}
+	BODY {ldelim} behavior:url("{$ROOT_URL}template-common/csshover.htc"); }
+	A IMG, .button, .icon {ldelim}
+		behavior:url("{$ROOT_URL}template-common/tooltipfix.htc");
+	}
+	FORM {ldelim} behavior: url("{$ROOT_URL}template-common/inputfix.htc"); }
+</style>
+<script type="text/javascript" src="{$ROOT_URL}template-common/pngfix.js"></script>
+<![endif]-->
+
+{if not empty($head_elements)}
+	{foreach from=$head_elements item=elt}{$elt}
+	{/foreach}
+{/if}
+
+</head>
+
+<body id="{$BODY_ID}">
+<div id="the_page">
+
+{if not empty($header_msgs)}
+<div class="header_msgs">
+	{foreach from=$header_msgs item=elt}
+	{$elt}<br />
+	{/foreach}
+</div>
+{/if}
+
+<div id="theHeader">{$PAGE_BANNER}</div>
+{if isset($theSwiftHeader)}{$theSwiftHeader}{/if}
+{if not empty($header_notes)}
+<div class="header_notes">
+	{foreach from=$header_notes item=elt}
+	<p>{$elt}</p>
+  	{/foreach}
+</div>
+{/if}
Index: /tags/2.0.2/template/yoga/icon/admin/index.php
===================================================================
--- /tags/2.0.2/template/yoga/icon/admin/index.php	(revision 3278)
+++ /tags/2.0.2/template/yoga/icon/admin/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/template/yoga/icon/index.php
===================================================================
--- /tags/2.0.2/template/yoga/icon/index.php	(revision 3278)
+++ /tags/2.0.2/template/yoga/icon/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/template/yoga/icon/mimetypes/index.php
===================================================================
--- /tags/2.0.2/template/yoga/icon/mimetypes/index.php	(revision 3278)
+++ /tags/2.0.2/template/yoga/icon/mimetypes/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/template/yoga/identification.tpl
===================================================================
--- /tags/2.0.2/template/yoga/identification.tpl	(revision 3278)
+++ /tags/2.0.2/template/yoga/identification.tpl	(revision 3278)
@@ -0,0 +1,72 @@
+{* $Id$ *}
+<div id="content" class="content">
+
+  <div class="titrePage">
+    <ul class="categoryActions">
+      <li><a href="{$U_LOST_PASSWORD}" title="{'Forgot your password?'|@translate}"><img src="{$ROOT_URL}{$themeconf.icon_dir}/lost_password.png" class="button" alt="{'Forgot your password?'|@translate}"></a></li>
+      {if isset($U_REGISTER) }
+      <li><a href="{$U_REGISTER}" title="{'Create a new account'|@translate}"><img src="{$ROOT_URL}{$themeconf.icon_dir}/register.png" class="button" alt="{'Register'|@translate}"/></a></li>
+      {/if}
+      <li><a href="{$U_HOME}" title="{'Go through the gallery as a visitor'|@translate}"><img src="{$ROOT_URL}{$themeconf.icon_dir}/home.png" class="button" alt="{'home'|@translate}"/></a></li>
+    </ul>
+    <h2>{'Identification'|@translate}</h2>
+  </div>
+
+  {if isset($errors) }
+  <div class="errors">
+    <ul>
+      {foreach from=$errors item=error}
+      <li>{$error}</li>
+      {/foreach}
+    </ul>
+  </div>
+  {/if}
+
+<form action="{$F_LOGIN_ACTION}" method="post" name="login_form" class="properties">
+  <fieldset>
+    <legend>{'Connection settings'|@translate}</legend>
+
+    <input type="hidden" name="redirect" value="{$U_REDIRECT}">
+
+    <ul>
+      <li>
+        <span class="property">
+          <label for="username">{'Username'|@translate}</label>
+        </span>
+        <input tabindex="1" class="login" type="text" name="username" id="username" size="25" maxlength="40" />
+      </li>
+
+      <li>
+        <span class="property">
+          <label for="password">{'Password'|@translate}</label>
+        </span>
+        <input tabindex="2" class="login" type="password" name="password" id="password" size="25" maxlength="25" />
+      </li>
+
+      {if $authorize_remembering }
+      <li>
+        <span class="property">
+          <label for="remember_me">{'remember_me'|@translate}</label>
+        </span>
+        <input tabindex="3" type="checkbox" name="remember_me" id="remember_me" value="1">
+      </li>
+      {/if}
+    </ul>
+  </fieldset>
+
+  <p><input class="submit" tabindex="4" type="submit" name="login" value="{'Submit'|@translate}"></p>
+
+  <p>
+    {if isset($U_REGISTER) }
+    <a href="{$U_REGISTER}" title="{'Create a new account'|@translate}"><img src="{$ROOT_URL}{$themeconf.icon_dir}/register.png" class="button" alt="{'Register'|@translate}"> {'Register'|@translate}</a>
+    {/if}
+    <a href="{$U_LOST_PASSWORD}" title="{'Forgot your password?'|@translate}"><img src="{$ROOT_URL}{$themeconf.icon_dir}/lost_password.png" class="button" alt="{'Forgot your password?'|@translate}"> {'Forgot your password?'|@translate}</a>
+  </p>
+
+</form>
+
+<script type="text/javascript"><!--
+document.login_form.username.focus();
+//--></script>
+
+</div> <!-- content -->
Index: /tags/2.0.2/template/yoga/include/autosize.inc.tpl
===================================================================
--- /tags/2.0.2/template/yoga/include/autosize.inc.tpl	(revision 3278)
+++ /tags/2.0.2/template/yoga/include/autosize.inc.tpl	(revision 3278)
@@ -0,0 +1,14 @@
+{* $Id$ *}
+{known_script id="jquery" src=$ROOT_URL|@cat:"template-common/lib/jquery.packed.js"}
+{known_script id="jquery.autogrow" src=$ROOT_URL|@cat:"template-common/lib/plugins/jquery.autogrow-textarea.js"}
+
+{* Auto size and auto grow textarea *}
+{literal}
+<script type="text/javascript">
+  jQuery().ready(function(){
+    jQuery('textarea').css('overflow-y', 'hidden');
+    // Auto size and auto grow for all text area
+    jQuery('textarea').autogrow();
+  });
+</script>
+{/literal}
Index: /tags/2.0.2/template/yoga/include/datepicker.inc.tpl
===================================================================
--- /tags/2.0.2/template/yoga/include/datepicker.inc.tpl	(revision 3278)
+++ /tags/2.0.2/template/yoga/include/datepicker.inc.tpl	(revision 3278)
@@ -0,0 +1,25 @@
+{* $Id$ *}
+
+{known_script id="jquery" src=$ROOT_URL|@cat:"template-common/lib/jquery.packed.js"}
+{known_script id="jquery.ui" src=$ROOT_URL|@cat:"template-common/lib/ui/ui.core.packed.js"}
+{known_script id="jquery.ui.datepicker" src=$ROOT_URL|@cat:"template-common/lib/ui/ui.datepicker.packed.js"}
+{known_script id="datepicker.js" src=$ROOT_URL|@cat:"template-common/datepicker.js"}
+
+{assign var="datepicker_language" value="template-common/lib/ui/i18n/ui.datepicker-"|@cat:$lang_info.code|@cat:".js"}
+
+{if "PHPWG_ROOT_PATH"|@constant|@cat:$datepicker_language|@file_exists}
+{known_script id="jquery.ui.datepicker-$lang_info.code" src=$ROOT_URL|@cat:$datepicker_language}
+{/if}
+
+{html_head}
+<link rel="stylesheet" type="text/css" href="{$ROOT_URL}template-common/lib/ui/ui.datepicker.css">
+{/html_head}
+
+<script type="text/javascript">
+function pwg_initialization_datepicker(day, month, year, linked_date, checked_on_change, min_linked_date, max_linked_date)
+{ldelim}
+  return pwg_common_initialization_datepicker(
+    "{$ROOT_URL}{$themeconf.icon_dir}/datepicker.png",
+    day, month, year, linked_date, checked_on_change, min_linked_date, max_linked_date);
+}
+</script>
Index: /tags/2.0.2/template/yoga/include/resize.inc.tpl
===================================================================
--- /tags/2.0.2/template/yoga/include/resize.inc.tpl	(revision 3278)
+++ /tags/2.0.2/template/yoga/include/resize.inc.tpl	(revision 3278)
@@ -0,0 +1,23 @@
+{* $Id$ *}
+{known_script id="jquery" src=$ROOT_URL|@cat:"template-common/lib/jquery.packed.js"}
+{known_script id="jquery.ui" src=$ROOT_URL|@cat:"template-common/lib/ui/ui.core.packed.js"}
+{known_script id="jquery.ui.resizable" src=$ROOT_URL|@cat:"template-common/lib/ui/ui.resizable.packed.js"}
+
+{* Resize possible *}
+{literal}
+<script type="text/javascript">
+  jQuery().ready(function(){
+    // Resize possible for list
+    jQuery(".categoryList").resizable({
+      handles: "all",
+      animate: true,
+      animateDuration: "slow",
+      animateEasing: "swing",
+      preventDefault: true,
+      preserveCursor: true,
+      autoHide: true,
+      ghost: true
+    });
+  });
+</script>
+{/literal}
Index: /tags/2.0.2/template/yoga/index.php
===================================================================
--- /tags/2.0.2/template/yoga/index.php	(revision 3278)
+++ /tags/2.0.2/template/yoga/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/template/yoga/index.tpl
===================================================================
--- /tags/2.0.2/template/yoga/index.tpl	(revision 3278)
+++ /tags/2.0.2/template/yoga/index.tpl	(revision 3278)
@@ -0,0 +1,118 @@
+{* $Id$ *}
+{$MENUBAR}
+{if !empty($PLUGIN_INDEX_CONTENT_BEFORE)}{$PLUGIN_INDEX_CONTENT_BEFORE}{/if}
+<div id="content" class="content">
+  <div class="titrePage">
+    <ul class="categoryActions">
+      {if !empty($image_orders) }
+      <li>
+      {'Sort order'|@translate}:
+      <select onchange="document.location = this.options[this.selectedIndex].value;">
+        {foreach from=$image_orders item=image_order }
+        <option value="{$image_order.URL}"{if $image_order.SELECTED} selected="selected"{/if}>{$image_order.DISPLAY}</option>
+        {/foreach}
+      </select>
+      </li>
+      {/if}
+
+      {if isset($U_CADDIE) }
+      <li><a href="{$U_CADDIE}" title="{'add to caddie'|@translate}"><img src="{$ROOT_URL}{$themeconf.icon_dir}/caddie_add.png" class="button" alt="{'caddie'|@translate}"/></a></li>
+      {/if}
+
+      {if isset($U_EDIT) }
+      <li><a href="{$U_EDIT}" title="{'edit category informations'|@translate}"><img src="{$ROOT_URL}{$themeconf.icon_dir}/category_edit.png" class="button" alt="{'edit'|@translate}"/></a></li>
+      {/if}
+
+      {if isset($U_SEARCH_RULES) }
+      <li><a href="{$U_SEARCH_RULES}" onclick="popuphelp(this.href); return false;" title="{'Search rules'|@translate}" rel="nofollow"><img src="{$ROOT_URL}{$themeconf.icon_dir}/search_rules.png" class="button" alt="(?)" /></a></li>
+      {/if}
+
+      {if isset($U_SLIDESHOW) }
+      <li><a href="{$U_SLIDESHOW}" title="{'slideshow'|@translate}" rel="nofollow"><img src="{$ROOT_URL}{$themeconf.icon_dir}/start_slideshow.png" class="button" alt="{'slideshow'|@translate}"/></a></li>
+      {/if}
+
+      {if isset($U_MODE_FLAT) }
+      <li><a href="{$U_MODE_FLAT}" title="{'mode_flat_hint'|@translate}" rel="nofollow"><img src="{$ROOT_URL}{$themeconf.icon_dir}/flat.png" class="button" alt="{'mode_flat_hint'|@translate}" /></a></li>
+      {/if}
+
+      {if isset($U_MODE_NORMAL) }
+      <li><a href="{$U_MODE_NORMAL}" title="{'mode_normal_hint'|@translate}"><img src="{$ROOT_URL}{$themeconf.icon_dir}/normal_mode.png" class="button" alt="{'mode_normal_hint'|@translate}" /></a></li>
+      {/if}
+
+      {if isset($U_MODE_POSTED) }
+      <li><a href="{$U_MODE_POSTED}" title="{'mode_posted_hint'|@translate}" rel="nofollow"><img src="{$ROOT_URL}{$themeconf.icon_dir}/calendar.png" class="button" alt="{'mode_posted_hint'|@translate}" /></a></li>
+      {/if}
+      
+      {if isset($U_MODE_CREATED) }
+      <li><a href="{$U_MODE_CREATED}" title="{'mode_created_hint'|@translate}" rel="nofollow"><img src="{$ROOT_URL}{$themeconf.icon_dir}/calendar_created.png" class="button" alt="{'mode_created_hint'|@translate}" /></a></li>
+      {/if}
+      
+      {if !empty($PLUGIN_INDEX_ACTIONS)}{$PLUGIN_INDEX_ACTIONS}{/if}
+    </ul>
+
+  <h2>{$TITLE}</h2>
+
+  {if isset($chronology_views) }
+  <div class="calendarViews">{'calendar_view'|@translate}:
+    <select onchange="document.location = this.options[this.selectedIndex].value;">
+      {foreach from=$chronology_views item=view}
+      <option value="{$view.VALUE}"{if $view.SELECTED} selected="selected"{/if}>{$view.CONTENT}</option>
+      {/foreach}
+    </select>
+  </div>
+  {/if}
+
+  {if isset($chronology.TITLE) }
+  <h2>{$chronology.TITLE}</h2>
+  {/if}
+
+  </div> <!-- titrePage -->
+
+{if !empty($PLUGIN_INDEX_CONTENT_BEGIN)}{$PLUGIN_INDEX_CONTENT_BEGIN}{/if}
+
+{if !empty($category_search_results) }
+<div style="font-size:16px;margin:10px 16px">{'Category results for'|@translate} <strong>{$QUERY_SEARCH}</strong> :
+  <em><strong>
+  {foreach from=$category_search_results item=res name=res_loop}
+  {if !$smarty.foreach.res_loop.first} &mdash; {/if}
+  {$res}
+  {/foreach}
+  </strong></em>
+</div>
+{/if}
+
+{if !empty($tag_search_results) }
+<div style="font-size:16px;margin:10px 16px">{'Tag results for'|@translate} <strong>{$QUERY_SEARCH}</strong> :
+  <em><strong>
+  {foreach from=$tag_search_results item=res name=res_loop}
+  {if !$smarty.foreach.res_loop.first} &mdash; {/if}
+  {$res}
+  {/foreach}
+  </strong></em>
+</div>
+{/if}
+
+{if isset($FILE_CHRONOLOGY_VIEW) }
+{include file=$FILE_CHRONOLOGY_VIEW}
+{/if}
+
+{if !empty($CATEGORIES) }{$CATEGORIES}{/if}
+{if !empty($THUMBNAILS) }{$THUMBNAILS}{/if}
+
+
+{if !empty($NAV_BAR) }
+<div class="navigationBar">
+  {$NAV_BAR}
+</div>
+{/if}
+
+{if !empty($CONTENT_DESCRIPTION) }
+<div class="additional_info">
+  {$CONTENT_DESCRIPTION}
+</div>
+{/if}
+
+{if !empty($PLUGIN_INDEX_CONTENT_END) }{$PLUGIN_INDEX_CONTENT_END}{/if}
+</div> <!-- content -->
+
+{if !empty($PLUGIN_INDEX_CONTENT_AFTER)}{$PLUGIN_INDEX_CONTENT_AFTER}{/if}
Index: /tags/2.0.2/template/yoga/layout.css
===================================================================
--- /tags/2.0.2/template/yoga/layout.css	(revision 3278)
+++ /tags/2.0.2/template/yoga/layout.css	(revision 3278)
@@ -0,0 +1,17 @@
+/* $Id$ */
+
+/* template css */
+@import "menubar.css";
+@import "content.css";
+@import "thumbnails.css";
+@import "picture.css";
+@import "default-layout.css";
+/* Override properties with import local file */
+@import "local-layout.css";
+/* common css */
+@import "../../template-common/default-layout.css";
+/* Override properties with import local file */
+@import "../../template-common/local-layout.css";
+
+@import "default-colors.css";
+
Index: /tags/2.0.2/template/yoga/mail/index.php
===================================================================
--- /tags/2.0.2/template/yoga/mail/index.php	(revision 3278)
+++ /tags/2.0.2/template/yoga/mail/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/template/yoga/mail/text/html/cat_group_info.tpl
===================================================================
--- /tags/2.0.2/template/yoga/mail/text/html/cat_group_info.tpl	(revision 3278)
+++ /tags/2.0.2/template/yoga/mail/text/html/cat_group_info.tpl	(revision 3278)
@@ -0,0 +1,9 @@
+{* $Id$ *}
+<div id="cat_group_info">
+<h2>{'Informations'|@translate}</h2>
+<p>{$IMG_URL}</p>
+<p>{'Hello,'|@translate}</p>
+<p>{'Come to discover the category:'|@translate} <a href="{$LINK}">{$CAT_NAME}</a></p>
+<p>{$CPL_CONTENT}</p>
+<p>{'See you soon.'|@translate}</p>
+</div>
Index: /tags/2.0.2/template/yoga/mail/text/html/footer.tpl
===================================================================
--- /tags/2.0.2/template/yoga/mail/text/html/footer.tpl	(revision 3278)
+++ /tags/2.0.2/template/yoga/mail/text/html/footer.tpl	(revision 3278)
@@ -0,0 +1,20 @@
+{* $Id$ *}
+</div> <!-- content -->
+<div id="copyright">
+<hr/>
+ {* Please, do not remove this copyright. If you really want to,
+      contact us on http://piwigo.org to find a solution on how
+      to show the origin of the script...*}
+
+  {'powered_by'|@translate}
+  <a href="http://piwigo.org" class="Piwigo">
+  <span class="Piwigo">Piwigo</span></a>
+  {$VERSION}
+  - {'send_mail'|@translate}
+  <a href="mailto:{$MAIL}?subject={$TITLE_MAIL}">{'Webmaster'|@translate}</a>
+
+</div> <!-- copyright -->
+</div> <!-- the_page -->
+
+</body>
+</html>
Index: /tags/2.0.2/template/yoga/mail/text/html/global-mail-css.tpl
===================================================================
--- /tags/2.0.2/template/yoga/mail/text/html/global-mail-css.tpl	(revision 3278)
+++ /tags/2.0.2/template/yoga/mail/text/html/global-mail-css.tpl	(revision 3278)
@@ -0,0 +1,12 @@
+{* $Id$ *}
+/* Global mail css */
+
+body {ldelim} font-family: Univers, Helvetica, Optima; font-size:12px; margin:0px; padding:0px; }
+#the_page {ldelim} margin:0px; padding:0px; text-align:left;}
+#content {ldelim} margin:0px; padding:82px 0px 0px 62px; width:732px;}
+hr {ldelim} width:632px; margin-left:0;}
+#copyright {ldelim} font-size:10px; margin:0px; padding:48px 0px 32px 62px;}
+.PWG {ldelim} font-family:verdana, sans-serif !important; font-size:0.9em; font-weight:normal; letter-spacing:0px;}
+h2 {ldelim} padding:7px 15px; width:617px; font-weight:bold;}
+img {ldelim} margin:16px; border:16px solid #aaa; -moz-border-radius: 4px; border-radius: 4px 4px; }
+img:hover {ldelim} padding: 15px; border: 1px solid yellow; -moz-border-radius: 4px; border-radius: 4px 4px; }
Index: /tags/2.0.2/template/yoga/mail/text/html/header.tpl
===================================================================
--- /tags/2.0.2/template/yoga/mail/text/html/header.tpl	(revision 3278)
+++ /tags/2.0.2/template/yoga/mail/text/html/header.tpl	(revision 3278)
@@ -0,0 +1,19 @@
+{* $Id$ *}
+-----={$BOUNDARY_KEY}
+Content-Type: {$CONTENT_TYPE}; charset="{$CONTENT_ENCODING}";
+Content-Transfer-Encoding: 8bit
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html lang="{$lang_info.code}" dir="{$lang_info.direction}">
+<head>
+<title>Piwigo Mail</title>
+<meta http-equiv="Content-Type" content="text/html; charset={$CONTENT_ENCODING}">
+<style><!-- /* Mini style for mails */
+{if isset($GLOBAL_MAIL_CSS)}{$GLOBAL_MAIL_CSS}{/if}
+{if isset($MAIL_CSS)}{$MAIL_CSS}{/if}
+{if isset($LOCAL_MAIL_CSS)}{$LOCAL_MAIL_CSS}{/if}
+--></style>
+</head>
+<body>
+<div id="the_page">
+<div id="content" class="content">
Index: /tags/2.0.2/template/yoga/mail/text/html/images/index.php
===================================================================
--- /tags/2.0.2/template/yoga/mail/text/html/images/index.php	(revision 3278)
+++ /tags/2.0.2/template/yoga/mail/text/html/images/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/template/yoga/mail/text/html/index.php
===================================================================
--- /tags/2.0.2/template/yoga/mail/text/html/index.php	(revision 3278)
+++ /tags/2.0.2/template/yoga/mail/text/html/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/template/yoga/mail/text/html/notification_by_mail.tpl
===================================================================
--- /tags/2.0.2/template/yoga/mail/text/html/notification_by_mail.tpl	(revision 3278)
+++ /tags/2.0.2/template/yoga/mail/text/html/notification_by_mail.tpl	(revision 3278)
@@ -0,0 +1,57 @@
+{* $Id$ *}
+<div id="nbm_message">
+<h2>{'Notification'|@translate}</h2>
+<p>{'nbm_content_hello_1'|@translate}{$USERNAME}{'nbm_content_hello_2'|@translate}</p>
+
+{if isset($subscribe_by_admin)}
+<p>{'nbm_content_subscribe_by_admin'|@translate}</p>
+{/if}
+{if isset($subscribe_by_himself)}
+<p>{'nbm_content_subscribe_by_himself'|@translate}</p>
+{/if}
+{if isset($unsubscribe_by_admin)}
+<p>{'nbm_content_unsubscribe_by_admin'|@translate}</p>
+{/if}
+{if isset($unsubscribe_by_himself)}
+<p>{'nbm_content_unsubscribe_by_himself'|@translate}</p>
+{/if}
+{if isset($content_new_elements_single)}
+<p>{'nbm_content_new_elements'|@translate}{'nbm_content_new_elements_single'|@translate}{$content_new_elements_single.DATE_SINGLE}.</p>
+{/if}
+{if isset($content_new_elements_between)}
+<p>{'nbm_content_new_elements'|@translate}{'nbm_content_new_elements_between_1'|@translate}{$content_new_elements_between.DATE_BETWEEN_1}{'nbm_content_new_elements_between_2'|@translate}{$content_new_elements_between.DATE_BETWEEN_2}.</p>
+{/if}
+
+{if not empty($global_new_lines)}
+<ul id="nbm_new_line">
+{foreach from=$global_new_lines item=line}
+  <li>{$line}</li>
+{/foreach}
+</ul>
+{/if}
+
+{if not empty($custom_mail_content)}
+<p>{$custom_mail_content}</p>
+{/if}
+
+{if not empty($GOTO_GALLERY_TITLE)}
+<p>{'nbm_content_goto_1'|@translate}<a href="{$GOTO_GALLERY_URL}">{$GOTO_GALLERY_TITLE}</a>{'nbm_content_goto_2'|@translate}</p>
+{/if}
+<p>{'nbm_content_byebye'|@translate}</p>
+<p style="text-align:center">{$SEND_AS_NAME}</p>
+<p>
+<br/><hr/>
+{'nbm_content_unsubscribe_link'|@translate}{'nbm_content_click_on'|@translate}<a href="{$UNSUBSCRIBE_LINK}">{$UNSUBSCRIBE_LINK}</a><br/>
+{'nbm_content_subscribe_link'|@translate}{'nbm_content_click_on'|@translate}<a href="{$SUBSCRIBE_LINK}">{$SUBSCRIBE_LINK}</a><br/>
+{'nbm_content_problem_contact'|@translate}<a href="mailto:{$CONTACT_EMAIL}?subject={'nbm_content_pb_contact_object'|@translate}">{$CONTACT_EMAIL}</a><br/>
+<hr/><br/>
+</p>
+{if not empty($recent_posts)}
+</div>
+<div id="nbm_recent_post">
+  {foreach from=$recent_posts item=recent_post }
+  <h2>{$recent_post.TITLE}</h2>
+  {$recent_post.HTML_DATA}
+  {/foreach}
+{/if}
+</div>
Index: /tags/2.0.2/template/yoga/mail/text/index.php
===================================================================
--- /tags/2.0.2/template/yoga/mail/text/index.php	(revision 3278)
+++ /tags/2.0.2/template/yoga/mail/text/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/template/yoga/mail/text/plain/cat_group_info.tpl
===================================================================
--- /tags/2.0.2/template/yoga/mail/text/plain/cat_group_info.tpl	(revision 3278)
+++ /tags/2.0.2/template/yoga/mail/text/plain/cat_group_info.tpl	(revision 3278)
@@ -0,0 +1,9 @@
+{* $Id$ *}
+{'Hello,'|@translate}
+
+{'Come to discover the category:'|@translate} {$CAT_NAME}
+{$LINK}
+
+{$CPL_CONTENT}
+
+{'See you soon.'|@translate}
Index: /tags/2.0.2/template/yoga/mail/text/plain/footer.tpl
===================================================================
--- /tags/2.0.2/template/yoga/mail/text/plain/footer.tpl	(revision 3278)
+++ /tags/2.0.2/template/yoga/mail/text/plain/footer.tpl	(revision 3278)
@@ -0,0 +1,4 @@
+{* $Id$ *}
+
+------------------------
+Piwigo {$VERSION}
Index: /tags/2.0.2/template/yoga/mail/text/plain/header.tpl
===================================================================
--- /tags/2.0.2/template/yoga/mail/text/plain/header.tpl	(revision 3278)
+++ /tags/2.0.2/template/yoga/mail/text/plain/header.tpl	(revision 3278)
@@ -0,0 +1,6 @@
+{* $Id$ *}
+-----={$BOUNDARY_KEY}
+Content-Type: {$CONTENT_TYPE}; charset="{$CONTENT_ENCODING}";
+Content-Transfer-Encoding: 8bit{literal}
+
+{/literal}{*note that there must be an empty line to separate the mime headers*}
Index: /tags/2.0.2/template/yoga/mail/text/plain/index.php
===================================================================
--- /tags/2.0.2/template/yoga/mail/text/plain/index.php	(revision 3278)
+++ /tags/2.0.2/template/yoga/mail/text/plain/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/template/yoga/mail/text/plain/notification_by_mail.tpl
===================================================================
--- /tags/2.0.2/template/yoga/mail/text/plain/notification_by_mail.tpl	(revision 3278)
+++ /tags/2.0.2/template/yoga/mail/text/plain/notification_by_mail.tpl	(revision 3278)
@@ -0,0 +1,42 @@
+{* $Id$ *}
+{'nbm_content_hello_1'|@translate}{$USERNAME}{'nbm_content_hello_2'|@translate}
+
+{if isset($subscribe_by_admin)}
+{'nbm_content_subscribe_by_admin'|@translate}
+{/if}
+{if isset($subscribe_by_himself)}
+{'nbm_content_subscribe_by_himself'|@translate}
+{/if}
+{if isset($unsubscribe_by_admin)}
+{'nbm_content_unsubscribe_by_admin'|@translate}
+{/if}
+{if isset($unsubscribe_by_himself)}
+{'nbm_content_unsubscribe_by_himself'|@translate}
+{/if}
+{if isset($content_new_elements_single)}
+{'nbm_content_new_elements'|@translate}{'nbm_content_new_elements_single'|@translate}{$content_new_elements_single.DATE_SINGLE}.
+{/if}
+{if isset($content_new_elements_between)}
+{'nbm_content_new_elements'|@translate}{'nbm_content_new_elements_between_1'|@translate}{$content_new_elements_between.DATE_BETWEEN_1}{'nbm_content_new_elements_between_2'|@translate}{$content_new_elements_between.DATE_BETWEEN_2}.
+{/if}
+{if not empty($global_new_lines)}
+{foreach from=$global_new_lines item=line}
+  o {$line}
+{/foreach}
+{/if}
+{if not empty($custom_mail_content)}
+{$custom_mail_content}
+{/if}
+{if not empty($GOTO_GALLERY_TITLE)}
+{'nbm_content_goto_1'|@translate}{$GOTO_GALLERY_TITLE} {$GOTO_GALLERY_URL} {'nbm_content_goto_2'|@translate}
+{/if}
+
+{'nbm_content_byebye'|@translate}
+  {$SEND_AS_NAME}
+
+______________________________________________________________________________
+
+{'nbm_content_unsubscribe_link'|@translate}{'nbm_content_click_on'|@translate}{$UNSUBSCRIBE_LINK}
+{'nbm_content_subscribe_link'|@translate}{'nbm_content_click_on'|@translate}{$SUBSCRIBE_LINK}
+{'nbm_content_problem_contact'|@translate}{$CONTACT_EMAIL}
+______________________________________________________________________________
Index: /tags/2.0.2/template/yoga/mainpage_categories.tpl
===================================================================
--- /tags/2.0.2/template/yoga/mainpage_categories.tpl	(revision 3278)
+++ /tags/2.0.2/template/yoga/mainpage_categories.tpl	(revision 3278)
@@ -0,0 +1,30 @@
+{* $Id$ *}
+
+<ul class="thumbnailCategories">
+{foreach from=$category_thumbnails item=cat}
+	<li>
+		<div class="thumbnailCategory">
+			<div class="illustration">
+			<a href="{$cat.URL}">
+				<img src="{$cat.TN_SRC}" alt="{$cat.TN_ALT}" title="{$cat.NAME|@replace:'"':' '} - {'hint_category'|@translate}">
+			</a>
+			</div>
+			<div class="description">
+				<h3>
+					<a href="{$cat.URL}">{$cat.NAME}</a>
+					{$cat.ICON_TS}
+				</h3>
+		<div class="text">
+				{if isset($cat.INFO_DATES) }
+				<p class="dates">{$cat.INFO_DATES}</p>
+				{/if}
+				<p class="Nb_images">{$cat.CAPTION_NB_IMAGES}</p>
+				{if not empty($cat.DESCRIPTION)}
+				<p>{$cat.DESCRIPTION}</p>
+				{/if}
+		</div>
+			</div>
+		</div>
+	</li>
+{/foreach}
+</ul>
Index: /tags/2.0.2/template/yoga/menubar.css
===================================================================
--- /tags/2.0.2/template/yoga/menubar.css	(revision 3278)
+++ /tags/2.0.2/template/yoga/menubar.css	(revision 3278)
@@ -0,0 +1,87 @@
+#menubar {
+	float: left;
+	margin: 0 0 10px 1em;
+	padding: 0;
+	display: inline;
+}
+
+#menubar DL, #menubar DT, #menubar DD {
+	margin: 0; padding: 0; display: block;
+}
+
+#menubar .button {
+	margin: -2px 2px 2px;
+	width: auto;
+	padding: 0;
+	text-indent: 0;
+	list-style: none;
+	text-align: center;
+	float: right;
+}
+
+/* H2 properties copied here */
+#menubar DT {
+	font-weight: bold;
+	padding: 5px 5px 5px 5px;
+	font-size: 120%;
+	text-align: center;
+}
+
+#menubar UL,
+#menubar FORM,
+#menubar P {
+	font-size: 92%;
+	margin: 10px 0 10px 5px;
+}
+#menubar UL {
+	list-style-type: square;
+	list-style-position: inside;
+	padding: 0 0 0 2px;
+}
+#menubar UL UL {
+	font-size: 100%;
+	margin-top: 0;
+	margin-bottom: 0;
+}
+
+#menubar LI.selected A {
+	font-weight: bold;
+}
+
+#menubar LI.selected LI A {
+	font-weight: normal;
+}
+
+#menubar .menuInfoCatByChild {
+	font-size: 80%;
+	font-style: italic;
+}
+
+#menubar INPUT {
+	text-indent: 2px;
+}
+
+/* quickconnect form */
+FORM#quickconnect {
+	margin: 5px;
+	padding: 0;
+}
+
+FORM#quickconnect FIELDSET {
+	margin: 0;
+	padding: 0; /*IE6 requires padding 0*/
+}
+
+FORM#quickconnect FIELDSET DIV {
+	margin: 8px 5px;
+	padding: 0;
+}
+
+#menubar #menuTagCloud {
+	text-align: center;
+	margin: 5px 0;
+}
+
+#menubar #menuTagCloud SPAN {
+	white-space: nowrap;
+}
Index: /tags/2.0.2/template/yoga/menubar.tpl
===================================================================
--- /tags/2.0.2/template/yoga/menubar.tpl	(revision 3278)
+++ /tags/2.0.2/template/yoga/menubar.tpl	(revision 3278)
@@ -0,0 +1,13 @@
+{if !empty($blocks) }
+<div id="menubar">
+	{foreach from=$blocks key=id item=block}
+	<dl id="{$id}">
+		{if not empty($block->template)}
+		{include file=$block->template|@get_extent:$id }
+		{else}
+		{$block->raw_content}
+		{/if}
+	</dl>
+	{/foreach}
+</div>
+{/if}
Index: /tags/2.0.2/template/yoga/menubar_categories.tpl
===================================================================
--- /tags/2.0.2/template/yoga/menubar_categories.tpl	(revision 3278)
+++ /tags/2.0.2/template/yoga/menubar_categories.tpl	(revision 3278)
@@ -0,0 +1,20 @@
+<dt>
+  {if isset($U_START_FILTER)}
+  <a href="{$U_START_FILTER}" title="{'start_filter_hint'|@translate}" rel="nofollow"><img src="{$ROOT_URL}{$themeconf.icon_dir}/start_filter.png" class="button" alt="start filter"></a>
+  {/if}
+  {if isset($U_STOP_FILTER)}
+  <a href="{$U_STOP_FILTER}" title="{'stop_filter_hint'|@translate}"><img src="{$ROOT_URL}{$themeconf.icon_dir}/stop_filter.png" class="button" alt="stop filter"></a>
+  {/if}
+	<a href="{$block->data.U_CATEGORIES}">{'Categories'|@translate}</a>
+</dt>
+<dd>
+	{$block->data.MENU_CATEGORIES_CONTENT}
+	{if isset($block->data.U_UPLOAD)}
+	<ul>
+		<li>
+			<a href="{$block->data.U_UPLOAD}">{'upload_picture'|@translate}</a>
+		</li>
+	</ul>
+	{/if}
+	<p class="totalImages">{$pwg->l10n_dec('%d element', '%d elements', $block->data.NB_PICTURE)}</p>
+</dd>
Index: /tags/2.0.2/template/yoga/menubar_identification.tpl
===================================================================
--- /tags/2.0.2/template/yoga/menubar_identification.tpl	(revision 3278)
+++ /tags/2.0.2/template/yoga/menubar_identification.tpl	(revision 3278)
@@ -0,0 +1,64 @@
+<dt>{'identification'|@translate}</dt>
+<dd>
+	{if isset($USERNAME)}
+	<p>{'hello'|@translate}&nbsp;{$USERNAME}&nbsp;!</p>
+	{/if}
+
+	<ul>
+	{if isset($U_REGISTER)}
+	<li><a href="{$U_REGISTER}" title="{'Create a new account'|@translate}" rel="nofollow">{'Register'|@translate}</a></li>
+	{/if}
+
+	{if isset($U_LOGIN)}
+	<li><a href="{$U_LOGIN}" rel="nofollow">{'Connection'|@translate}</a></li>
+	{/if}
+
+	{if isset($U_LOGOUT)}
+	<li><a href="{$U_LOGOUT}">{'logout'|@translate}</a></li>
+	{/if}
+
+	{if isset($U_PROFILE)}
+	<li><a href="{$U_PROFILE}" title="{'hint_customize'|@translate}">{'customize'|@translate}</a></li>
+	{/if}
+
+	{if isset($U_ADMIN)}
+	<li><a href="{$U_ADMIN}" title="{'hint_admin'|@translate}">{'admin'|@translate}</a></li>
+	{/if}
+	</ul>
+
+	{if isset($U_LOGIN)}
+	<form method="post" action="{$U_LOGIN}" id="quickconnect">
+	<fieldset>
+	<legend>{'Quick connect'|@translate}</legend>
+	<div>
+	<label for="username">{'Username'|@translate}</label><br/>
+	<input type="text" name="username" id="username" value="" style="width:99%">
+	</div>
+
+	<div><label for="password">{'Password'|@translate}</label>
+	<br/>
+	<input type="password" name="password" id="password" style="width:99%">
+	</div>
+
+	{if $AUTHORIZE_REMEMBERING}
+	<div><label for="remember_me">
+	{'remember_me'|@translate}
+	<input type="checkbox" name="remember_me" id="remember_me" value="1">
+	</label></div>
+	{/if}
+
+	<div>
+	<input class="submit" type="submit" name="login" value="{'Submit'|@translate}">
+	<ul class="actions">
+		<li><a href="{$U_LOST_PASSWORD}" title="{'Forgot your password?'|@translate}" rel="nofollow"><img src="{$ROOT_URL}{$themeconf.icon_dir}/lost_password.png" class="button" alt="{'Forgot your password?'|@translate}"></a></li>
+		{if isset($U_REGISTER)}
+		<li><a href="{$U_REGISTER}" title="{'Create a new account'|@translate}" rel="nofollow"><img src="{$ROOT_URL}{$themeconf.icon_dir}/register.png" class="button" alt="{'Register'|@translate}"/></a></li>
+		{/if}
+	</ul>
+	</div>
+
+	</fieldset>
+	</form>
+	{/if}
+</dd>
+
Index: /tags/2.0.2/template/yoga/menubar_links.tpl
===================================================================
--- /tags/2.0.2/template/yoga/menubar_links.tpl	(revision 3278)
+++ /tags/2.0.2/template/yoga/menubar_links.tpl	(revision 3278)
@@ -0,0 +1,15 @@
+<dt>{'Links'|@translate}</dt>
+<dd>
+	<ul>
+		{foreach from=$block->data item=link}
+			<li>
+				<a href="{$link.URL}" class="external" 
+					{if isset($link.new_window) } onclick="window.open(this.href, '{$link.new_window.NAME}','{$link.new_window.FEATURES}'); return false;"{/if}
+				>
+				{$link.LABEL}
+				</a>
+			</li>
+		{/foreach}
+	</ul>
+</dd>
+
Index: /tags/2.0.2/template/yoga/menubar_menu.tpl
===================================================================
--- /tags/2.0.2/template/yoga/menubar_menu.tpl	(revision 3278)
+++ /tags/2.0.2/template/yoga/menubar_menu.tpl	(revision 3278)
@@ -0,0 +1,20 @@
+<dt>{'title_menu'|@translate}</dt>
+<dd>
+  {if isset($block->data.qsearch) and  $block->data.qsearch==true}
+    <form action="{$ROOT_URL}qsearch.php" method="get" id="quicksearch" onsubmit="return this.q.value!='' && this.q.value!=qsearch_prompt;">
+      <p style="margin:0;padding:0"{*this <p> is for html validation only - does not affect positioning*}>
+        <input type="text" name="q" id="qsearchInput" onfocus="if (value==qsearch_prompt) value='';" onblur="if (value=='') value=qsearch_prompt;" style="width:90%"/>
+      </p>
+    </form>
+    <script type="text/javascript">var qsearch_prompt="{'qsearch'|@translate|@escape:'javascript'}"; document.getElementById('qsearchInput').value=qsearch_prompt;</script>
+  {/if}
+
+	<ul>
+	{foreach from=$block->data item=link}
+		{if is_array($link)}
+			<li><a href="{$link.URL}" title="{$link.TITLE}" {if isset($link.REL)}{$link.REL}{/if}>{$link.NAME}</a></li>
+		{/if}
+	{/foreach}
+	</ul>
+</dd>
+
Index: /tags/2.0.2/template/yoga/menubar_specials.tpl
===================================================================
--- /tags/2.0.2/template/yoga/menubar_specials.tpl	(revision 3278)
+++ /tags/2.0.2/template/yoga/menubar_specials.tpl	(revision 3278)
@@ -0,0 +1,9 @@
+<dt>{'special_categories'|@translate}</dt>
+<dd>
+	<ul>
+		{foreach from=$block->data item=link}
+		<li><a href="{$link.URL}" title="{$link.TITLE}" {if isset($link.REL)}{$link.REL}{/if}>{$link.NAME}</a></li>
+		{/foreach}
+	</ul>
+</dd>
+
Index: /tags/2.0.2/template/yoga/menubar_tags.tpl
===================================================================
--- /tags/2.0.2/template/yoga/menubar_tags.tpl	(revision 3278)
+++ /tags/2.0.2/template/yoga/menubar_tags.tpl	(revision 3278)
@@ -0,0 +1,18 @@
+<dt>{'Related tags'|@translate}</dt>
+<dd>
+	<div id="menuTagCloud">
+		{foreach from=$block->data item=tag}
+		<span>
+			{if !empty($tag.U_ADD) }
+			<a href="{$tag.U_ADD}"
+				title="{$pwg->l10n_dec('%d element are also linked to current tags', '%d elements are also linked to current tags', $tag.counter)}"
+				rel="nofollow">
+				<img src="{$ROOT_URL}{$themeconf.icon_dir}/add_tag.png" alt="+" />
+			</a>
+			{/if}
+			<a href="{$tag.URL}" class="tagLevel{$tag.level}" title="{'See elements linked to this tag only'|@translate}">{$tag.name}</a>
+		</span>
+		{/foreach}
+	</div>
+</dd>
+
Index: /tags/2.0.2/template/yoga/month_calendar.tpl
===================================================================
--- /tags/2.0.2/template/yoga/month_calendar.tpl	(revision 3278)
+++ /tags/2.0.2/template/yoga/month_calendar.tpl	(revision 3278)
@@ -0,0 +1,70 @@
+{* $Id$ *}
+
+{if !empty($chronology_navigation_bars) }
+{foreach from=$chronology_navigation_bars item=bar}
+<div class="calendarBar">
+  {if isset($bar.previous)}
+    <div style="float:left">&laquo; <a href="{$bar.previous.URL}">{$bar.previous.LABEL}</a></div>
+  {/if}
+  {if isset($bar.next)}
+    <div style="float:right"><a href="{$bar.next.URL}">{$bar.next.LABEL}</a> &raquo;</div>
+  {/if}
+  {if isset($bar.CONTENT)}
+  {$bar.CONTENT}
+  {else}
+  &nbsp;
+  {/if}
+</div>
+{/foreach}
+{/if}
+
+{if !empty($chronology_calendar.calendar_bars) }
+{foreach from=$chronology_calendar.calendar_bars item=bar}
+<div class="calendarCalBar">
+  <span class="calCalHead"><a href="{$bar.U_HEAD}">{$bar.HEAD_LABEL}</a>  ({$bar.NB_IMAGES})</span><br/>
+  {$bar.NAV_BAR}
+</div>
+{/foreach}
+{/if}
+
+{if isset($chronology_calendar.month_view) }
+<table class="calMonth">
+ <thead>
+ <tr>
+ {foreach from=$chronology_calendar.month_view.wday_labels item=wday}
+	<td class="calDayHead">{$wday}</td>
+ {/foreach}
+ </tr>
+ </thead>
+{html_head} {*add the style to html head for strict standard compliance*}
+<style type="text/css">
+TABLE.calMonth TBODY TD, TABLE.calMonth TBODY TD DIV.calImg {ldelim}
+  width:{$chronology_calendar.month_view.CELL_WIDTH}px;height:{$chronology_calendar.month_view.CELL_HEIGHT}px;
+}
+</style>
+{/html_head}
+ {foreach from=$chronology_calendar.month_view.weeks item=week}
+ <tr>
+ 	{foreach from=$week item=day}
+ 	{if !empty($day)}
+ 		{if isset($day.IMAGE)}
+ 			<td class="calDayCellFull">
+	 			<div class="calBackDate">{$day.DAY}</div><div class="calForeDate">{$day.DAY}</div>
+	 			<div class="calImg">
+					<a href="{$day.U_IMG_LINK}">
+			  			<img style="{$day.IMAGE_STYLE}" src="{$day.IMAGE}" alt="{$day.IMAGE_ALT}" title="{$pwg->l10n_dec('%d element','%d elements', $day.NB_ELEMENTS)}" />
+					</a>
+				</div>
+ 		{else}
+ 			<td class="calDayCellEmpty">{$day.DAY}
+ 		{/if}
+ 	{else}
+ 		<td class="calDayCellBlank">
+ 	{/if}
+ 	</td>
+ 	{/foreach} {*day in week*}
+ </tr>
+ {/foreach}  {*week in month*}
+</table>
+{/if}
+
Index: /tags/2.0.2/template/yoga/nbm.tpl
===================================================================
--- /tags/2.0.2/template/yoga/nbm.tpl	(revision 3278)
+++ /tags/2.0.2/template/yoga/nbm.tpl	(revision 3278)
@@ -0,0 +1,31 @@
+{* $Id$ *}
+
+<div id="content" class="content">
+  <div class="titrePage">
+    <ul class="categoryActions">
+      <li><a href="{$U_HOME}" title="{'Go through the gallery as a visitor'|@translate}"><img src="{$themeconf.icon_dir}/home.png" class="button" alt="{'home'|@translate}"/></a></li>
+    </ul>
+    <h2>{'nbm_item_notification'|@translate}</h2>
+  </div>
+
+  {if not empty($errors)}
+  <div class="errors">
+    <ul>
+      {foreach from=$errors item=error}
+      <li>{$error}</li>
+      {/foreach}
+    </ul>
+  </div>
+  {/if}
+
+  {if not empty($infos)}
+  <div class="infos">
+    <ul>
+      {foreach from=$infos item=info}
+      <li>{$info}</li>
+      {/foreach}
+    </ul>
+  </div>
+  {/if}
+
+</div>
Index: /tags/2.0.2/template/yoga/not-ie.css
===================================================================
--- /tags/2.0.2/template/yoga/not-ie.css	(revision 3278)
+++ /tags/2.0.2/template/yoga/not-ie.css	(revision 3278)
@@ -0,0 +1,9 @@
+/* $Id$ */
+
+/* All directives not supported by IE */
+/* can be overiden in any theme but not hidden to IE */
+
+.content UL.thumbnails SPAN.wrap2 {
+  -moz-border-radius: 4px;	/* round corners with Geko */
+  -webkit-border-radius: 4px; /* Safari webkit project */
+}
Index: /tags/2.0.2/template/yoga/notification.tpl
===================================================================
--- /tags/2.0.2/template/yoga/notification.tpl	(revision 3278)
+++ /tags/2.0.2/template/yoga/notification.tpl	(revision 3278)
@@ -0,0 +1,25 @@
+{* $Id$ *}
+{html_head}
+<link rel="alternate" type="application/rss+xml" title="{'Image only RSS feed'|@translate}" href="{$U_FEED_IMAGE_ONLY}">
+<link rel="alternate" type="application/rss+xml" title="{'Complete RSS feed'|@translate}" href="{$U_FEED}">
+{/html_head}
+<div id="content" class="content">
+
+  <div class="titrePage">
+    <ul class="categoryActions">
+      <li><a href="{$U_HOME}" title="{'return to homepage'|@translate}"><img src="{$themeconf.icon_dir}/home.png" class="button" alt="{'home'|@translate}"/></a></li>
+    </ul>
+    <h2>{'Notification'|@translate}</h2>
+  </div>
+
+  <p>{'The RSS notification feed provides notification on news from this website : new pictures, updated categories, new comments. Use a RSS feed reader.'|@translate}</p>
+
+  <dl>
+    <dt>
+      <a href="{$U_FEED_IMAGE_ONLY}">{'Image only RSS feed'|@translate}</a><br /><br />
+    </dt>
+    <dt>
+      <a href="{$U_FEED}">{'Complete RSS feed'|@translate}</a>
+    </dt>
+  </dl>
+</div>
Index: /tags/2.0.2/template/yoga/password.tpl
===================================================================
--- /tags/2.0.2/template/yoga/password.tpl	(revision 3278)
+++ /tags/2.0.2/template/yoga/password.tpl	(revision 3278)
@@ -0,0 +1,54 @@
+{* $Id$ *}
+<div id="content" class="content">
+
+  <div class="titrePage">
+    <ul class="categoryActions">
+      <li><a href="{$U_HOME}" title="{'Go through the gallery as a visitor'|@translate}"><img src="{$themeconf.icon_dir}/home.png" class="button" alt="{'home'|@translate}"/></a></li>
+    </ul>
+    <h2>{'Password forgotten'|@translate}</h2>
+  </div>
+
+  {if count($errors)}
+  <div class="errors">
+    <ul>
+      {foreach from=$errors item=error}
+      <li>{$error}</li>
+      {/foreach}
+    </ul>
+  </div>
+  {/if}
+
+  {if count($infos)}
+  <div class="infos">
+    <ul>
+      {foreach from=$infos item=info}
+      <li>{$info}</li>
+      {/foreach}
+    </ul>
+  </div>
+  {/if}
+
+<form action="{$F_ACTION}" method="post" class="properties">
+  <fieldset>
+    <legend>{'Retrieve password'|@translate}</legend>
+
+    <ul>
+      <li>
+        <span class="property">
+          <label for="mail_address">{'Email address'|@translate}</label>
+        </span>
+        <input class="login" type="text" name="mail_address" id="mail_address" size="40" maxlength="40" >
+      </li>
+      <li>
+        <span class="property">
+          <label for="no_mail_address">{'No email address'|@translate}</label>
+        </span>
+        <input type="checkbox" id="no_mail_address" name="no_mail_address" value="1">
+      </li>
+    </ul>
+  </fieldset>
+
+  <p><input class="submit" type="submit" name="submit" value="{'Send new password'|@translate}"></p>
+</form>
+
+</div> <!-- content -->
Index: /tags/2.0.2/template/yoga/picture.css
===================================================================
--- /tags/2.0.2/template/yoga/picture.css	(revision 3278)
+++ /tags/2.0.2/template/yoga/picture.css	(revision 3278)
@@ -0,0 +1,103 @@
+/* $Id$ */
+#imageHeaderBar {
+	padding-top: 2px;
+	padding-bottom: 2px;
+	margin-top: 4px;
+	overflow: hidden;
+	width: 100%;
+}
+
+#imageHeaderBar .browsePath {
+	float: left;
+	margin-left: 10px;
+}
+
+#imageHeaderBar .imageNumber {
+	float: right;
+	margin-right: 10px;
+}
+
+#imageHeaderBar H2 {
+	text-align: center;
+	padding: 0;
+	clear: both;
+}
+
+#imageToolBar {
+	text-align: center;
+	position: relative;
+	clear: both;
+	margin-bottom: 4px;
+	padding: 0;
+	height: 28px;
+}
+
+#imageToolBar A, #imageToolBar IMG {
+	display: block;
+	border: none;
+	margin: 0; padding: 0;
+}
+#imageToolBar A { width: 48px; }
+#imageToolBar IMG { margin: 2px auto; }
+#imageToolBar .randomButtons A { float: left; }
+#imageToolBar .navButtons    A { float: right; }
+
+#theImage {
+	clear: left;
+	text-align: center;
+}
+
+#theImage>IMG {
+	display: block;
+	margin: 0 auto;
+	border: none;
+}
+
+#linkPrev {
+	float: left;
+	margin-right: 10px;
+	margin-left: 5px;
+}
+
+#linkNext {
+	float: right;
+	margin-right: 5px;
+	margin-left: 10px;
+}
+
+TABLE.infoTable .label {
+	font-weight: bold;
+	text-align: right;
+	padding-right: 0.5em;
+}
+
+TABLE.infoTable TD.value UL {
+	margin: 0;
+	padding: 0 0 0 1.5em;
+	list-style-type: square;
+}
+
+.thumbnailCategories LI { list-style: none; }
+
+.rateButton, .rateButtonSelected, .rateButtonStarFull, .rateButtonStarEmpty  {
+	padding:0;
+	border:0;
+}
+
+.rateButton, .rateButtonStarFull, .rateButtonStarEmpty {
+	cursor: pointer;
+}
+
+.rateButtonSelected {
+	font-weight:bold;
+	font-size:120%;
+}
+
+.rateButtonStarFull {
+	background: url('icon/rating-stars.gif') no-repeat scroll; background-position:-16px center; width:16px;
+}
+
+.rateButtonStarEmpty {
+	background: url('icon/rating-stars.gif') no-repeat scroll; background-position:0 center; width:16px;
+}
+
Index: /tags/2.0.2/template/yoga/picture.tpl
===================================================================
--- /tags/2.0.2/template/yoga/picture.tpl	(revision 3278)
+++ /tags/2.0.2/template/yoga/picture.tpl	(revision 3278)
@@ -0,0 +1,282 @@
+{* $Id$ *}
+
+{* Example of resizeable *}
+{*
+{include file='include/autosize.inc.tpl'}
+*}
+
+{if isset($errors)}
+<div class="errors">
+  <ul>
+    {foreach from=$errors item=error}
+    <li>{$error}</li>
+    {/foreach}
+  </ul>
+</div>
+{/if}
+
+{if isset($infos)}
+<div class="infos">
+  <ul>
+    {foreach from=$infos item=info}
+    <li>{$info}</li>
+    {/foreach}
+  </ul>
+</div>
+{/if}
+
+{if !empty($PLUGIN_PICTURE_BEFORE)}{$PLUGIN_PICTURE_BEFORE}{/if}
+
+<div id="imageHeaderBar">
+  <div class="browsePath">
+    <a href="{$U_HOME}" rel="home">{'home'|@translate}</a>
+    {if !$IS_HOME}{$LEVEL_SEPARATOR}{$SECTION_TITLE}{/if}
+    {$LEVEL_SEPARATOR}{$current.TITLE}
+  </div>
+  <div class="imageNumber">{$PHOTO}</div>
+  {if $SHOW_PICTURE_NAME_ON_TITLE }
+  <h2>{$current.TITLE}</h2>
+  {/if}
+</div>
+
+<div id="imageToolBar">
+  <div class="randomButtons">
+    {if isset($U_SLIDESHOW_START) }
+      <a href="{$U_SLIDESHOW_START}" title="{'slideshow'|@translate}" rel="nofollow"><img src="{$ROOT_URL}{$themeconf.icon_dir}/start_slideshow.png" class="button" alt="{'slideshow'|@translate}"></a>
+    {/if}
+    {if isset($U_SLIDESHOW_STOP) }
+      <a href="{$U_SLIDESHOW_STOP}" title="{'slideshow_stop'|@translate}" rel="nofollow"><img src="{$ROOT_URL}{$themeconf.icon_dir}/stop_slideshow.png" class="button" alt="{'slideshow_stop'|@translate}"></a>
+    {/if}
+      <a href="{$U_METADATA}" title="{'picture_show_metadata'|@translate}" rel="nofollow"><img src="{$ROOT_URL}{$themeconf.icon_dir}/metadata.png" class="button" alt="metadata" /></a>
+    {if isset($current.U_DOWNLOAD) }
+      <a href="{$current.U_DOWNLOAD}" title="{'download_hint'|@translate}"><img src="{$ROOT_URL}{$themeconf.icon_dir}/save.png" class="button" alt="{'download'|@translate}"></a>
+    {/if}
+    {if isset($PLUGIN_PICTURE_ACTIONS)}{$PLUGIN_PICTURE_ACTIONS}{/if}
+    {if isset($favorite) }
+      <a href="{$favorite.U_FAVORITE}" title="{$favorite.FAVORITE_HINT}"><img src="{$favorite.FAVORITE_IMG}" class="button" alt="favorite" title="{$favorite.FAVORITE_HINT}"></a>
+    {/if}
+    {if !empty($U_SET_AS_REPRESENTATIVE) }
+      <a href="{$U_SET_AS_REPRESENTATIVE}" title="{'set as category representative'|@translate}"><img src="{$ROOT_URL}{$themeconf.icon_dir}/representative.png" class="button" alt="{'representative'|@translate}"></a>
+    {/if}
+    {if isset($U_ADMIN) }
+      <a href="{$U_ADMIN}" title="{'link_info_image'|@translate}"><img src="{$ROOT_URL}{$themeconf.icon_dir}/preferences.png" class="button" alt="{'edit'|@translate}"></a>
+    {/if}
+    {if isset($U_CADDIE) }{*caddie management BEGIN*}
+<script type="text/javascript">
+{literal}function addToCadie(aElement, rootUrl, id)
+{
+if (aElement.disabled) return;
+aElement.disabled=true; 
+var y = new PwgWS(rootUrl);
+
+y.callService(
+  "pwg.caddie.add", {image_id: id} ,
+  {
+    onFailure: function(num, text) { alert(num + " " + text); document.location=aElement.href; },
+    onSuccess: function(result) { aElement.disabled = false; }
+  }
+  );
+}{/literal}
+</script>
+      <a href="{$U_CADDIE}" onclick="addToCadie(this, '{$ROOT_URL|@escape:'javascript'}', {$current.id}); return false;" title="{'add to caddie'|@translate}"><img src="{$ROOT_URL}{$themeconf.icon_dir}/caddie_add.png" class="button" alt="{'caddie'|@translate}"></a>
+    {/if}{*caddie management END*}
+  </div>
+  {include file='picture_nav_buttons.tpl'|@get_extent:'picture_nav_buttons'}
+</div> <!-- imageToolBar -->
+
+<div id="theImage">
+{$ELEMENT_CONTENT}
+
+{if isset($COMMENT_IMG)}
+<p>{$COMMENT_IMG}</p>
+{/if}
+
+{if isset($U_SLIDESHOW_STOP) }
+<p>
+  [ <a href="{$U_SLIDESHOW_STOP}">{'slideshow_stop'|@translate}</a> ]
+</p>
+{/if}
+
+</div>
+
+{if isset($previous) }
+<a class="navThumb" id="linkPrev" href="{$previous.U_IMG}" title="{'previous_page'|@translate} : {$previous.TITLE}" rel="prev">
+  <img src="{$previous.THUMB_SRC}" alt="{$previous.TITLE}">
+</a>
+{/if}
+{if isset($next) }
+<a class="navThumb" id="linkNext" href="{$next.U_IMG}" title="{'next_page'|@translate} : {$next.TITLE}" rel="next">
+  <img src="{$next.THUMB_SRC}" alt="{$next.TITLE}">
+</a>
+{/if}
+
+<table class="infoTable" summary="Some info about this picture">
+  <tr>
+    <td class="label">{'Author'|@translate}</td>
+    <td class="value">{if isset($INFO_AUTHOR)}{$INFO_AUTHOR}{else}{'N/A'|@translate}{/if}</td>
+  </tr>
+  <tr>
+    <td class="label">{'Created on'|@translate}</td>
+    <td class="value">{if isset($INFO_CREATION_DATE)}{$INFO_CREATION_DATE}{else}{'N/A'|@translate}{/if}</td>
+  </tr>
+  <tr>
+    <td class="label">{'Posted on'|@translate}</td>
+    <td class="value">{$INFO_POSTED_DATE}</td>
+  </tr>
+  <tr>
+    <td class="label">{'Dimensions'|@translate}</td>
+    <td class="value">{if isset($INFO_DIMENSIONS)}{$INFO_DIMENSIONS}{else}{'N/A'|@translate}{/if}</td>
+  </tr>
+  <tr>
+    <td class="label">{'File'|@translate}</td>
+    <td class="value">{$INFO_FILE}</td>
+  </tr>
+  <tr>
+    <td class="label">{'Filesize'|@translate}</td>
+    <td class="value">{if isset($INFO_FILESIZE)}{$INFO_FILESIZE}{else}{'N/A'|@translate}{/if}</td>
+  </tr>
+  <tr>
+    <td class="label">{'Tags'|@translate}</td>
+    <td class="value">
+      {if isset($related_tags)}
+        {foreach from=$related_tags item=tag name=tag_loop}{if !$smarty.foreach.tag_loop.first}, {/if}
+        <a href="{$tag.URL}">{$tag.name}</a>{/foreach}
+      {/if}
+    </td>
+  </tr>
+  <tr>
+    <td class="label">{'Categories'|@translate}</td>
+    <td class="value">
+      {if isset($related_categories)}
+      <ul>
+        {foreach from=$related_categories item=cat}
+        <li>{$cat}</li>
+        {/foreach}
+      </ul>
+      {/if}
+    </td>
+  </tr>
+  <tr>
+    <td class="label">{'Visits'|@translate}</td>
+    <td class="value">{$INFO_VISITS}</td>
+  </tr>
+
+{if isset($rate_summary) }
+	<tr>
+		<td class="label">{'Average rate'|@translate}</td>
+		<td class="value" id="ratingSummary">
+		{if $rate_summary.count}
+			{assign var='rate_text' value='%.2f (rated %d times, standard deviation = %.2f)'|@translate }
+			{$pwg->sprintf($rate_text, $rate_summary.average, $rate_summary.count, $rate_summary.std) }
+		{else}
+			{'no_rate'|@translate}
+		{/if}
+		</td>
+	</tr>
+{/if}
+  
+{if isset($rating)}
+	<tr>
+		<td class="label">
+			<span id="updateRate">{if isset($rating.USER_RATE)}{'update_rate'|@translate}{else}{'new_rate'|@translate}{/if}</span>
+		</td>
+		<td class="value">
+			<form action="{$rating.F_ACTION}" method="post" id="rateForm" style="margin:0;">
+			<div>&nbsp;
+			{foreach from=$rating.marks item=mark name=rate_loop}
+			{if !$smarty.foreach.rate_loop.first} | {/if}
+			{if isset($rating.USER_RATE) && $mark==$rating.USER_RATE}
+			  <input type="button" name="rate" value="{$mark}" class="rateButtonSelected" title="{$mark}" />
+			{else}
+			  <input type="submit" name="rate" value="{$mark}" class="rateButton" title="{$mark}" />
+			{/if}
+			{/foreach}
+			<script type="text/javascript" src="{$ROOT_URL}template/{$themeconf.template}/rating.js"></script>
+			<script type="text/javascript">
+			makeNiceRatingForm( {ldelim}rootUrl: '{$ROOT_URL|@escape:"javascript"}', image_id: {$current.id},
+			updateRateText: "{'update_rate'|@translate|@escape:'javascript'}", updateRateElement: document.getElementById("updateRate"),
+			ratingSummaryText: "{'%.2f (rated %d times, standard deviation = %.2f)'|@translate|@escape:'javascript'}", ratingSummaryElement: document.getElementById("ratingSummary") {rdelim} );
+			</script>
+			</div>
+			</form>
+		</td>
+	</tr>
+{/if}
+
+{if isset($available_permission_levels) }
+	<tr>
+		<td class="label">{'Privacy level'|@translate}:</td>
+		<td class="value"> 
+<script type="text/javascript">
+{literal}function setPrivacyLevel(selectElement, rootUrl, id, level)
+{
+selectElement.disabled = true;
+var y = new PwgWS(rootUrl);
+y.callService(
+	"pwg.images.setPrivacyLevel", {image_id: id, level:level} ,
+	{
+		onFailure: function(num, text) { selectElement.disabled = false; alert(num + " " + text); },
+		onSuccess: function(result) { selectElement.disabled = false; }
+	}
+	);
+}{/literal}
+</script>
+	<select onchange="setPrivacyLevel(this, '{$ROOT_URL|@escape:'javascript'}', {$current.id}, this.options[selectedIndex].value)">
+	{foreach from=$available_permission_levels item=level}
+		<option value="{$level}"{if $current.level==$level} selected="selected"{/if}>{$pwg->l10n($pwg->sprintf('Level %d',$level))}</option>
+	{/foreach}
+	</select>
+	</td></tr>
+{/if}
+
+</table>
+
+{if isset($metadata)}
+<table class="infoTable" summary="Some more (technical) info about this picture">
+{foreach from=$metadata item=meta}
+  <tr>
+    <th colspan="2">{$meta.TITLE}</th>
+  </tr>
+  {foreach from=$meta.lines item=value key=label}
+  <tr>
+    <td class="label">{$label}</td>
+    <td class="value">{$value}</td>
+  </tr>
+  {/foreach}
+{/foreach}
+</table>
+{/if}
+
+
+<hr class="separation">
+
+{if isset($COMMENT_COUNT)}
+<div id="comments">
+  {if $COMMENT_COUNT > 0}
+		<h3>{$pwg->l10n_dec('%d comment', '%d comments',$COMMENT_COUNT)}</h3>
+  {/if}
+	{if !empty($COMMENT_NAV_BAR)}
+	<div class="navigationBar">{$COMMENT_NAV_BAR}</div>
+	{/if}
+
+	{if isset($comments)}
+		{include file='comment_list.tpl' comment_separator=true}
+	{/if}
+
+	{if isset($comment_add)}
+	<form  method="post" action="{$comment_add.F_ACTION}" class="filter" id="addComment">
+	<fieldset>
+		<legend>{'comments_add'|@translate}</legend>
+		{if $comment_add.SHOW_AUTHOR}
+		<label>{'upload_author'|@translate}<input type="text" name="author"></label>
+		{/if}
+		<label>{'comment'|@translate}<textarea name="content" id="contentid" rows="5" cols="80">{$comment_add.CONTENT}</textarea></label>
+		<input type="hidden" name="key" value="{$comment_add.KEY}" />
+		<input class="submit" type="submit" value="{'Submit'|@translate}">
+	</fieldset>
+	</form>
+	{/if}
+</div>
+{/if} {*comments*}
+
+{if !empty($PLUGIN_PICTURE_AFTER)}{$PLUGIN_PICTURE_AFTER}{/if}
Index: /tags/2.0.2/template/yoga/picture_content.tpl
===================================================================
--- /tags/2.0.2/template/yoga/picture_content.tpl	(revision 3278)
+++ /tags/2.0.2/template/yoga/picture_content.tpl	(revision 3278)
@@ -0,0 +1,12 @@
+{* $Id$ *}
+{if isset($high) }
+<a href="javascript:phpWGOpenWindow('{$high.U_HIGH}','{$high.UUID}','scrollbars=yes,toolbar=no,status=no,resizable=yes')">
+{/if}
+  <img src="{$SRC_IMG}" style="width:{$WIDTH_IMG}px;height:{$HEIGHT_IMG}px;" alt="{$ALT_IMG}" 
+	{if isset($COMMENT_IMG)}
+		title="{$COMMENT_IMG|@strip_tags:false|@replace:'"':' '}" {else} title="{$current.TITLE|@replace:'"':' '} - {$ALT_IMG}"
+	{/if}>
+{if isset($high) }
+</a>
+  <p>{'picture_high'|@translate}</p>
+{/if}
Index: /tags/2.0.2/template/yoga/picture_nav_buttons.tpl
===================================================================
--- /tags/2.0.2/template/yoga/picture_nav_buttons.tpl	(revision 3278)
+++ /tags/2.0.2/template/yoga/picture_nav_buttons.tpl	(revision 3278)
@@ -0,0 +1,103 @@
+{* $Id$ *}
+  <div class="navButtons">
+  
+{if isset($last)}
+  <a class="navButton" href="{$last.U_IMG}" title="{'last_page'|@translate} : {$last.TITLE}" rel="last"><img src="{$ROOT_URL}{$themeconf.icon_dir}/last.png" class="button" alt="{'last_page'|@translate}"></a>
+{else}
+  <a class="navButton"><img src="{$ROOT_URL}{$themeconf.icon_dir}/last_unactive.png" class="button" alt=""></a>
+{/if}
+  
+{if isset($next)}
+  <a class="navButton" href="{$next.U_IMG}" title="{'next_page'|@translate} : {$next.TITLE}" rel="next"><img src="{$ROOT_URL}{$themeconf.icon_dir}/right.png" class="button" alt="{'next_page'|@translate}"></a>
+{else}
+  <a class="navButton"><img src="{$ROOT_URL}{$themeconf.icon_dir}/right_unactive.png" class="button" alt=""></a>
+{/if}
+
+{if isset($slideshow.U_START_PLAY)}
+  <a class="navButton" href="{$slideshow.U_START_PLAY}" title="{'start_play'|@translate}"><img src="{$ROOT_URL}{$themeconf.icon_dir}/play.png" class="button" alt="{'start_play'|@translate}"></a>
+{/if}
+
+{if isset($slideshow.U_STOP_PLAY)}
+  <a class="navButton" href="{$slideshow.U_STOP_PLAY}" title="{'stop_play'|@translate}"><img src="{$ROOT_URL}{$themeconf.icon_dir}/pause.png" class="button" alt="{'stop_play'|@translate}"></a>
+{/if}
+
+{if isset($U_UP) and !isset($slideshow)}
+  <a class="navButton" href="{$U_UP}" title="{'thumbnails'|@translate}" rel="up"><img src="{$ROOT_URL}{$themeconf.icon_dir}/up.png" class="button" alt="{'thumbnails'|@translate}"></a>
+{/if}
+  
+{if isset($previous)}
+  <a class="navButton" href="{$previous.U_IMG}" title="{'previous_page'|@translate} : {$previous.TITLE}" rel="prev"><img src="{$ROOT_URL}{$themeconf.icon_dir}/left.png" class="button" alt="{'previous_page'|@translate}"></a>
+{else}
+  <a class="navButton"><img src="{$ROOT_URL}{$themeconf.icon_dir}/left_unactive.png" class="button" alt=""></a>
+{/if}
+  
+{if isset($first)}
+  <a class="navButton" href="{$first.U_IMG}" title="{'first_page'|@translate} : {$first.TITLE}" rel="first"><img src="{$ROOT_URL}{$themeconf.icon_dir}/first.png" class="button" alt="{'first_page'|@translate}"></a>
+{else}
+  <a class="navButton"><img src="{$ROOT_URL}{$themeconf.icon_dir}/first_unactive.png" class="button" alt=""></a>
+{/if}
+
+
+{if isset($slideshow.U_START_REPEAT)}
+  <a class="navButton" href="{$slideshow.U_START_REPEAT}" title="{'start_repeat'|@translate}"><img src="{$ROOT_URL}{$themeconf.icon_dir}/start_repeat.png" class="button" alt="{'start_repeat'|@translate}"></a>
+{/if}
+
+{if isset($slideshow.U_STOP_REPEAT)}
+  <a class="navButton" href="{$slideshow.U_STOP_REPEAT}" title="{'stop_repeat'|@translate}"><img src="{$ROOT_URL}{$themeconf.icon_dir}/stop_repeat.png" class="button" alt="{'stop_repeat'|@translate}"></a>
+{/if}
+
+{if isset($slideshow)}
+  {if isset($slideshow.U_DEC_PERIOD)}
+    <a class="navButton" href="{$slideshow.U_DEC_PERIOD}" title="{'dec_period'|@translate}"><img src="{$ROOT_URL}{$themeconf.icon_dir}/dec_period.png" class="button" alt="{'dec_period'|@translate}"></a>
+  {else}
+    <a class="navButton"> <img src="{$ROOT_URL}{$themeconf.icon_dir}/dec_period_unactive.png" class="button" alt=""></a>
+  {/if}
+
+  {if isset($slideshow.U_INC_PERIOD)}
+    <a class="navButton" href="{$slideshow.U_INC_PERIOD}" title="{'inc_period'|@translate}"><img src="{$ROOT_URL}{$themeconf.icon_dir}/inc_period.png" class="button" alt="{'inc_period'|@translate}"></a>
+  {else}
+    <a class="navButton"> <img src="{$ROOT_URL}{$themeconf.icon_dir}/inc_period_unactive.png" class="button" alt=""></a>
+  {/if}
+{/if}
+
+  </div>
+
+<script type="text/javascript">// <![CDATA[
+{literal}
+function keyboardNavigation(e)
+{
+	if(!e) e=window.event;
+	if (e.altKey) return true;
+	var target = e.target || e.srcElement;
+	if (target && target.type) return true; //an input editable element
+	var keyCode=e.keyCode || e.which;
+	var docElem = document.documentElement;
+	switch(keyCode) {
+{/literal}
+{if isset($next)}
+	case 63235: case 39: if (e.ctrlKey || docElem.scrollLeft==docElem.scrollWidth-docElem.clientWidth ){ldelim}window.location="{$next.U_IMG}".replace( "&amp;", "&" ); return false; } break;
+{/if}
+{if isset($previous)}
+	case 63234: case 37: if (e.ctrlKey || docElem.scrollLeft==0){ldelim}window.location="{$previous.U_IMG|@escape:jasvascript}".replace("&amp;","&"); return false; } break;
+{/if}
+{if isset($first)}
+	/*Home*/case 36: if (e.ctrlKey){ldelim}window.location="{$first.U_IMG|@escape:jasvascript}".replace("&amp;","&"); return false; } break;
+{/if}
+{if isset($last)}
+	/*End*/case 35: if (e.ctrlKey){ldelim}window.location="{$last.U_IMG|@escape:jasvascript}".replace("&amp;","&"); return false; } break;
+{/if}
+{if isset($U_UP) and !isset($slideshow)}
+	/*Up*/case 38: if (e.ctrlKey){ldelim}window.location="{$U_UP|@escape:jasvascript}".replace("&amp;","&"); return false; } break;
+{/if}
+
+{if isset($slideshow.U_START_PLAY)}
+	/*Pause*/case 32: {ldelim}window.location="{$slideshow.U_START_PLAY|@escape:jasvascript}".replace("&amp;","&"); return false; } break;
+{/if}
+{if isset($slideshow.U_STOP_PLAY)}
+	/*Play*/case 32: {ldelim}window.location="{$slideshow.U_STOP_PLAY|@escape:jasvascript}".replace("&amp;","&"); return false; } break;
+{/if}
+	}
+	return true;
+}
+document.onkeydown=keyboardNavigation;
+// ]]></script>
Index: /tags/2.0.2/template/yoga/popuphelp.tpl
===================================================================
--- /tags/2.0.2/template/yoga/popuphelp.tpl	(revision 3278)
+++ /tags/2.0.2/template/yoga/popuphelp.tpl	(revision 3278)
@@ -0,0 +1,13 @@
+{* $Id$ *}
+<div id="content" class="content">
+{$HELP_CONTENT}
+</div> <!-- content -->
+
+<ul class="categoryActions">
+	<li>
+		<a href="#" onclick="window.close();" title="{'Close this window'|@translate}">
+			<img src="{$ROOT_URL}{$themeconf.icon_dir}/exit.png" class="button" alt="exit">
+		</a>
+	</li>
+</ul>
+
Index: /tags/2.0.2/template/yoga/print.css
===================================================================
--- /tags/2.0.2/template/yoga/print.css	(revision 3278)
+++ /tags/2.0.2/template/yoga/print.css	(revision 3278)
@@ -0,0 +1,14 @@
+#menubar, .content .navigationBar, UL.categoryActions, .content DIV.calendarViews, .calendarBar,
+#imageToolBar, .navThumb, #addComment {
+    display: none;
+}
+
+BODY {
+    margin: 0;
+    color: #000000;
+    background: #ffffff;
+}
+
+.content {
+    margin: 0;
+}
Index: /tags/2.0.2/template/yoga/profile.tpl
===================================================================
--- /tags/2.0.2/template/yoga/profile.tpl	(revision 3278)
+++ /tags/2.0.2/template/yoga/profile.tpl	(revision 3278)
@@ -0,0 +1,22 @@
+{* $Id$ *}
+<div id="content" class="content">
+
+{if isset($errors)}
+<div class="errors">
+  <ul>
+    {foreach from=$errors item=error}
+    <li>{$error}</li>
+    {/foreach}
+  </ul>
+</div>
+{/if}
+
+  <div class="titrePage">
+    <ul class="categoryActions">
+      <li><a href="{$U_HOME}" title="{'return to homepage'|@translate}"><img src="{$ROOT_URL}{$themeconf.icon_dir}/home.png" class="button" alt="{'home'|@translate}"/></a></li>
+    </ul>
+    <h2>{'Profile'|@translate}</h2>
+  </div>
+
+{$PROFILE_CONTENT}
+</div> <!-- content -->
Index: /tags/2.0.2/template/yoga/profile_content.tpl
===================================================================
--- /tags/2.0.2/template/yoga/profile_content.tpl	(revision 3278)
+++ /tags/2.0.2/template/yoga/profile_content.tpl	(revision 3278)
@@ -0,0 +1,109 @@
+{* $Id$ *}
+<form method="post" name="profile" action="{$F_ACTION}" id="profile" class="properties">
+
+  <fieldset>
+    <legend>{'Registration'|@translate}</legend>
+    <input type="hidden" name="redirect" value="{$REDIRECT}" />
+    <ul>
+      <li>
+        <span class="property">{'Username'|@translate}</span>
+        {$USERNAME}
+      </li>
+{if not $SPECIAL_USER} {* can modify password + email*}
+      <li>
+        <span class="property">
+          <label for="mail_address">{'Email address'|@translate}</label>
+        </span>
+        <input type="text" name="mail_address" id="mail_address" value="{$EMAIL}">
+      </li>
+{if not $IN_ADMIN} {* admins do not need old password*}
+      <li>
+        <span class="property">
+          <label for="password">{'Password'|@translate}</label>
+        </span>
+        <input type="password" name="password" id="password" value="">
+      </li>
+{/if}
+      <li>
+        <span class="property">
+          <label for="use_new_pwd">{'new_password'|@translate}</label>
+        </span>
+        <input type="password" name="use_new_pwd" id="use_new_pwd" value="">
+      </li>
+      <li>
+        <span class="property">
+          <label for="passwordConf">{'Confirm Password'|@translate}</label>
+        </span>
+        <input type="password" name="passwordConf" id="passwordConf" value="">
+      </li>
+    </ul>
+{/if}
+  </fieldset>
+
+  <fieldset>
+    <legend>{'preferences'|@translate}</legend>
+
+    <ul>
+      <li>
+        <span class="property">
+          <label for="nb_image_line">{'nb_image_per_row'|@translate}</label>
+        </span>
+        <input type="text" size="3" maxlength="2" name="nb_image_line" id="nb_image_line" value="{$NB_IMAGE_LINE}">
+      </li>
+      <li>
+        <span class="property">
+          <label for="nb_line_page">{'nb_row_per_page'|@translate}</label>
+        </span>
+        <input type="text" size="3" maxlength="2" name="nb_line_page" id="nb_line_page" value="{$NB_ROW_PAGE}" >
+      </li>
+      <li>
+        <span class="property">
+          <label for="template">{'theme'|@translate}</label>
+        </span>
+        {html_options name=template options=$template_options selected=$template_selection}
+      </li>
+      <li>
+        <span class="property">
+          <label for="language">{'language'|@translate}</label>
+        </span>
+        {html_options name=language options=$language_options selected=$language_selection}
+      </li>
+      <li>
+        <span class="property">
+          <label for="recent_period">{'recent_period'|@translate}</label>
+        </span>
+        <input type="text" size="3" maxlength="2" name="recent_period" id="recent_period" value="{$RECENT_PERIOD}">
+      </li>
+      <li>
+        <span class="property">{'auto_expand'|@translate}</span>
+        {html_radios name='expand' options=$radio_options selected=$EXPAND}
+      </li>
+      <li>
+        <span class="property">{'show_nb_comments'|@translate}</span>
+        {html_radios name='show_nb_comments' options=$radio_options selected=$NB_COMMENTS}
+      </li>
+      <li>
+        <span class="property">{'show_nb_hits'|@translate}</span>
+        {html_radios name='show_nb_hits' options=$radio_options selected=$NB_HITS}
+      </li>
+      <li>
+        <span class="property">
+          <label for="maxwidth">{'maxwidth'|@translate}</label>
+        </span>
+        <input type="text" size="4" maxlength="4" name="maxwidth" id="maxwidth" value="{$MAXWIDTH}">
+      </li>
+      <li>
+        <span class="property">
+          <label for="maxheight">{'maxheight'|@translate}</label>
+        </span>
+        <input type="text" size="4" maxlength="4" name="maxheight" id="maxheight" value="{$MAXHEIGHT}">
+      </li>
+    </ul>
+  </fieldset>
+
+  <p class="bottomButtons">
+    <input class="submit" type="submit" name="validate" value="{'Submit'|@translate}">
+    <input class="submit" type="reset" name="reset" value="{'Reset'|@translate}">
+  </p>
+
+</form>
Index: /tags/2.0.2/template/yoga/rating.js
===================================================================
--- /tags/2.0.2/template/yoga/rating.js	(revision 3278)
+++ /tags/2.0.2/template/yoga/rating.js	(revision 3278)
@@ -0,0 +1,100 @@
+var gRatingOptions, gRatingButtons, gUserRating;
+
+function makeNiceRatingForm(options)
+{
+	gRatingOptions = options || {};
+	var form = document.getElementById('rateForm');
+	if (!form) return; //? template changed
+
+	gRatingButtons = form.getElementsByTagName('input');
+	gUserRating = "";
+	for (var i=0; i<gRatingButtons.length; i++)
+	{
+		if ( gRatingButtons[i].type=="button" )
+		{
+			gUserRating = gRatingButtons[i].value;
+			break;
+		}
+	}
+
+	for (var i=0; i<gRatingButtons.length; i++)
+	{
+		var rateButton = gRatingButtons[i];
+		rateButton.initialRateValue = rateButton.value; // save it as a property
+		try { rateButton.type = "button"; } catch (e){}// avoid normal submit (use ajax); not working in IE6
+
+		if (navigator.userAgent.indexOf('AppleWebKit/') == -1 ) rateButton.value = ""; //hide the text IE/Opera - breaks safari
+		with (rateButton.style)
+		{
+			textIndent = "-50px"; //hide the text FF
+			marginLeft = marginRight = 0;
+		}
+
+		if (i!=gRatingButtons.length-1 && rateButton.nextSibling.nodeType == 3 /*TEXT_NODE*/)
+			rateButton.parentNode.removeChild(rateButton.nextSibling);
+		if (i>0 && rateButton.previousSibling.nodeType == 3 /*TEXT_NODE*/)
+			rateButton.parentNode.removeChild(rateButton.previousSibling);
+
+		if(window.addEventListener){ // Mozilla, Netscape, Firefox
+			rateButton.addEventListener("click", updateRating, false );
+			rateButton.addEventListener("mouseout", resetRatingStarDisplay, false );
+			rateButton.addEventListener("mouseover", updateRatingStarDisplayEvt, false );
+		}
+		else if(window.attachEvent) { // IE
+			rateButton.attachEvent("onclick", updateRating);
+			rateButton.attachEvent("onmouseout", resetRatingStarDisplay);
+			rateButton.attachEvent("onmouseover", updateRatingStarDisplayEvt);
+		}
+	}
+	resetRatingStarDisplay();
+}
+
+function resetRatingStarDisplay()
+{
+	updateRatingStarDisplay( gUserRating );
+}
+
+function updateRatingStarDisplay(userRating)
+{
+	for (var i=0; i<gRatingButtons.length; i++)
+		gRatingButtons[i].className = (userRating!=="" && userRating>=gRatingButtons[i].initialRateValue ) ? "rateButtonStarFull" : "rateButtonStarEmpty";
+}
+
+function updateRatingStarDisplayEvt(e)
+{
+	updateRatingStarDisplay(
+		e.target ? e.target.initialRateValue : e.srcElement.initialRateValue);
+}
+
+function updateRating(e)
+{
+	var rateButton = e.target || e.srcElement;
+	if (rateButton.initialRateValue == gUserRating)
+		return false; //nothing to do
+
+	for (var i=0; i<gRatingButtons.length; i++) gRatingButtons[i].disabled=true;
+	var y = new PwgWS(gRatingOptions.rootUrl);
+	y.callService(
+		"pwg.images.rate", {image_id: gRatingOptions.image_id, rate: rateButton.initialRateValue } ,
+		{
+			onFailure: function(num, text) {
+				alert(num + " " + text);
+				document.location = rateButton.form.action + "&rate="+rateButton.initialRateValue;
+			},
+			onSuccess: function(result) {
+				gUserRating = rateButton.initialRateValue;
+				for (var i=0; i<gRatingButtons.length; i++) gRatingButtons[i].disabled=false;
+				if (gRatingOptions.updateRateElement) gRatingOptions.updateRateElement.innerHTML = gRatingOptions.updateRateText;
+				if (gRatingOptions.ratingSummaryElement)
+				{
+					var t = gRatingOptions.ratingSummaryText;
+					var args =[result.average, result.count, result.stdev], idx = 0, rexp = new RegExp( /%\.?\d*[sdf]/ );
+					_xxx = t.match( rexp );
+					while (idx<args.length) t=t.replace(rexp, args[idx++]);
+					gRatingOptions.ratingSummaryElement.innerHTML = t;
+				}
+			}
+		}
+	);
+	return false;
+}
Index: /tags/2.0.2/template/yoga/redirect.tpl
===================================================================
--- /tags/2.0.2/template/yoga/redirect.tpl	(revision 3278)
+++ /tags/2.0.2/template/yoga/redirect.tpl	(revision 3278)
@@ -0,0 +1,14 @@
+{* $Id$ *}
+{html_head}
+<style type="text/css">#the_page {ldelim}text-align:center;} </style>
+{/html_head}
+
+<div>
+	{$REDIRECT_MSG}
+</div>
+
+<p style="margin: 2em">
+	<a href="{$page_refresh.U_REFRESH}">
+		{'click_to_redirect'|@translate}
+	</a>
+</p>
Index: /tags/2.0.2/template/yoga/register.tpl
===================================================================
--- /tags/2.0.2/template/yoga/register.tpl	(revision 3278)
+++ /tags/2.0.2/template/yoga/register.tpl	(revision 3278)
@@ -0,0 +1,69 @@
+{* $Id$ *}
+<div id="registerPage">
+
+<div id="content" class="content">
+
+  <div class="titrePage">
+    <ul class="categoryActions">
+      <li><a href="{$U_HOME}" title="{'return to homepage'|@translate}"><img src="{$ROOT_URL}{$themeconf.icon_dir}/home.png" class="button" alt="{'home'|@translate}"/></a></li>
+    </ul>
+    <h2>{'Registration'|@translate}</h2>
+  </div>
+
+{if isset($errors)}
+  <div class="errors">
+    <ul>
+      {foreach from=$errors item=error}
+      <li>{$error}</li>
+      {/foreach}
+    </ul>
+  </div>
+{/if}
+
+<form method="post" action="{$F_ACTION}" class="properties" name="register_form">
+  <fieldset>
+    <legend>{'Enter your personnal informations'|@translate}</legend>
+
+    <ul>
+      <li>
+        <span class="property">
+          <label for="login">* {'Username'|@translate}</label>
+        </span>
+        <input type="text" name="login" id="login" value="{$F_LOGIN}" >
+      </li>
+      <li>
+        <span class="property">
+          <label for="password">* {'Password'|@translate}</label>
+        </span>
+        <input type="password" name="password" id="password" >
+      </li>
+      <li>
+        <span class="property">
+          <label for="password_conf">* {'Confirm Password'|@translate}</label>
+        </span>
+        <input type="password" name="password_conf" id="password_conf" >
+      </li>
+      <li>
+        <span class="property">
+          <label for="mail_address">{'Mail address'|@translate}</label>
+        </span>
+        <input type="text" name="mail_address" id="mail_address" value="{$F_EMAIL}" >
+        ({'useful when password forgotten'|@translate})
+      </li>
+    </ul>
+
+  </fieldset>
+
+  <p class="bottomButtons">
+    <input class="submit" type="submit" name="submit" value="{'Register'|@translate}">
+    <input class="submit" type="reset" value="{'Reset'|@translate}">
+  </p>
+
+</form>
+
+<script type="text/javascript"><!--
+document.register_form.login.focus();
+//--></script>
+
+</div> <!-- content -->
+</div> <!-- registerPage -->
Index: /tags/2.0.2/template/yoga/search.tpl
===================================================================
--- /tags/2.0.2/template/yoga/search.tpl	(revision 3278)
+++ /tags/2.0.2/template/yoga/search.tpl	(revision 3278)
@@ -0,0 +1,147 @@
+{* $Id$ *}
+
+{* Example of resizeable *}
+{*
+{include file='include/resize.inc.tpl'}
+*}
+
+{* Example of datepicker *}
+{*
+{include file='include/datepicker.inc.tpl'}
+
+{literal}
+<script type="text/javascript">
+  pwg_initialization_datepicker("#start_day", "#start_month", "#start_year", "#start_linked_date", null, null, "#end_linked_date");
+  pwg_initialization_datepicker("#end_day", "#end_month", "#end_year", "#end_linked_date", null, "#start_linked_date", null);
+ jQuery().ready(function(){ $(".date_today").hide(); });
+</script>
+{/literal}
+*}
+
+<div id="content" class="content">
+
+  <div class="titrePage">
+    <ul class="categoryActions">
+      <li><a href="{$U_HELP}" onclick="popuphelp(this.href); return false;" title="{'Help'|@translate}" rel="nofollow"><img src="{$ROOT_URL}{$themeconf.icon_dir}/help.png" class="button" alt="(?)"></a></li>
+      <li><a href="{$U_HOME}" title="{'return to homepage'|@translate}" rel="home"><img src="{$ROOT_URL}{$themeconf.icon_dir}/home.png" class="button" alt="{'home'|@translate}"/></a></li>
+    </ul>
+    <h2>{'Search'|@translate}</h2>
+  </div>
+
+{if isset($errors) }
+<div class="errors">
+  <ul>
+    {foreach from=$errors item=error}
+    <li>{$error}</li>
+    {/foreach}
+  </ul>
+</div>
+{/if}
+
+<form class="filter" method="post" name="search" action="{$F_SEARCH_ACTION}">
+<fieldset>
+  <legend>{'Filter'|@translate}</legend>
+  <label>{'search_keywords'|@translate}
+    <input type="text" style="width: 300px" name="search_allwords" size="30"  />
+  </label>
+  <ul>
+    <li><label>
+      <input type="radio" name="mode" value="AND" checked="checked" />{'search_mode_and'|@translate}
+    </label></li>
+    <li><label>
+      <input type="radio" name="mode" value="OR" />{'search_mode_or'|@translate}
+    </label></li>
+  </ul>
+  <label>{'search_author'|@translate}
+    <input type="text" style="width: 300px" name="search_author" size="30"  />
+  </label>
+</fieldset>
+
+{if isset($TAG_SELECTION)}
+<fieldset>
+  <legend>{'Search tags'|@translate}</legend>
+  {$TAG_SELECTION}
+  <label><span><input type="radio" name="tag_mode" value="AND" checked="checked" /> {'All tags'|@translate}</span></label>
+  <label><span><input type="radio" name="tag_mode" value="OR" /> {'Any tag'|@translate}</span></label>
+</fieldset>
+{/if}
+
+<fieldset>
+  <legend>{'search_date'|@translate}</legend>
+  <ul>
+    <li><label>{'search_date_type'|@translate}</label></li>
+    <li><label>
+      <input type="radio" name="date_type" value="date_creation" checked="checked" />{'Creation date'|@translate}
+    </label></li>
+    <li><label>
+      <input type="radio" name="date_type" value="date_available" />{'Post date'|@translate}
+    </label></li>
+  </ul>
+  <ul>
+    <li><label>{'search_date_from'|@translate}</label></li>
+    <li>
+      <select id="start_day" name="start_day">
+          <option value="0">--</option>
+        {section name=day start=1 loop=32}
+          <option value="{$smarty.section.day.index}" {if $smarty.section.day.index==$START_DAY_SELECTED}selected="selected"{/if}>{$smarty.section.day.index}</option>
+        {/section}
+      </select>
+      <select id="start_month" name="start_month">
+        {html_options options=$month_list selected=$START_MONTH_SELECTED}
+      </select>
+      <input id="start_year" name="start_year" type="text" size="4" maxlength="4" >
+      <input id="start_linked_date" name="start_linked_date" type="hidden" size="10" disabled="disabled"/>
+    </li>
+    <li>
+      <a class="date_today" href="#" onClick="document.search.start_day.value={$smarty.now|date_format:"%d"};document.search.start_month.value={$smarty.now|date_format:"%m"};document.search.start_year.value={$smarty.now|date_format:"%Y"};return false;">{'today'|@translate}</a>
+    </li>
+  </ul>
+  <ul>
+    <li><label>{'search_date_to'|@translate}</label></li>
+    <li>
+      <select id="end_day" name="end_day">
+          <option value="0">--</option>
+        {section name=day start=1 loop=32}
+          <option value="{$smarty.section.day.index}" {if $smarty.section.day.index==$END_DAY_SELECTED}selected="selected"{/if}>{$smarty.section.day.index}</option>
+        {/section}
+      </select>
+      <select id="end_month" name="end_month">
+        {html_options options=$month_list selected=$END_MONTH_SELECTED}
+      </select>
+      <input id="end_year" name="end_year" type="text" size="4" maxlength="4" >
+      <input id="end_linked_date" name="end_linked_date" type="hidden" size="10" disabled="disabled"/>
+    </li>
+    <li>
+      <a class="date_today" href="#" onClick="document.search.end_day.value={$smarty.now|date_format:"%d"};document.search.end_month.value={$smarty.now|date_format:"%m"};document.search.end_year.value={$smarty.now|date_format:"%Y"};return false;">{'today'|@translate}</a>
+    </li>
+  </ul>
+</fieldset>
+
+<fieldset>
+  <legend>{'search_options'|@translate}</legend>
+  <label>{'search_categories'|@translate}
+    <select class="categoryList" name="cat[]" multiple="multiple" >
+      {html_options options=$category_options selected=$category_options_selected}
+    </select>
+  </label>
+  <ul>
+    <li><label>{'search_subcats_included'|@translate}</label></li>
+    <li><label>
+      <input type="radio" name="subcats-included" value="1" checked="checked" />{'Yes'|@translate}
+    </label></li>
+    <li><label>
+      <input type="radio" name="subcats-included" value="0" />{'No'|@translate}
+    </label></li>
+  </ul>
+</fieldset>
+<p>
+  <input class="submit" type="submit" name="submit" value="{'Submit'|@translate}" />
+  <input class="submit" type="reset" value="{'Reset'|@translate}" />
+</p>
+</form>
+
+<script type="text/javascript"><!--
+document.search.search_allwords.focus();
+//--></script>
+
+</div> <!-- content -->
Index: /tags/2.0.2/template/yoga/search_rules.tpl
===================================================================
--- /tags/2.0.2/template/yoga/search_rules.tpl	(revision 3278)
+++ /tags/2.0.2/template/yoga/search_rules.tpl	(revision 3278)
@@ -0,0 +1,58 @@
+{* $Id$ *}
+<div id="content" class="content">
+<h2>{'Search rules'|@translate}</h2>
+
+{if isset($INTRODUCTION) }
+<p>{$INTRODUCTION}</p>
+{/if}
+
+<ul>
+
+  {if isset($search_words) }
+  {foreach from=$search_words item=v}
+  <li>{$v}</li>
+  {/foreach}
+  {/if}
+
+  {if isset($SEARCH_TAGS_MODE) }
+  <li>
+    <p>{if 'AND'==$SEARCH_TAGS_MODE}{'All tags must match'|@translate}{else}{'At least one tag must match'|@translate}{/if}</p>
+    <ul>
+      {foreach from=$search_tags item=v}
+      <li>{$v}</li>
+      {/foreach}
+    </ul>
+  </li>
+  {/if}
+  
+  {if isset($DATE_CREATION) }
+  <li>{$DATE_CREATION}</li>
+  {/if}
+
+  {if isset($DATE_AVAILABLE) }
+  <li>{$DATE_AVAILABLE}</li>
+  {/if}
+
+  {if isset($search_categories) }
+  <li>
+    <p>{'Categories'|@translate}</p>
+
+    <ul>
+      {foreach from=$search_categories item=v}
+      <li>{$v}</li>
+      {/foreach}
+    </ul>
+  </li>
+  {/if}
+  
+</ul>
+
+</div> <!-- content -->
+
+<ul class="categoryActions">
+	<li>
+		<a href="#" onclick="window.close();" title="{'Close this window'|@translate}">
+			<img src="{$ROOT_URL}{$themeconf.icon_dir}/exit.png" class="button" alt="exit">
+		</a>
+	</li>
+</ul>
Index: /tags/2.0.2/template/yoga/slideshow.tpl
===================================================================
--- /tags/2.0.2/template/yoga/slideshow.tpl	(revision 3278)
+++ /tags/2.0.2/template/yoga/slideshow.tpl	(revision 3278)
@@ -0,0 +1,23 @@
+{* $Id$ *}
+<div id="imageHeaderBar">
+  <div class="browsePath">
+    {if isset($U_SLIDESHOW_STOP) }
+    [ <a href="{$U_SLIDESHOW_STOP}">{'slideshow_stop'|@translate}</a> ]
+    {/if}
+  </div>
+  <div class="imageNumber">{$PHOTO}</div>
+  {if $SHOW_PICTURE_NAME_ON_TITLE }
+  <h2 class="showtitle">{$current.TITLE}</h2>
+  {/if}
+</div>
+
+<div id="imageToolBar">
+  {include file='picture_nav_buttons.tpl'|@get_extent:'picture_nav_buttons'}
+</div>
+
+<div id="theImage">
+  {$ELEMENT_CONTENT}
+  {if isset($COMMENT_IMG)}
+  <p class="showlegend">{$COMMENT_IMG}</p>
+  {/if}
+</div>
Index: /tags/2.0.2/template/yoga/tags.tpl
===================================================================
--- /tags/2.0.2/template/yoga/tags.tpl	(revision 3278)
+++ /tags/2.0.2/template/yoga/tags.tpl	(revision 3278)
@@ -0,0 +1,55 @@
+{* $Id$ *}
+<div id="content" class="content">
+
+	<div class="titrePage">
+		<ul class="categoryActions">
+		{if $display_mode == 'letters'}
+			<li><a href="{$U_CLOUD}" title="{'show tag cloud'|@translate}" rel="nofollow"><img src="{$themeconf.icon_dir}/tag_cloud.png" class="button" alt="{'cloud'|@translate}"/></a></li>
+		{/if}
+
+		{if $display_mode == 'cloud'}
+			<li><a href="{$U_LETTERS}" title="{'group by letters'|@translate}" rel="nofollow"><img src="{$themeconf.icon_dir}/tag_letters.png" class="button" alt="{'letters'|@translate}"/></a></li>
+		{/if}
+
+			<li><a href="{$U_HOME}" title="{'return to homepage'|@translate}"><img src="{$themeconf.icon_dir}/home.png" class="button" alt="{'home'|@translate}"/></a></li>
+		</ul>
+		<h2>{'Tags'|@translate}</h2>
+  </div>
+
+{if isset($tags)}
+	{if $display_mode == 'cloud'}
+	<div id="fullTagCloud">
+		{foreach from=$tags item=tag}
+		<span><a href="{$tag.URL}" class="tagLevel{$tag.level}" title="{$tag.counter}">{$tag.name}</a></span>
+		{/foreach}
+	</div>
+	{/if}
+
+  {if $display_mode == 'letters'}
+  <table>
+    <tr>
+      <td valign="top">
+    {foreach from=$letters item=letter}
+  <fieldset class="tagLetter">
+    <legend class="tagLetterLegend">{$letter.TITLE}</legend>
+    <table class="tagLetterContent">
+      {foreach from=$letter.tags item=tag}
+      <tr class="tagLine">
+        <td><a href="{$tag.URL}">{$tag.name}</a></td>
+        <td class="nbEntries">{$pwg->l10n_dec('%d element', '%d elements', $tag.counter)}</td>
+      </tr>
+      {/foreach}
+    </table>
+  </fieldset>
+      {if isset($letter.CHANGE_COLUMN) }
+      </td>
+      <td valign="top">
+      {/if}
+    {/foreach}
+      </td>
+    </tr>
+  </table>
+  {/if}
+{/if}
+
+</div> <!-- content -->
Index: /tags/2.0.2/template/yoga/theme/Sylvia/icon/index.php
===================================================================
--- /tags/2.0.2/template/yoga/theme/Sylvia/icon/index.php	(revision 3278)
+++ /tags/2.0.2/template/yoga/theme/Sylvia/icon/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/template/yoga/theme/Sylvia/icon/mimetypes/index.php
===================================================================
--- /tags/2.0.2/template/yoga/theme/Sylvia/icon/mimetypes/index.php	(revision 3278)
+++ /tags/2.0.2/template/yoga/theme/Sylvia/icon/mimetypes/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/template/yoga/theme/Sylvia/index.php
===================================================================
--- /tags/2.0.2/template/yoga/theme/Sylvia/index.php	(revision 3278)
+++ /tags/2.0.2/template/yoga/theme/Sylvia/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/template/yoga/theme/Sylvia/mail-css.tpl
===================================================================
--- /tags/2.0.2/template/yoga/theme/Sylvia/mail-css.tpl	(revision 3278)
+++ /tags/2.0.2/template/yoga/theme/Sylvia/mail-css.tpl	(revision 3278)
@@ -0,0 +1,16 @@
+{* $Id$ *}
+/* Theme Sylvia mail css */
+
+body {ldelim} background-color:#111; color:#666;}
+#the_page {ldelim} }
+#content {ldelim} }
+#copyright {ldelim} background: transparent url({$ROOT_URL}template/{$themeconf.template}/mail/text/html/images/footer-bg.jpg) no-repeat scroll left bottom;
+min-height: 220px; height: 220px; width: 100%; min-width: 100%; padding: 10px 100px 30px 100px; }
+h2 {ldelim} color:#f70;background: transparent url({$ROOT_URL}template/{$themeconf.template}/theme/{$themeconf.theme}/images/fillet.gif) repeat-x scroll left bottom; padding-bottom: 5px;}
+img {ldelim} margin: 16px; border: 16px solid #444; -moz-border-radius: 4px; border-radius: 4px 4px; }
+img:hover {ldelim} padding: 15px; border: 0; background-color:#222;-moz-border-radius: 4px; border-radius: 4px 4px; }
+a {ldelim} color: #f70; background-color: transparent; border:0; text-decoration: none;}
+a:hover {ldelim} color: #F33; border-bottom: 1px solid #FF3363;}
+a.thumblnk:hover {ldelim} border:0;}
+a.Piwigo {ldelim} font-family: verdana, arial, helvetica, sans-serif; color : #F33; text-decoration: none; border: 0; }
+a.Piwigo:hover {ldelim} border-bottom: 1px solid #FF3363; }
Index: /tags/2.0.2/template/yoga/theme/Sylvia/theme-ie.css
===================================================================
--- /tags/2.0.2/template/yoga/theme/Sylvia/theme-ie.css	(revision 3278)
+++ /tags/2.0.2/template/yoga/theme/Sylvia/theme-ie.css	(revision 3278)
@@ -0,0 +1,12 @@
+#content .thumbnailCategory div.description .text {
+	scrollbar-face-color:#222;
+	scrollbar-shadow-color:#444;
+	scrollbar-highlight-color:#000;
+	scrollbar-darkshadow-color:#333;
+	scrollbar-track-color:#111;
+	scrollbar-arrow-color:#f70;
+}
+
+#debug { word-wrap:break-word; }
+/* IE6... Hacks: */
+/*\*/ * html #menubar #mbIdentification .button { margin-right:25px; } /* */ 
Index: /tags/2.0.2/template/yoga/theme/Sylvia/theme.css
===================================================================
--- /tags/2.0.2/template/yoga/theme/Sylvia/theme.css	(revision 3278)
+++ /tags/2.0.2/template/yoga/theme/Sylvia/theme.css	(revision 3278)
@@ -0,0 +1,436 @@
+/* $Id$ */
+.content div.thumbnailCategory div.illustration { 
+	width:165px !important; /* Usable range 162px-360px , optimal : Thumbnail width + 40px */ 
+}
+.content div.thumbnailCategory { 
+	height: 180px !important; /* Usable range 172px-250px , optimal : Thumbnail height + 30px */ 
+}
+.content div.thumbnailCategory div.description .text { 
+	height: 130px !important; /* -42px than previous one */ 
+}
+#comments div.thumbnailCategory div.illustration { 
+	width:220px !important; /* Usable range 219px-360px , optimal : Thumbnail width + 95px */ 
+}
+#comments .thumbnailCategories hr {display:none;}
+#comments form.filter input[type="submit"] { margin-top:1.8em; }
+/*  Sylvia Theme is close to the Roma Admin theme */
+BODY, H1, H3, DT, INPUT.rateButtonSelected, H2, #menubar DT { 
+	color:#666; 
+}
+#imageHeaderBar, #imageToolBar A:hover { 
+	background-color: transparent; 
+}
+BODY { 
+	background:#111 url(images/bottom-left-bg.jpg) no-repeat fixed left bottom;
+	margin:0; 
+	min-height: 100%; 
+	height: 100%; 
+	padding:0; 
+}
+#the_page { 
+	background:transparent url(images/top-left-bg.jpg) no-repeat scroll left top;
+	left:0; 
+	margin:0; 
+	padding:0; 
+	position:absolute; 
+	top:0; 
+	z-index:0; 
+	width: 100%; 
+	min-width: 100%; 
+}
+#theHeader { 
+	min-height:110px;
+	height:110px; 
+}
+#mbIdentification p, .totalImages { 
+	color:#333; 
+}
+.header_msgs { 
+	background:transparent url(images/header_msgs-bg.gif) repeat scroll left top;
+	border:0; 
+	color:#333; 
+	font-size:24px; 
+	left:0; 
+	margin:0; 
+	padding:10px 0 6px 0; 
+	position:absolute;
+	text-align:center; 
+	top:0; 
+	width:100%; 
+	z-index:99; 
+}
+.header_notes {
+	background:transparent url(images/header_msgs-bg.gif) repeat scroll left top;
+	border:0 none;
+	color:#333;
+	font-size:16px;
+	margin:0;
+	padding:0;
+	position:absolute;
+	top:0;
+	width:100%;
+	z-index:99;
+}
+#menubar DL { 
+	background:transparent url(images/menuBox_top.gif) no-repeat scroll left top;
+	margin:0 0 5px 40px; 
+	padding:0; 
+	width: 231px; 
+	min-width: 231px; 
+	border: 0; 
+	min-height: 32px; 
+	overflow-x: hidden;
+}
+#imageHeaderBar H2 { 
+	border: 0; 
+}
+#menubar DT { 
+	background-color:#111; 
+	border:0; 
+	display:inline; 
+	margin-left:8px; 
+	text-align:left; 
+}
+#menubar DD { 
+	background:transparent url(images/menuBox_bottom.gif) no-repeat scroll left bottom;
+	margin:14px 0 0 0; 
+	padding:0 0 22px; 
+	width: 231px; 
+	min-width: 231px; 
+	border: 0; 
+	overflow-x: hidden;
+}
+#menubar DD P {
+  background:transparent url(images/menuBox_sides.gif) repeat-y scroll left bottom; 
+  padding: 2px 16px 0; 
+  margin: 0;
+}
+#menubar UL, #menubar #mbCategories p, #menubar .illustration  { 
+	background:transparent url(images/menuBox_sides.gif) repeat-y scroll left bottom;
+	margin:0; 
+}
+#menubar DT A { 
+	font-size: 100%; 
+}
+#menubar UL { 
+	color:#333; 
+	font-size: 16px; 
+	line-height: 15px; 
+}
+#menubar LI { 
+	padding-left: 12px; 
+}
+#menubar LI UL {
+  background: transparent url(images/transparent.gif);
+}
+#menubar A, .menuInfoCat { 
+	font-size: 13px; 
+}
+#menubar form { 
+	background:transparent url(images/menuBox_sides.gif) repeat-y scroll left bottom; 
+	margin:0; 
+}
+#menubar DL#mbIdentification { 
+	background:transparent url(images/menuId_top.gif) no-repeat scroll left top !important;
+}
+#menubar #mbIdentification DD { 
+	background:transparent url(images/menuId_bottom.gif) no-repeat scroll left bottom; 
+}
+#menubar #mbIdentification UL, #menubar #mbIdentification p, #menubar #mbIdentification .illustration  { 
+	background:transparent url(images/menuId_sides.gif) repeat-y scroll left bottom; 
+}
+#menubar #mbIdentification form { 
+	background:transparent url(images/menuId_sides.gif) repeat-y scroll left bottom; 
+}
+#menubar #mbIdentification  .actions, #menubar #mbIdentification form  p { 
+	background:transparent none repeat-y scroll left bottom; 
+}
+#menubar #mbIdentification p { 
+	padding: 2px 16px 0; 
+	margin: 0;
+}
+#menubar p { 
+	padding: 16px 16px 0; 
+}
+#menubar .button { 
+	position:relative; 
+	right:9px; 
+	top:16px; 
+	height:16px; 
+	width:16px; 
+}
+#menubar #mbIdentification .button { 
+	height:24px; 
+	width:24px; 
+	right:0px; 
+	top:-40px; 
+}
+#menubar #mbIdentification fieldset { 
+	border:0; 
+	margin:0 24px 0 23px; 
+}
+#menubar #mbIdentification legend { 
+	display: none; 
+}
+#menubar #menuTagCloud { 
+	margin: 0; 
+	padding: 0 8px 0 16px; 
+}
+
+.content { 
+	background:#222 url(images/fillet.gif) repeat-x scroll left top; 
+	min-height:466px; 
+}
+
+.content { 
+	border: 1px solid #000; 
+	border-top: 0; 
+	margin:21px 7px 0 290px; 
+	padding-top:7px; 
+}
+.content h2 { 
+	margin:0; 
+	padding:0px 10px 15px 15px; 
+	border:0;
+}
+#menubar form { 
+	background:transparent url(images/menuBox_sides.gif) repeat-y scroll left bottom; 
+	margin:0; 
+}
+.content ul.thumbnailCategories li {
+	background:#222 url(images/cat_bottom-right.gif) no-repeat scroll right bottom; 
+	width:49%; 
+	margin: 0; 
+	padding:0; 
+}
+.content div.thumbnailCategory { 
+	background:transparent url(images/cat_bottom-left.gif) no-repeat scroll left bottom; 
+	padding: 0; 
+	margin:0; 
+}
+.content .thumbnailCategory div.illustration { 
+	background:transparent url(images/cat_top-left.gif) no-repeat scroll left top; 
+	padding: 0 0 0 10px; 
+	margin: 0 !important; 
+}
+.content .thumbnailCategory div.illustration a { 
+	display: block; 
+	margin: 0; 
+	padding:20px 0 0 8px; 
+}
+.content .thumbnailCategory div.description { 
+	background:transparent url(images/cat_top-right.gif) no-repeat scroll right top;
+	margin: 0; 
+	padding:15px 10px 3px 0; 
+	overflow: hidden !important; 
+}
+.content .thumbnailCategory div.description .text { 
+	display:block; 
+	margin:10px 2px 0 0;
+	overflow: auto; 
+	overflow-x:hidden; 
+	padding:0 0 5px; 
+}
+.content div.thumbnailCategory div.description p.dates { 
+	margin: 0 15px 0 15px; 
+	text-align: right; 
+}
+.content .thumbnailCategory div.description H3 { 
+	display: block; 
+}
+.content ul.thumbnailCategories li:hover { 
+	background-color:#111; 
+} 
+.content .navigationBar {
+	color:#666;
+}
+.infos { 
+	color:#f70; 
+	border:0; 
+	background-color: transparent; 
+	margin-left:125px;
+	padding:5px 0px 0pt 10pt; 
+	min-height: 48px; 
+	text-align:left; 
+}
+.infos li, .errors li { 
+	list-style-type:none; 
+}
+.errors { 
+	color:#f33; 
+	border:0; 
+	background: transparent url(icon/errors.png) no-repeat scroll right top; 
+	margin-left:125px;
+	padding:5px 0px 0pt 10pt; 
+	min-height: 48px; 
+	text-align:left; 
+	font-weight:bold; 
+}
+#menubar #menuTagCloud { 
+	background:transparent url(images/menuBox_sides.gif) repeat-y scroll left bottom;
+	margin:0; 
+	padding: 0 12px; 
+}
+H2 { 
+	border-bottom: 1px solid #000000; 
+}
+#qsearchInput { 
+	color:#999;
+}
+FIELDSET, INPUT, SELECT, TEXTAREA { 
+	border: 1px solid #666; 
+}
+input[type="text"], input[type="password"], input[type="button"], input[type="submit"], input[type="reset"], input[type="file"] {
+	background-color:#444; 
+	color:#999; 
+} /* stupid Line but needed  due to inpact on other themes and deadline of Piwigo 2.0 */
+input[type="file"] {
+	background-color:#222; 
+	border: 1px solid #666;
+}
+INPUT, select, textarea { 
+	color:#999; 
+	background-color:#444; 
+}
+input[type="radio"], input[type="checkbox"], input[type="button"].rateButtonStarEmpty, input[type="button"].rateButtonStarFull { 
+	background-color: transparent; 
+}
+#qsearchInput:focus, input:focus, select:focus, textarea:focus, input.focus, form .focus { 
+	background-color:#444;
+	color:#999; 
+}
+.content UL.thumbnails SPAN.wrap2 {
+	border: 1px solid #666;	/* thumbnails border color and style */
+	border-radius: 4px 4px;	/* round corners with CSS3 compliant browsers */ 
+}
+.content UL.thumbnails SPAN.wrap2:hover { 
+	color:#666;
+	background-color:#111; 
+	border:1px solid #ff3363;	/* thumbnails border color when mouse cursor is over it */ 
+}
+#comments ul.actions li, #comments ul.actions li:hover { 
+	background:transparent none;
+ 	padding: 0 22px; 
+	clear:both; 
+	list-style-type:none; 
+}
+span.calItem {
+	border:1px solid #666; 
+	margin:0 5px; 
+	padding:2px 5px 0 8px;
+}
+span.calItemEmpty, td.calDayCellEmpty, td.calDayCellFull {
+	border:1px solid #666;
+}
+A, INPUT.rateButton { 
+	color:#f70; 
+	border-width: 0; 
+}
+A:hover, A:active { 
+	color:#f33; 
+	border-bottom: 1px solid #FF3363; 
+	cursor: pointer; 
+}
+a.external { 
+	color:#FF3363; 
+	border:0; 
+	text-decoration: none; 
+}
+a.external:hover { 
+	color:#FF7700; 
+	border:0; 
+}
+a.Piwigo {
+  font-family: verdana, arial, helvetica, sans-serif !important;
+  font-size: 11px; font-weight: normal; letter-spacing: 0;
+  color : #F33; text-decoration: none; border: 0; }
+a.Piwigo:hover  span.Piwigo  { 
+  border-bottom: 1px solid #FF3363; 
+}
+#theImage A, .illustration A, A.navThumb, A.navThumb { 
+	border-bottom-width: 0; 
+}
+#imageToolBar { 
+	padding:0 7%; 
+}
+#imageHeaderBar .imageNumber { 
+	margin-right:7%; 
+}
+#imageHeaderBar .browsePath { 
+	margin-left:7%; 
+}
+*, *:focus, *:active, input:active, a:active, input:focus, a:focus { 
+	outline: none; 
+}
+#debug { 
+	margin: 15px 15px 5px 248px; 
+	font-size:12px; 
+	clear: both; 
+}
+.rateButtonStarFull, .rateButtonStarEmpty {   	
+	background-image: url('icon/rating-stars.gif'); 
+}
+#menubar #mbIdentification fieldset div input[type="text"] { 
+	margin: 0 0 3px; 
+	width: 174px; 
+	display: inline; 
+}
+input[type="button"], input[type="submit"], input[type="reset"] {
+	color:#ff3363; 
+	background-color:#222; 
+	border-color:#ff3363; 
+}
+input[type="button"]:hover, input[type="submit"]:hover, input[type="reset"]:hover {
+	color:#999; 
+	border-color:#666; 
+}
+.titrePage img.button[alt="x"] { margin: 0 3px 3px; }
+
+#thePicturePage .thumbnailCategory {
+	padding: 15px 2px 6px 12px; 
+	border: 1px solid #666; 
+}
+#thePicturePage .thumbnailCategory  .date, #thePicturePage .thumbnailCategory  .author {
+	font-weight:bold;
+}
+#thePicturePage .thumbnailCategories { 
+	padding-left: 12px; 
+	padding-right: 12px; 
+}
+#thePicturePage .odd { 
+	background-color: #222; 
+	border-top:0 !important; 
+}
+#addComment fieldset {
+  color: #f70;
+	border-color: #f70;
+}
+#addComment fieldset  label {
+  color: #666;
+}
+#theCommentsPage .content ul.thumbnailCategories li,
+#theCommentsPage .content div.thumbnailCategory ,
+#theCommentsPage .content div.thumbnailCategory div.description,
+#theCommentsPage .content .thumbnailCategory div.illustration { 
+	background-image: none;
+}
+#theCommentsPage .content div.thumbnailCategory {
+	padding: 15px 2px 6px 12px; 
+	border: 1px solid #666; 
+}
+#theCommentsPage .content .odd { 
+	background-color: #222; 
+	border-top:0 !important; 
+}
+#theCommentsPage .content .even { 
+	background-color: #111; 
+}
+#theCommentsPage .content ul.thumbnailCategories li:hover { 
+	background-color: transparent; 
+}
+#theCommentsPage div#comments {
+	padding: 0 0 5px 10px;
+}
+tr.tagLine, fieldset.tagLetter, legend.tagLetterLegend {
+	border-color: #666666;
+}
Index: /tags/2.0.2/template/yoga/theme/Sylvia/themeconf.inc.php
===================================================================
--- /tags/2.0.2/template/yoga/theme/Sylvia/themeconf.inc.php	(revision 3278)
+++ /tags/2.0.2/template/yoga/theme/Sylvia/themeconf.inc.php	(revision 3278)
@@ -0,0 +1,14 @@
+<?php
+$themeconf = array(
+  'template' => 'yoga',
+  'theme' => 'Sylvia',
+  'icon_dir' => 'template/yoga/theme/Sylvia/icon',
+  'admin_icon_dir' => 'template/yoga/icon/admin',
+  'mime_icon_dir' => 'template/yoga/theme/Sylvia/icon/mimetypes/',
+  'local_head' => '
+<!--[if IE]> 
+	<link rel="stylesheet" href="template/yoga/theme/Sylvia/theme-ie.css" type="text/css">
+<![endif]-->
+  ',
+);
+?>
Index: /tags/2.0.2/template/yoga/theme/clear/index.php
===================================================================
--- /tags/2.0.2/template/yoga/theme/clear/index.php	(revision 3278)
+++ /tags/2.0.2/template/yoga/theme/clear/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/template/yoga/theme/clear/mail-css.tpl
===================================================================
--- /tags/2.0.2/template/yoga/theme/clear/mail-css.tpl	(revision 3278)
+++ /tags/2.0.2/template/yoga/theme/clear/mail-css.tpl	(revision 3278)
@@ -0,0 +1,13 @@
+{* $Id$ *}
+/* Theme clear mail css */
+
+body {ldelim} background-color:#fff; color:#696969;}
+#the_page {ldelim} background: #fff url({$ROOT_URL}template/{$themeconf.template}/mail/text/html/images/mailbody-bg.png) repeat-y scroll left top;}
+#content {ldelim} background: transparent url({$ROOT_URL}template/{$themeconf.template}/mail/text/html/images/header-bg.png) no-repeat scroll left top;}
+#copyright {ldelim} background: transparent url({$ROOT_URL}template/{$themeconf.template}/mail/text/html/images/footer-bg.png) no-repeat scroll left bottom;
+color: #333;}
+h2 {ldelim} background-color: #ddd;}
+img {ldelim} margin: 16px; border: 16px solid #aaa; -moz-border-radius: 4px; border-radius: 4px 4px; }
+img:hover {ldelim} padding: 15px; border: 1px solid yellow;background-color:#faebd7; -moz-border-radius: 4px; border-radius: 4px 4px; }
+a {ldelim} color: #369; background: transparent; }
+a:hover {ldelim} color: #ddd; }
Index: /tags/2.0.2/template/yoga/theme/clear/theme.css
===================================================================
--- /tags/2.0.2/template/yoga/theme/clear/theme.css	(revision 3278)
+++ /tags/2.0.2/template/yoga/theme/clear/theme.css	(revision 3278)
@@ -0,0 +1,78 @@
+/* $Id$ */
+
+/* text color */
+BODY, H1, H2, H3, DT,
+INPUT.rateButtonSelected /* <= why IE doesn't inherit this ? */ {
+	color:#696969;	/* dimgray */
+}
+
+/* backgrounds */
+BODY, H3 {
+	background-color: #ffffff;	/* white */
+}
+
+H2, #menubar DT, #imageHeaderBar, #imageToolBar A:hover {
+	background-color: #d3d3d3;
+}
+
+#menubar DL, .content, #imageToolBar, .header_notes {
+  background-color: #eeeeee;
+}
+
+/* borders */
+#menubar DL, .content, #imageToolBar {
+  border: 1px solid #d3d3d3;
+}
+
+#theImage IMG {
+  border: 3px solid #d3d3d3;
+}
+
+.content UL.thumbnail IMG {
+    border: 1px solid #a0a0a0;
+}
+
+FIELDSET, INPUT, SELECT, TEXTAREA,
+.content DIV.thumbnailCategory {
+  border: 1px solid gray;
+}
+
+.content UL.thumbnails SPAN.wrap2 {
+  border: 1px solid #aaaaaa;	/* thumbnails border color and style */
+  border-radius: 4px 4px;	/* round corners with CSS3 compliant browsers */
+}
+
+.content UL.thumbnails SPAN.wrap2:hover,
+.content UL.thumbnailCategories DIV.thumbnailCategory:hover,
+.content UL.thumbnailCategories DIV.thumbnailCategory:hover A {
+  background-color: #faebd7;
+  border-color: yellow;		/* thumbnails border color when mouse cursor is over it */
+  color: black;
+}
+
+/* links */
+A, INPUT.rateButton {
+    color: #005e89;
+    background: transparent;
+}
+
+A:hover, INPUT.rateButton:hover {
+    color: #858460;
+}
+
+#imageToolBar A, #imageToolBar A:hover {
+    border-bottom: none;
+}
+
+A.navThumb, A.navThumb:hover {
+    border-bottom: none;
+}
+
+/*calendar elements*/
+SPAN.calItem, SPAN.calItemEmpty
+{
+  border: 1px solid silver;
+}
+
+#qsearchInput { color: #d3d3d3; }
+#qsearchInput:focus { color: #005e89; }
Index: /tags/2.0.2/template/yoga/theme/clear/themeconf.inc.php
===================================================================
--- /tags/2.0.2/template/yoga/theme/clear/themeconf.inc.php	(revision 3278)
+++ /tags/2.0.2/template/yoga/theme/clear/themeconf.inc.php	(revision 3278)
@@ -0,0 +1,10 @@
+<?php
+$themeconf = array(
+  'template' => 'yoga',
+  'theme' => 'clear',
+  'icon_dir' => 'template/yoga/icon',
+  'admin_icon_dir' => 'template/yoga/icon/admin',
+  'mime_icon_dir' => 'template/yoga/icon/mimetypes/',
+  'local_head' => '',
+);
+?>
Index: /tags/2.0.2/template/yoga/theme/dark/images/index.php
===================================================================
--- /tags/2.0.2/template/yoga/theme/dark/images/index.php	(revision 3278)
+++ /tags/2.0.2/template/yoga/theme/dark/images/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/template/yoga/theme/dark/index.php
===================================================================
--- /tags/2.0.2/template/yoga/theme/dark/index.php	(revision 3278)
+++ /tags/2.0.2/template/yoga/theme/dark/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/template/yoga/theme/dark/mail-css.tpl
===================================================================
--- /tags/2.0.2/template/yoga/theme/dark/mail-css.tpl	(revision 3278)
+++ /tags/2.0.2/template/yoga/theme/dark/mail-css.tpl	(revision 3278)
@@ -0,0 +1,13 @@
+{* $Id$ *}
+/* Theme dark mail css */
+
+body {ldelim} background-color:#444; color:#fff;}
+#the_page {ldelim} background: #444 url({$ROOT_URL}template/{$themeconf.template}/mail/text/html/images/mailbody-bg.png) repeat-y scroll left top;}
+#content {ldelim} background: transparent url({$ROOT_URL}template/{$themeconf.template}/mail/text/html/images/header-bg.png) no-repeat scroll left top;}
+#copyright {ldelim} background: transparent url({$ROOT_URL}template/{$themeconf.template}/mail/text/html/images/footer-bg.png) no-repeat scroll left bottom;
+color: #69c;}
+h2 {ldelim} background-color: #333;color:#fff48e;background-image: url({$ROOT_URL}template/{$themeconf.template}/theme/{$themeconf.theme}/images/tableh1_bg.png);}
+img {ldelim} margin: 16px; border: 16px solid #111; -moz-border-radius: 4px; border-radius: 4px 4px; }
+img:hover {ldelim} padding: 15px; border: 1px solid yellow;background-color:#444;-moz-border-radius: 4px; border-radius: 4px 4px; }
+a {ldelim} color: #fff48e; background: transparent;border-bottom:1px dotted #005e89; }
+a:hover {ldelim} color: #fff48e;}
Index: /tags/2.0.2/template/yoga/theme/dark/theme.css
===================================================================
--- /tags/2.0.2/template/yoga/theme/dark/theme.css	(revision 3278)
+++ /tags/2.0.2/template/yoga/theme/dark/theme.css	(revision 3278)
@@ -0,0 +1,77 @@
+/* $Id$ */
+
+/* text color */
+BODY, H1, H3,
+INPUT.rateButtonSelected /* <= why IE doesn't inherit this ? */ {
+	color:#d0d0d0;
+}
+
+H2, #menubar DT {
+	color: #fff48e;
+}
+
+
+/* backgrounds */
+
+BODY, H3, #imageHeaderBar, #imageToolBar A:hover {
+	background-color: #2f2f2f;
+}
+
+#menubar DL, .content, #imageToolBar, .header_notes {
+	background-color: #505050;
+}
+
+H2, #menubar DT {
+	background-image: url(images/tableh1_bg.png);
+}
+
+#imageHeaderBar H2 {
+	background-image: none;
+	background-color: transparent;
+	border: none;
+}
+
+#imageHeaderBar {
+	background-image: url(images/tableh2_bg.png);
+	background-repeat: repeat-x;
+	background-position: center;
+	border-top: 1px solid #000;
+}
+
+/* borders */
+#menubar DL, .content{
+	border: 1px solid #000;
+}
+
+H2, #menubar DT, #imageToolBar {
+	border-bottom: 1px solid #000;
+}
+
+FIELDSET, INPUT, SELECT, TEXTAREA,
+.content DIV.thumbnailCategory {
+	border: 1px solid gray;
+}
+
+.content UL.thumbnails SPAN.wrap2 {
+	border: 1px solid #aaaaaa;	/* thumbnails border color and style */
+	border-radius: 4px 4px;	/* round corners with CSS3 compliant browsers */
+}
+
+.content UL.thumbnails SPAN.wrap2:hover,
+.content UL.thumbnailCategories DIV.thumbnailCategory:hover,
+.content UL.thumbnailCategories DIV.thumbnailCategory:hover A {
+	background-color: #faebd7;
+	border-color: yellow;	/* thumbnails border color when mouse cursor is over it */
+	color: black;
+}
+
+
+/* links */
+A, INPUT.rateButton {
+	color: #fff;
+	border: none;
+}
+
+A:hover {
+	color: #FFF48E;
+}
Index: /tags/2.0.2/template/yoga/theme/dark/themeconf.inc.php
===================================================================
--- /tags/2.0.2/template/yoga/theme/dark/themeconf.inc.php	(revision 3278)
+++ /tags/2.0.2/template/yoga/theme/dark/themeconf.inc.php	(revision 3278)
@@ -0,0 +1,10 @@
+<?php
+$themeconf = array(
+  'template' => 'yoga',
+  'theme' => 'dark',
+  'icon_dir' => 'template/yoga/icon',
+  'admin_icon_dir' => 'template/yoga/icon/admin',
+  'mime_icon_dir' => 'template/yoga/icon/mimetypes/',
+  'local_head' => '',
+);
+?>
Index: /tags/2.0.2/template/yoga/theme/index.php
===================================================================
--- /tags/2.0.2/template/yoga/theme/index.php	(revision 3278)
+++ /tags/2.0.2/template/yoga/theme/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/template/yoga/theme/p0w0/images/index.php
===================================================================
--- /tags/2.0.2/template/yoga/theme/p0w0/images/index.php	(revision 3278)
+++ /tags/2.0.2/template/yoga/theme/p0w0/images/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/template/yoga/theme/p0w0/index.php
===================================================================
--- /tags/2.0.2/template/yoga/theme/p0w0/index.php	(revision 3278)
+++ /tags/2.0.2/template/yoga/theme/p0w0/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/template/yoga/theme/p0w0/mail-css.tpl
===================================================================
--- /tags/2.0.2/template/yoga/theme/p0w0/mail-css.tpl	(revision 3278)
+++ /tags/2.0.2/template/yoga/theme/p0w0/mail-css.tpl	(revision 3278)
@@ -0,0 +1,12 @@
+{* $Id$ *}
+/* Theme p0w0 mail css */
+
+body {ldelim} background-color:#cde; color:#369;}
+#the_page {ldelim} background: #cde url({$ROOT_URL}template/{$themeconf.template}/mail/text/html/images/mailbody-bg.png) repeat-y scroll left top;}
+#content {ldelim} background: transparent url({$ROOT_URL}template/{$themeconf.template}/mail/text/html/images/header-bg.png) no-repeat scroll left top;}
+#copyright {ldelim} background: transparent url({$ROOT_URL}template/{$themeconf.template}/mail/text/html/images/footer-bg.png) no-repeat scroll left bottom;
+color: #69c;}
+h2 {ldelim} color:#fff;background: #369 url({$ROOT_URL}template/{$themeconf.template}/theme/{$themeconf.theme}/images/button-bg.png);}
+img {ldelim} margin:16px;padding:15px;border:1px solid #69c;background-color:#eef;-moz-border-radius:4px; border-radius:4px 4px; }
+img:hover {ldelim} border: 1px solid #c60; -moz-border-radius:4px; border-radius:4px 4px; }
+a {ldelim} color: #f92; background: transparent; }
Index: /tags/2.0.2/template/yoga/theme/p0w0/theme.css
===================================================================
--- /tags/2.0.2/template/yoga/theme/p0w0/theme.css	(revision 3278)
+++ /tags/2.0.2/template/yoga/theme/p0w0/theme.css	(revision 3278)
@@ -0,0 +1,248 @@
+/* $Id$ */
+
+/**
+ * Color scheme (Remember #6699cc = #69c)
+ * #000000 #336699 #4477aa #6699cc (Black -> Blues)
+ * #cc6600 #ff9933 (Oranges)
+ * #cccccc
+ * #ccddee #dfe8ff #eeeeff #ffffff (Light colors -> White)
+ * */  
+/**
+ * Logic
+ * - Texts
+ * - Backgrounds
+ * - Borders, Margins, Padding
+ * - Visibility / Display
+ */
+
+/******************************************************************************/
+/* Texts Only */
+BODY, H1, H3, DT, H2 { color: #369; }
+H2, #menubar DT, TD H3 {
+  color: #fff;
+}
+#menubar DT, #menubar DT A {
+  color: #fff;
+  font-weight: bold;
+}
+.content .titrePage .categoryActions li { color: #cde;}
+#menubar DT A:hover {
+  color: #f92;
+  font-weight: bold;
+}
+h1 { font-weight: bold; letter-spacing: 0.2em; }
+#mbIdentification dd p,
+#menubar .selected A { color: #c60; font-weight: bold; }
+#copyright { color: #c60; }
+.content .pageNumberSelected,
+A, INPUT.rateButton, legend { color: #369; }
+A:hover { color: #f92; }
+INPUT.rateButtonSelected /* <= why IE doesn't inherit this ? */ {
+  color:#69c;
+}
+.infoTable,
+input#qsearchInput { color: #369; }
+.content .infos { color: #036; }
+.content .errors { color: #900; }
+.content .titrePage H2 A { color: #dfe8ff; }
+input.rateButtonSelected,
+.content .titrePage H2 A:hover { color: #f92; }
+.content H2 {
+  letter-spacing: 0.01em;
+  text-indent: 1em;
+  font-weight: normal;
+}
+.content ul.thumbnailCategories li div.thumbnailCategory .description h3,
+.content h3 { text-align: center; }
+.browsePath, .imageNumber,
+#imageHeaderBar H2,
+.browsePath A {
+  color: #eef;
+  font-weight: bold;
+}
+.browsePath A:hover { color: #fff; }
+.content H2:before, .browsePath:before, .imageNumber:before,
+#imageHeaderBar H2:before,
+.content H2:after, .browsePath:after, .imageNumber:after,
+#imageHeaderBar H2:after {
+ content: "   ";
+ color: #fff;
+ font-family: sans-serif;
+ font-weight: normal;
+ letter-spacing: 0em;
+}
+#thePicturePage #comments H3 {
+  color: #69c;
+}
+.content ul.thumbnailCategories li div.thumbnailCategory .description p {
+  color: #c60;
+}
+.content ul.thumbnailCategories li div.thumbnailCategory .description p + p {
+  color: #369;
+}
+.content div.thumbnailCategory .description h3 a {
+  color: #fff;
+}
+.content div.thumbnailCategory .description h3 a:hover {
+  color: #f92;
+}
+
+
+/******************************************************************************/
+/* Backgrounds Only */
+BODY { background: #cde; }
+.header_notes,
+#thePicturePage #the_page,
+#thePicturePage #theImage,
+.content { background-color: #dfe8ff; }
+#the_page { background-color: #dfe8ff; }
+#menubar, H3, #imageHeaderBar { background-color: #eef; }
+H2, #menubar DT, TD H3,
+#imageToolBar,
+#imageHeaderBar, #imageHeaderBar H2,
+.content H2 { background-color: #369; }
+.content .infos { background-color: #47a; ;}
+.content .errors { background-color: #fc5; ;}
+#thePicturePage #comments H3 { background-color: #eef; ;}
+.content ul.thumbnailCategories li div.thumbnailCategory .description h3 {
+  background-color: #69c; 
+}
+.content ul.thumbnailCategories li div.thumbnailCategory,
+.content UL.thumbnails SPAN.wrap2 { background-color: #eef; }
+.content ul.thumbnailCategories li div.thumbnailCategory:hover,
+#theImage IMG, .navThumb IMG,
+.content UL.thumbnails SPAN.wrap2:hover { background-color: #fff; }
+.content UL.thumbnails SPAN.wrap2:active img {
+  outline: 3px ridge #f92;
+}
+input#qsearchInput { background-color: #cde; }
+/******************************************************************************/
+/* Borders, Margins, Padding Only */
+BODY { margin: 0px;  padding: 0px; }
+#menubar {
+  margin : 0px 0px 0px 8px;
+  border: 0px;
+  text-decoration: none;
+  border: 1px solid #369;
+}
+A { border: 0px; text-decoration: none; }
+A:hover { text-decoration: none; border: 0px; }
+.content {
+  border: 1px solid #369;
+  padding: 0px;
+}
+#menubar DT, .content H2 {
+  background-image: url(images/button-bg.png);
+  border: 0px;
+  margin-bottom: 3px;
+}
+.content ul.thumbnailCategories li div.thumbnailCategory .description h3 {
+  background-image: url(images/button-bg.png);
+  border-width: 1px;
+  border-style: outset;
+  border-color: #369;
+}
+.content ul.thumbnailCategories li div.thumbnailCategory .description h3:active
+{
+	background: #69c;
+	border: 1px inset #369;
+}
+.content .errors { border-color: #f92; }
+#imageHeaderBar H2 { border: 0px; }
+#thePicturePage #imageToolBar { padding: 0px 25px 5px 25px; }
+#thePicturePage #theImage {
+  margin: 0px;
+  padding: 3px 0px 15px 0px;
+}
+#thePicturePage #comments H3 {
+  border-top: 2px solid #69c;
+  border-bottom: 1px solid #369;
+}
+H2, #imageToolBar {
+  border-bottom: 1px solid #fff;
+}
+.navThumb IMG { border: 1px solid #c60; padding: 1px; opacity: 0.8; }
+.navThumb:hover IMG { border: 1px solid #f92; padding: 1px; opacity: 1; }
+#theImage IMG {
+  border: 3px solid #369;
+  margin: 2px auto;
+  padding: 1px;
+  box-shadow: 0.2em 0.2em #ccc;
+}
+.content UL.thumbnail IMG {
+  border: 1px solid #666;
+}
+.illustration A {
+  border: 0px;
+}
+FIELDSET, INPUT, SELECT, TEXTAREA,
+.content DIV.thumbnailCategory {
+  border: 1px solid #69c;
+  background-color: #dfe8ff;
+  margin: 3px;
+}
+.content DIV.thumbnailCategory:hover {
+  border: 1px solid #f92;
+}
+.content UL.thumbnails SPAN.wrap2 {
+  border: 1px solid #69c;	/* thumbnails border color and style */
+  border-radius: 4px 4px;	/* round corners with CSS3 compliant browsers */
+}
+.content UL.thumbnails SPAN.wrap2:hover {
+  border-color: #f92;		/* thumbnails border color when mouse cursor is over it */
+}
+A.navThumb, A.navThumb:hover,
+#imageToolBar A, #imageToolBar A:hover {
+  border-bottom: none;
+}
+#the_page {
+  border: 0px;
+  padding: 5px 0px 30px 0px;
+  margin: 0px;
+}
+
+/******************************************************************************/
+/* Display, Visibility, buttons and others */
+label { cursor:pointer }
+.zero { display: none }
+
+input[type="text"], input[type="password"], input.button,
+input.submit, input.reset, input.file,
+select, textarea {
+  color: #369;
+  border: 1px solid #369;
+  background-color: #eeeeff;
+}
+input.submit[type="reset"]:focus,
+input.submit:focus {
+  background-color: #369;
+}
+input.submit[type="reset"],
+input.submit {
+  background-image: url(images/button-bg.png);
+  height:22px;
+  font-weight: bold;
+	color: #fff;
+  border-width: 1px;
+  border-style: outset;
+  border-color: #369;
+  padding-left: 2em;
+  padding-right: 2em;
+}
+input.submit[type="reset"]:active,
+input.submit:active {
+	background: #69c;
+  height:22px;
+	border: 1px inset #369;
+}
+#addComment fieldset input.submit[type="submit"]  {
+  height: 38px;
+  padding-left: 4em;
+  padding-right: 4em;
+}
+#menubar .menuInfoCat, #menubar .menuInfoCatByChild {
+  font-size: 80%;
+  font-style: normal;
+}
+* { outline: none; }
+
Index: /tags/2.0.2/template/yoga/theme/p0w0/themeconf.inc.php
===================================================================
--- /tags/2.0.2/template/yoga/theme/p0w0/themeconf.inc.php	(revision 3278)
+++ /tags/2.0.2/template/yoga/theme/p0w0/themeconf.inc.php	(revision 3278)
@@ -0,0 +1,10 @@
+<?php
+$themeconf = array(
+  'template' => 'yoga',
+  'theme' => 'p0w0',
+  'icon_dir' => 'template/yoga/icon',
+  'admin_icon_dir' => 'template/yoga/icon/admin',
+  'mime_icon_dir' => 'template/yoga/icon/mimetypes/',
+  'local_head' => '',
+);
+?>
Index: /tags/2.0.2/template/yoga/theme/wipi/images/index.php
===================================================================
--- /tags/2.0.2/template/yoga/theme/wipi/images/index.php	(revision 3278)
+++ /tags/2.0.2/template/yoga/theme/wipi/images/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/template/yoga/theme/wipi/index.php
===================================================================
--- /tags/2.0.2/template/yoga/theme/wipi/index.php	(revision 3278)
+++ /tags/2.0.2/template/yoga/theme/wipi/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/template/yoga/theme/wipi/mail-css.tpl
===================================================================
--- /tags/2.0.2/template/yoga/theme/wipi/mail-css.tpl	(revision 3278)
+++ /tags/2.0.2/template/yoga/theme/wipi/mail-css.tpl	(revision 3278)
@@ -0,0 +1,19 @@
+{* $Id$ *}
+/* Theme wipi mail css */
+
+body {ldelim} background-color:#111; color:#69c;}
+#the_page {ldelim} background: #111 url({$ROOT_URL}template/{$themeconf.template}/mail/text/html/images/mailbody-bg.png) repeat-y scroll left top;}
+#content {ldelim} background: transparent url({$ROOT_URL}template/{$themeconf.template}/mail/text/html/images/header-bg.png) no-repeat scroll left top;}
+#copyright {ldelim} background: transparent url({$ROOT_URL}template/{$themeconf.template}/mail/text/html/images/footer-bg.png) no-repeat scroll left bottom;
+color: #69c;}
+h2 {ldelim} background-color: #222;color:#eee;background-image: url({$ROOT_URL}template/{$themeconf.template}/theme/{$themeconf.theme}/images/tableh1_bg.png);}
+img {ldelim} margin: 16px; padding:15px;border:1px solid #eee; -moz-border-radius: 4px; border-radius: 4px 4px; }
+img:hover {ldelim} border:1px solid #69c; -moz-border-radius: 4px; border-radius: 4px 4px; }
+a {ldelim} color: #69c; background: transparent; }
+a:hover {ldelim} color: #f92; }
+a.PWG {ldelim} border: 0px; }
+a.PWG .P {ldelim} color : #f92; }
+a.PWG .W {ldelim} color : #aaa; }
+a.PWG .G {ldelim} color : #69c; }
+a.PWG:hover .P {ldelim} color : #69c; }
+a.PWG:hover .G {ldelim} color : #f92; }
Index: /tags/2.0.2/template/yoga/theme/wipi/theme.css
===================================================================
--- /tags/2.0.2/template/yoga/theme/wipi/theme.css	(revision 3278)
+++ /tags/2.0.2/template/yoga/theme/wipi/theme.css	(revision 3278)
@@ -0,0 +1,274 @@
+/* $Id$ */
+
+/* text color */
+BODY, H1, H3, DT,
+INPUT.rateButtonSelected /* <= why IE doesn't inherit this ? */ {
+  color:#e0e0e0;
+}
+#menubar { 
+  margin : 0px;
+  background-color: transparent;
+  border: 0px;
+}
+H2 {
+  color: #eee;
+}
+#menubar DT, #menubar DT A {
+  color: #eee; 
+  font-weight: lighter;
+}
+#menubar DT A:hover {
+  color: #69c; 
+  font-weight: lighter;
+}
+#menubar .selected  A {
+  color: #eee; 
+}
+#menubar .selected  A:hover {
+  color: #f92; 
+}
+#menubar DT:before {
+ content: "__\\_ "; 
+ color: #f92;
+}
+#menubar DT:after {
+ content: " _/__"; 
+ color: #69c;
+}
+#menubar .button {
+  margin: 0 2px 0px 8px;
+  width: auto;
+  padding: 0;
+  text-indent: 0;
+  list-style: none;
+  text-align: center;
+  float: left;
+}
+.content .pageNumberSelected {
+  color: #f92;
+}
+.content .infos {
+  background-color: #69c;
+  color: #036;
+}
+.content .errors {
+  background-color: #fc5;
+  border-color: #f92;
+  color: #900;
+}
+/* backgrounds */
+BODY {
+  background: #111;
+  margin: 0px;
+  padding: 0px;
+}
+H3, #imageToolBar A:hover {
+  background-color: #222;
+}
+
+#imageHeaderBar {
+  background-color: #111;
+}
+#imageToolBar, .header_notes {
+  background-color: #333;
+}
+A {
+  border-color: #69c;
+}
+A:hover {
+  border-color: #f92;
+}
+.content {
+  background-color: #181818;
+  border: 1px solid #eee;
+  padding: 5px;
+}
+
+H2, #menubar DT, TD H3 {
+  background-image: url(images/tableh1_bg.png);
+  background-repeat: repeat-x;
+}
+.content H2 {
+  background: none;
+  border: 0px;
+  letter-spacing: -0.05em; 
+  text-indent: 1em;
+  text-transform:	uppercase;
+  font-weight: lighter;
+  margin-bottom: 20px;
+}
+.content ul.thumbnailCategories li div.thumbnailCategory .description h3,
+.content h3 { text-align: center; }
+.content ul.thumbnailCategories li div.thumbnailCategory .description p {
+  color: #f92; text-indent: 0em; 
+}
+.content ul.thumbnailCategories li div.thumbnailCategory .description p + p {
+  color: #fff; 
+}
+.browsePath A {
+  color: #eee;
+}
+.content H2:before, .browsePath:before, .imageNumber:before,
+#imageHeaderBar H2:before {
+ content: "____\\_ "; 
+ color: #69c; 
+ font-family: Times, Zapf-Chancery, Cottonwood, Helvetica;
+ letter-spacing: 0em; 
+}
+.content H2:after, .browsePath:after, .imageNumber:after,
+#imageHeaderBar H2:after {
+ content: " _/____"; 
+ color: #f92;
+ font-family: Times, Zapf-Chancery, Cottonwood, Helvetica;
+ letter-spacing: 0em; 
+}
+#imageHeaderBar H2 {
+  background-image: none;
+  background-color: transparent;
+  border: none;
+}
+#thePicturePage #the_page {
+  background-color: #111;
+}
+#thePicturePage #imageHeaderBar {
+  background-image: url(images/tableh2_bg.png);
+  background-repeat: repeat-x;
+}
+#thePicturePage #imageToolBar {
+  background-color: #111;
+  border-bottom: 2px solid #69c;
+}
+#thePicturePage #theImage {
+  background-color: #111;
+  margin: 0px;
+  padding: 3px 0px 15px 0px;
+}
+
+#thePicturePage #comments H3 {
+  background-image: none;
+  background-color: #222;
+  border-top: 2px solid #69c;
+  border-bottom: 2px solid #69c;
+  color: #69c; 
+  font-weight: lighter;
+}
+
+/* borders */
+#imageHeaderBar {
+  border-top: 1px solid #000;
+  padding: 8px 0px 3px 0px;
+}
+H2, #imageToolBar {
+  border-bottom: 1px solid #000;
+}
+
+#theImage IMG {
+  border: 3px solid #fff;
+}
+
+.content UL.thumbnail IMG {
+  border: 1px solid #a0a0a0;
+}
+.illustration A {
+  border: 0px;
+}
+FIELDSET, INPUT, SELECT, TEXTAREA,
+.content DIV.thumbnailCategory {
+  border: 1px solid gray;
+}
+.content DIV.thumbnailCategory {
+  border: 1px solid #69c;
+  margin: 8px 4px;
+}
+
+.content UL.thumbnails SPAN.wrap2 {
+  border: 1px solid #aaaaaa;	/* thumbnails border color and style */
+  border-radius: 4px 4px;	/* round corners with CSS3 compliant browsers */
+}
+
+.content UL.thumbnails SPAN.wrap2:hover,
+.content UL.thumbnailCategories DIV.thumbnailCategory:hover {
+  background-color: #333;
+  border-color: #69c;		/* thumbnails border color when mouse cursor is over it */
+}
+
+/* links */
+A, INPUT.rateButton, legend {
+  color: #69c;
+}
+
+A:hover {
+  color: #f92;
+}
+
+#imageToolBar A, #imageToolBar A:hover {
+  border-bottom: none;
+}
+A.navThumb, A.navThumb:hover {
+  border-bottom: none;
+}
+#the_page {
+  border: 1px dotted #f92;
+  padding-top: 5px;
+  padding-bottom:30px;
+  margin: 2px;
+}
+#copyright {
+  color: #69c;
+}
+
+label {
+	cursor:pointer
+}
+input#qsearchInput { 
+  color: #58c; 
+  background-color: #222;  
+  border: 1px solid #333;
+  padding: 1px 3px;
+}
+.zero { display: none }
+.nb-hits { color: #69c; }
+.nb-comments { color: #f92; }
+
+FORM#quickconnect,
+FORM#quickconnect FIELDSET,
+FORM#quickconnect DIV,
+FORM#quickconnect UL.actions,
+FORM#quickconnect LABEL {
+  color: #69c;   
+}
+FORM#quickconnect DIV INPUT,
+FORM#quickconnect INPUT[type=text],
+FORM#quickconnect INPUT[type=password] {
+  color: #58c;   
+  background-color: #222;  
+  border: 1px solid #333;
+}
+
+.PWG {
+  font-family: verdana, arial, helvetica, sans-serif !important;
+  font-size: 0.9em;
+  font-weight: normal;
+  letter-spacing: 0px;
+}
+a.PWG { border: 0px; }
+a.PWG .P { color : #f92; }
+a.PWG .W { color : #aaa; }
+a.PWG .G { color : #69c; }
+a.PWG:hover .P { color : #69c; }
+a.PWG:hover .G { color : #f92; }
+#menubar DT {
+    border-top: 1px solid #eef;
+    border-right: 1px solid #69c;
+    border-bottom: 1px solid #69c;
+    border-bottom-right-radius: 12px;
+   -moz-border-radius-bottomright: 12px;
+    box-shadow: 5px 5px #69c;
+}
+.statBar { background-color: #e60; }
+#imageToolBar .randomButtons a:hover,
+#imageToolBar .navButtons a:hover { background-color: #111; }
+#menubar .menuInfoCat,
+#menubar .menuInfoCatByChild,
+h2.showtitle, #theImage p.showlegend { display: none }
+* { outline-width: 0px; }
Index: /tags/2.0.2/template/yoga/theme/wipi/themeconf.inc.php
===================================================================
--- /tags/2.0.2/template/yoga/theme/wipi/themeconf.inc.php	(revision 3278)
+++ /tags/2.0.2/template/yoga/theme/wipi/themeconf.inc.php	(revision 3278)
@@ -0,0 +1,15 @@
+<?php
+$themeconf = array(
+  'template' => 'yoga',
+  'theme' => 'wipi',
+  'icon_dir' => 'template/yoga/icon',
+  'admin_icon_dir' => 'template/yoga/icon/admin',
+  'mime_icon_dir' => 'template/yoga/icon/mimetypes/',
+  'local_head' => '',
+);
+if ( !isset($lang['Theme: wipi']) )
+{
+  $lang['Theme: wipi'] = 'The site is displayed with wipi theme based ' .
+  ' on yoga template, a standard template/theme of PhpWebgallery.';
+}
+?>
Index: /tags/2.0.2/template/yoga/thumbnails.css
===================================================================
--- /tags/2.0.2/template/yoga/thumbnails.css	(revision 3278)
+++ /tags/2.0.2/template/yoga/thumbnails.css	(revision 3278)
@@ -0,0 +1,37 @@
+/* $Id$ */
+
+/* Thumbnails customization */
+.content UL.thumbnails SPAN.thumbLegend {
+	font-size: 90%;
+	overflow: hidden;/* oversized legend is clipped */
+}
+
+/* Thumbnail "elastic" layout */
+.content UL.thumbnails {
+	margin: 0;
+	padding: 0;
+	list-style: none;
+	text-align: center;	/* to center the whole collection in .content */
+}
+.content UL.thumbnails LI { display: inline }
+
+.content UL.thumbnails SPAN.wrap1 {
+	margin: 0 5px 5px 5px;
+	display: table-cell; display: inline-table;
+	display: inline-block;/* Why 3 display option ??? */
+	vertical-align: top;	/* OK with Opera and IE6 not Geko */
+	text-align: center;		/* to center the thumbnail and legend in Geko/Opera */
+}
+.content UL.thumbnails SPAN.wrap2 {
+	margin: 0;			/* important reset the margins */
+	display: table-cell;/* block prevents vertical-align here */
+	vertical-align: middle;/* Ok with Opera and Geko not IE6 */
+}
+.content UL.thumbnails SPAN.wrap2 A,
+.content UL.thumbnails LABEL {
+	display: block;
+	border-bottom: none;
+}
+.content UL.thumbnails IMG {
+	margin-bottom: -4px;  /* why ??? something wrong with Geko and Opera ignored by IE6*/
+}
Index: /tags/2.0.2/template/yoga/thumbnails.tpl
===================================================================
--- /tags/2.0.2/template/yoga/thumbnails.tpl	(revision 3278)
+++ /tags/2.0.2/template/yoga/thumbnails.tpl	(revision 3278)
@@ -0,0 +1,36 @@
+{* $Id$ *}
+
+{if !empty($thumbnails)}
+<ul class="thumbnails">
+{foreach from=$thumbnails item=thumbnail}
+	<li>
+	<span class="wrap1">
+		<span class="wrap2">
+		<a href="{$thumbnail.URL}">
+			<img class="thumbnail" src="{$thumbnail.TN_SRC}" alt="{$thumbnail.TN_ALT}" title="{$thumbnail.TN_TITLE}" />
+		</a>
+		</span>
+		<span class="thumbLegend">
+		{if isset($thumbnail.NAME)}{$thumbnail.NAME}{/if}
+		{$thumbnail.ICON_TS}
+		{if isset($thumbnail.NB_COMMENTS)}
+		<span class="{if 0==$thumbnail.NB_COMMENTS}zero {/if}nb-comments">
+		<br />
+		{$pwg->l10n_dec('%d comment', '%d comments',$thumbnail.NB_COMMENTS)}
+		</span>
+		{/if}
+
+		{if isset($thumbnail.NB_HITS)}
+		<span class="{if 0==$thumbnail.NB_HITS}zero {/if}nb-hits">
+		<br />
+		{$pwg->l10n_dec('%d hit', '%d hits',$thumbnail.NB_HITS)}
+		</span>
+		{/if}
+		</span>
+	</span>
+	</li>
+{/foreach}
+</ul>
+{/if}
+
+
Index: /tags/2.0.2/template/yoga/upload.tpl
===================================================================
--- /tags/2.0.2/template/yoga/upload.tpl	(revision 3278)
+++ /tags/2.0.2/template/yoga/upload.tpl	(revision 3278)
@@ -0,0 +1,115 @@
+{* $Id$ *}
+
+{* Example of resizeable *}
+{*
+{include file='include/autosize.inc.tpl'}
+*}
+
+<div id="content" class="content">
+
+  <div class="titrePage">
+    <ul class="categoryActions">
+      <li><a href="{$U_HOME}" title="{'return to homepage'|@translate}"><img src="{$themeconf.icon_dir}/home.png" class="button" alt="{'home'|@translate}"/></a></li>
+    </ul>
+    <h2>{'upload_title'|@translate}</h2>
+  </div>
+
+  {if !empty($errors)}
+  <div class="errors">
+    <ul>
+      {foreach from=$errors item=error}
+      <li>{$error}</li>
+      {/foreach}
+    </ul>
+  </div>
+  {/if}
+
+  {if not $UPLOAD_SUCCESSFUL }
+  <form enctype="multipart/form-data" method="post" action="{$F_ACTION}">
+    <table style="width:80%;margin-left:auto;margin-right:auto;">
+    <tr>
+      <td colspan="2" class="menu">
+      <div style="text-align:center;">{$ADVISE_TITLE}</div>
+      {if not empty($advises)}
+      <ul>
+        {foreach from=$advises item=advise}
+        <li>{$advise}</li>
+        {/foreach}
+      </ul>
+      {/if}
+      </td>
+    </tr>
+    <tr>
+      <td colspan="2" align="center">
+      <input class="file" name="picture" type="file" value="" />
+      </td>
+    </tr>
+    {if isset($SHOW_FORM_FIELDS) and $SHOW_FORM_FIELDS}
+    <!-- category -->
+    <tr>
+      <td>{'Category'|@translate}</td>
+      <td>
+        {html_options name="category" options=$categories selected=$categories_selected}
+      </td>
+    </tr>
+    <!-- username -->
+    <tr>
+      <td>{'Username'|@translate} <span style="color:red;">*</span></td>
+      <td>
+      <input name="username" type="text" value="{$NAME}" />
+      </td>
+    </tr>
+    <!-- mail address -->
+    <tr>
+      <td>{'mail_address'|@translate} <span style="color:red;">*</span></td>
+      <td>
+      <input name="mail_address" type="text" value="{$EMAIL}" />
+      </td>
+    </tr>
+    <!-- name of the picture -->
+    <tr>
+      <td>{'upload_name'|@translate}</td>
+      <td>
+      <input name="name" type="text" value="{$NAME_IMG}" />
+      </td>
+    </tr>
+    <!-- author -->
+    <tr>
+      <td>{'upload_author'|@translate}</td>
+      <td>
+      <input name="author" type="text" value="{$AUTHOR_IMG}" />
+      </td>
+    </tr>
+    <!-- date of creation -->
+    <tr>
+      <td>{'Creation date'|@translate} (DD/MM/YYYY)</td>
+      <td>
+      <input name="date_creation" type="text" value="{$DATE_IMG}" />
+      </td>
+    </tr>
+    <!-- comment -->
+    <tr>
+      <td>{'comment'|@translate}</td>
+      <td>
+       <textarea name="comment" id="comment" rows="3" cols="40" style="overflow:auto">{$COMMENT_IMG}</textarea>
+      </td>
+    </tr>
+    {/if}
+    <tr>
+      <td colspan="2" align="center">
+      <input class="submit" name="submit" type="submit" value="{'Submit'|@translate}" />
+      </td>
+    </tr>
+    </table>
+  </form>
+  {else}
+  {'upload_successful'|@translate}<br />
+  <div style="text-align:center;">
+    <a href="{$U_RETURN}">[ {'home'|@translate} ]</a>
+  </div>
+  {/if}
+  
+  {if isset($SHOW_FORM_FIELDS) and $SHOW_FORM_FIELDS}
+  <div style="text-align:left; margin-left:20px;"><span style="color:red;">*</span> : {'mandatory'|@translate}</div>
+  {/if}
+</div> <!-- content -->
Index: /tags/2.0.2/tools/config_local.inc.php
===================================================================
--- /tags/2.0.2/tools/config_local.inc.php	(revision 3278)
+++ /tags/2.0.2/tools/config_local.inc.php	(revision 3278)
@@ -0,0 +1,8 @@
+<?php
+// this file is provided as an example. It does not modify the configuration
+// as long as it remains in "tools" directory. Move it to "include"
+// directory if you want to modify default configuration.
+
+$conf['prefix_thumbnail'] = 'thumb_';
+$conf['show_gt'] = true;
+?>
Index: /tags/2.0.2/tools/create_listing_file.php
===================================================================
--- /tags/2.0.2/tools/create_listing_file.php	(revision 3278)
+++ /tags/2.0.2/tools/create_listing_file.php	(revision 3278)
@@ -0,0 +1,1697 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// +-----------------------------------------------------------------------+
+// |                                User configuration                     |
+// +-----------------------------------------------------------------------+
+
+// ****** Gallery configuration ****** //
+// Script version
+$conf['version'] = '2.0';
+
+// URL of main gallery
+// Example : http://www.my.domain/my/directory
+$conf['gallery'] = 'http://piwigo.org/demo';
+
+// prefix for thumbnails in "thumbnail" sub directories
+$conf['prefix_thumbnail'] = 'TN-';
+
+// $conf['file_ext'] lists all extensions (case insensitive) allowed
+// for your Piwigo installation
+$conf['file_ext'] = array('jpg','JPG','jpeg','JPEG',
+                          'png','PNG','gif','GIF','mpg','zip',
+                          'avi','mp3','ogg');
+
+
+// $conf['picture_ext'] must be a subset of $conf['file_ext']
+$conf['picture_ext'] = array('jpg','JPG','jpeg','JPEG',
+                             'png','PNG','gif','GIF');
+
+// ****** Time limitation functionality ****** //
+// max execution time before refresh in seconds
+$conf['max_execution_time'] = (5*ini_get('max_execution_time'))/6; // 25 seconds with default PHP configuration
+// force the use of refresh method
+// in order to have live informations
+// or
+// to fix system witch are not safe mode but not autorized set_time_limit
+$conf['force_refresh_method'] =  true;
+
+// refresh delay is seconds
+$conf['refresh_delay'] = 0;
+
+// ****** EXIF support functionality ****** //
+// $conf['use_exif'] set to true if you want to use Exif information
+$conf['use_exif'] = true;
+
+// use_exif_mapping: same behaviour as use_iptc_mapping
+$conf['use_exif_mapping'] = array(
+  'date_creation' => 'DateTimeOriginal'
+  );
+
+// ****** IPTC support functionality ****** //
+// $conf['use_iptc'] set to true if you want to use IPTC informations of the
+// element according to get_sync_iptc_data function mapping, otherwise, set
+// to false
+$conf['use_iptc'] = false;
+
+// use_iptc_mapping : in which IPTC fields will Piwigo find image
+// information ? This setting is used during metadata synchronisation. It
+// associates a piwigo_images column name to a IPTC key
+$conf['use_iptc_mapping'] = array(
+  'keywords'        => '2#025',
+  'date_creation'   => '2#055',
+  'author'          => '2#122',
+  'name'            => '2#005',
+  'comment'         => '2#120');
+
+// ****** Directory protection functionality ****** //
+// Define if directories have to be protected if they are not
+$conf['protect'] = false;
+
+// true/false : show/hide warnings
+$conf['protect_warnings'] = true;
+
+// ****** Thumbnails generation functionality ****** //
+// Define if images have to be reduced if they are not
+$conf['thumbnail'] = false;
+
+// Define method to generate thumbnails : 
+// - fixed (width and height required);
+// - width (only width required);
+// - height (only height required);
+// - ratio (only ratio is required)
+// - exif (no other parameter required)
+$conf['thumbnail_method'] = 'ratio';
+
+// Height in pixels (greater than 0)
+$conf['thumbnail_height'] = 128;
+
+// Width in pixels (greater than 0)
+$conf['thumbnail_width'] = 128;
+
+// Ratio between original and thumbnail size (strictly between 0 and 1)
+$conf['thumbnail_ratio'] = 0.2;
+
+// Define thumbnail format : jpeg, png or gif (will be verified)
+$conf['thumbnail_format'] = 'jpeg';
+
+// ****** Directory mapping ****** //
+// directories names 
+$conf['thumbs'] = 'thumbnail'; // thumbnails
+$conf['high'] = 'pwg_high'; // high resolution
+$conf['represent'] = 'pwg_representative'; // non pictures representative files
+
+
+// +-----------------------------------------------------------------------+
+// | Overload configurations                                               |
+// +-----------------------------------------------------------------------+
+@include(dirname(__FILE__).'/'.basename(__FILE__, '.php').'_local.inc.php');
+
+
+// +-----------------------------------------------------------------------+
+// |                                Advanced script configuration          |
+// +-----------------------------------------------------------------------+
+
+// url of icon directory in yoga template
+$pwg_conf['icon_dir'] = $conf['gallery'].'/template/yoga/icon/';
+
+// list of actions managed by this script
+$pwg_conf['scan_action'] = array('clean', 'test', 'generate');
+
+// url of this script
+$pwg_conf['this_url'] = 
+    (empty($_SERVER['HTTPS']) ? 'http://' : 'https://')
+    .str_replace(':'.$_SERVER['SERVER_PORT'], '', $_SERVER['HTTP_HOST'])
+    .($_SERVER['SERVER_PORT'] != 80 ? ':'.$_SERVER['SERVER_PORT'] : '')
+    .$_SERVER['PHP_SELF'];
+
+// list of reserved directory names
+$pwg_conf['reserved_directory_names'] = array($conf['thumbs'], $conf['high'], $conf['represent'], ".", "..", ".svn");
+
+// content of index.php generated in protect action
+$pwg_conf['protect_content'] = '<?php header("Location: '.$conf['gallery'].'") ?>';
+
+// backup of PHP safe_mode INI parameter (used for time limitation)
+$pwg_conf['safe_mode'] = (ini_get('safe_mode') == '1') ? true : false;
+
+// This parameter will be fixed in pwg_init()
+$pwg_conf['gd_version_major'] = '';
+$pwg_conf['gd_version_full'] = '';
+$pwg_conf['gd_supported_format'] = array();
+
+// +-----------------------------------------------------------------------+
+// |                               Functions                               |
+// +-----------------------------------------------------------------------+
+
+/**
+ * write line in log file
+ *
+ * @param string line
+ * @return string
+ */
+function pwg_log($line)
+{
+  $log_file = fopen(__FILE__.'.log', 'a');
+  fwrite($log_file, $line);
+  fclose($log_file);
+}
+
+/**
+ * Check web server graphical capabilities
+ *
+ * @return string
+ */
+function pwg_check_graphics()
+{
+  //~ pwg_log('>>>>> pwg_check_graphics() >>>>>'."\n");
+  
+  global $conf, $pwg_conf;
+  $log = '';
+  
+  // Verify gd library for thumbnail generation
+  if ($conf['thumbnail'] and !is_callable('gd_info'))
+  {
+    $log .= '          <code class="warning">Warning -</code> Your server can not generate thumbnails. Thumbnail creation switched off.<br />'."\n";
+    // Switch off thumbnail generation
+    $conf['thumbnail'] = false;
+    return $log;
+  }
+  
+  // Verify thumnail format
+  if ($conf['thumbnail'])
+  {
+    $info = gd_info();
+    
+    // Backup GD major version
+    $pwg_conf['gd_version_full'] = ereg_replace('[[:alpha:][:space:]()]+', '', $info['GD Version']);
+    list($pwg_conf['gd_version_major']) = preg_split('/[.]+/', $pwg_conf['gd_version_full']);
+    
+    // Backup input/output format support
+    array_push($pwg_conf['gd_supported_format'], $info['JPG Support'] ? 'jpeg' : NULL);
+    array_push($pwg_conf['gd_supported_format'], $info['PNG Support'] ? 'png' : NULL);
+    array_push($pwg_conf['gd_supported_format'], ($info['GIF Read Support'] and $info['GIF Create Support']) ? 'gif' : NULL);
+    
+    // Check output format support
+    if (!in_array($conf['thumbnail_format'], $pwg_conf['gd_supported_format']))
+    {
+      $log .= '          <code class="warning">Warning -</code> Your server does not support thumbnail\'s <code>';
+      $log .= $conf['thumbnail_format'].'</code> format. Thumbnail creation switched off.<br />'."\n";
+    }
+    
+    switch ($conf['thumbnail_method'])
+    {
+      case 'exif':
+      {
+        // exif_thumbnail() must be callable
+        if (!is_callable('exif_thumbnail'))
+        {
+          $log .= '          <code class="warning">Warning -</code> Your server does not support thumbnail creation through EXIF datas. Thumbnail creation switched off.<br />'."\n";
+        }
+        break;
+      }
+      case 'fixed':
+      {
+        // $conf['thumbnail_width'] > 0
+        if (!is_numeric($conf['thumbnail_width']) or $conf['thumbnail_width'] <= 0)
+        {
+          $log .= '          <code class="failure">Failure -</code> Bad value <code>thumbnail_width = ';
+          $log .= var_export($conf['thumbnail_width'], true).'</code>. Thumbnail creation switched off.<br />'."\n";
+        }
+        // $conf['thumbnail_height'] > 0
+        if (!is_numeric($conf['thumbnail_height']) or $conf['thumbnail_height'] <= 0)
+        {
+          $log .= '          <code class="failure">Failure -</code> Bad value <code>thumbnail_height = ';
+          $log .= var_export($conf['thumbnail_height'], true).'</code>. Thumbnail creation switched off.<br />'."\n";
+        }
+        break;
+      }
+      case 'ratio':
+      {
+        // 0 < $conf['thumbnail_ratio'] < 1
+        if (!is_numeric($conf['thumbnail_ratio']) or $conf['thumbnail_ratio'] <= 0 or $conf['thumbnail_ratio'] >= 1)
+        {
+          $log .= '          <code class="failure">Failure -</code> Bad value <code>thumbnail_ratio = ';
+          $log .= var_export($conf['thumbnail_ratio'], true).'</code>. Thumbnail creation switched off.<br />'."\n";
+        }
+        break;
+      }
+      case 'width':
+      {
+        // $conf['thumbnail_width'] > 0
+        if (!is_numeric($conf['thumbnail_width']) or $conf['thumbnail_width'] <= 0)
+        {
+          $log .= '          <code class="failure">Failure -</code> Bad value <code>thumbnail_width = ';
+          $log .= var_export($conf['thumbnail_width'], true).'</code>. Thumbnail creation switched off.<br />'."\n";
+        }
+        break;
+      }
+      case 'height':
+      {
+        // $conf['thumbnail_height'] > 0
+        if (!is_numeric($conf['thumbnail_height']) or $conf['thumbnail_height'] <= 0)
+        {
+          $log .= '          <code class="failure">Failure -</code> Bad value <code>thumbnail_height = ';
+          $log .= var_export($conf['thumbnail_height'], true).'</code>. Thumbnail creation switched off.<br />'."\n";
+        }
+        break;
+      }
+      default:
+      {
+        // unknown method
+          $log .= '          <code class="failure">Failure -</code> Bad value <code>thumbnail_method = ';
+          $log .= var_export($conf['thumbnail_method'], true).'</code>. Thumbnail creation switched off.<br />'."\n";
+        break;
+      }
+    }
+    
+    if (strlen($log))
+    {
+      $conf['thumbnail'] = false;
+    }
+  }
+  
+  //~ pwg_log('<<<<< pwg_check_graphics() returns '.var_export($log, TRUE).' <<<<<'."\n");
+  return $log;
+}
+
+/**
+ * returns xml </dirX> lines
+ *
+ * @param integer $dir_start
+ * @param integer $dir_number
+ * @return string
+ */
+function pwg_close_level($dir_start, $dir_number)
+{
+  //~ pwg_log('>>>>> pwg_close_level($dir_start = '.var_export($dir_start, TRUE).', $dir_number = '.var_export($dir_number, TRUE).') >>>>>'."\n");
+  
+  $lines ='';
+  do
+  {
+    $lines .= str_repeat(' ', 2*$dir_start).'</dir'.$dir_start.">\n";
+    $dir_number--;
+    $dir_start--;
+  }
+  while(($dir_number > 0) && ($dir_start >= 0));
+  
+  //~ pwg_log('<<<<< pwg_close_level returns '.var_export($lines, TRUE).' <<<<<'."\n");
+  return $lines;
+}
+
+/**
+ * return a cleaned IPTC value
+ *
+ * @param string value
+ * @return string
+ */
+function pwg_clean_iptc_value($value)
+{
+  //~ pwg_log('>>>>> pwg_clean_iptc_value ($value = '.var_export($value, TRUE).') >>>>>'."\n");
+  
+  // strip leading zeros (weird Kodak Scanner software)
+  while (isset($value[0]) and $value[0] == chr(0))
+  {
+    $value = substr($value, 1);
+  }
+  // remove binary nulls
+  $value = str_replace(chr(0x00), ' ', $value);
+
+  //~ pwg_log('<<<<< pwg_clean_iptc_value() returns '.var_export($value, TRUE).' <<<<<'."\n");
+  return $value;
+}
+
+/**
+ * returns informations from IPTC metadata, mapping is done at the beginning
+ * of the function
+ *
+ * @param string $filename
+ * @param string $map
+ * @return array
+ */
+function pwg_get_iptc_data($filename, $map)
+{
+  //~ pwg_log('>>>>> pwg_get_iptc_data ($filename = '.var_export($filename, TRUE).', $map = '.var_export($map, TRUE).') >>>>>'."\n");
+  
+  $result = array();
+
+  // Read IPTC data
+  $iptc = array();
+
+  $imginfo = array();
+  getimagesize($filename, $imginfo);
+
+  if (isset($imginfo['APP13']))
+  {
+    $iptc = iptcparse($imginfo['APP13']);
+    if (is_array($iptc))
+    {
+      $rmap = array_flip($map);
+      foreach (array_keys($rmap) as $iptc_key)
+      {
+        if (isset($iptc[$iptc_key][0]))
+        {
+          if ($iptc_key == '2#025')
+          {
+            $value = implode(',', array_map('pwg_clean_iptc_value', $iptc[$iptc_key]));
+          }
+          else
+          {
+            $value = pwg_clean_iptc_value($iptc[$iptc_key][0]);
+          }
+
+          foreach (array_keys($map, $iptc_key) as $pwg_key)
+          {
+            $result[$pwg_key] = $value;
+          }
+        }
+      }
+    }
+  }
+  
+  //~ pwg_log('<<<<< pwg_get_iptc_data() returns '.var_export($result, TRUE).' <<<<<'."\n");
+  return $result;
+}
+
+/**
+ * returns informations from IPTC metadata
+ *
+ * @param string $file
+ * @return array iptc
+ */
+function pwg_get_sync_iptc_data($file)
+{
+  //~ pwg_log('>>>>> pwg_get_sync_iptc_data ($file = '.var_export($file, TRUE).') >>>>>'."\n");
+
+  global $conf;
+
+  $map = $conf['use_iptc_mapping'];
+  $datefields = array('date_creation', 'date_available');
+
+  $iptc = pwg_get_iptc_data($file, $map);
+
+  foreach ($iptc as $pwg_key => $value)
+  {
+    if (in_array($pwg_key, $datefields))
+    {
+      if ( preg_match('/(\d{4})(\d{2})(\d{2})/', $value, $matches))
+      {
+        $value = $matches[1].'-'.$matches[2].'-'.$matches[3];
+      }
+    }
+    if ($pwg_key == 'keywords')
+    {
+      // official keywords separator is the comma
+      $value = preg_replace('/[.;]/', ',', $value);
+      $value = preg_replace('/^,+|,+$/', '', $value);
+    }
+    $iptc[$pwg_key] = htmlentities($value);
+  }
+
+  $iptc['keywords'] = isset($iptc['keywords']) ? implode(',', array_unique(explode(',', $iptc['keywords']))) : NULL;
+
+  //~ pwg_log('<<<<< pwg_get_sync_iptc_data() returns '.var_export($iptc, TRUE).' <<<<<'."\n");
+  return $iptc;
+}
+
+/**
+ * return extension of the representative file
+ *
+ * @param string $file_dir
+ * @param string $file_short
+ * @return string
+ */
+function pwg_get_representative_ext($file_dir, $file_short)
+{
+  //~ pwg_log('>>>>> pwg_get_representative_ext($file_dir = '.var_export($file_dir, TRUE).', $file_short = '.var_export($file_short, TRUE).') >>>>>'."\n");
+  
+  global $conf;
+  
+  $rep_ext = '';
+  foreach ($conf['picture_ext'] as $ext)
+  {
+    if (file_exists($file_dir.'/'.$conf['represent'].'/'.$file_short.'.'.$ext))
+    {
+      $rep_ext = $ext;
+      break;
+    }
+  }
+  
+  //~ pwg_log('<<<<< pwg_get_representative_ext() returns '.var_export($rep_ext, TRUE).' <<<<<'."\n");
+  return $rep_ext; 
+}
+
+/**
+ * return 'true' if high resolution picture exists else ''
+ *
+ * @param string $file_dir
+ * @param string $file_base
+ * @return boolean
+ */
+function pwg_get_high($file_dir, $file_base)
+{
+  //~ pwg_log('>>>>> pwg_get_high($file = '.var_export($file_dir, TRUE).', $line = '.var_export($file_base, TRUE).') >>>>>'."\n");
+  
+  global $conf;
+  
+  $high = false;
+  if (file_exists($file_dir.'/'.$conf['high'].'/'.$file_base))
+  {
+    $high = true;
+  }
+  
+  //~ pwg_log('<<<<< pwg_get_high() returns '.var_export($high, TRUE).' <<<<<'."\n");
+  return $high; 
+}
+
+/**
+ * return filename without extension
+ *
+ * @param string $filename
+ * @return string
+ */
+function pwg_get_filename_wo_extension($filename)
+{
+  //~ pwg_log('>>>>> _get_filename_wo_extension($filename = '.var_export($filename, TRUE).') >>>>>'."\n");
+  
+  $short_name = substr($filename, 0, strrpos($filename, '.'));
+  
+  //~ pwg_log('<<<<< _get_filename_wo_extension() returns '.var_export($short_name, TRUE).' <<<<<'."\n");
+  return $short_name;
+}
+
+/**
+ * return extension of the thumbnail and complete error_log
+ *
+ * @param string $file_dir
+ * @param string $file_short
+ * @param string $file_ext
+ * @param string &$error_log
+ * @return string
+ */
+function pwg_get_thumbnail_ext($file_dir, $file_short, $file_ext, &$error_log)
+{
+  //~ pwg_log('>>>>> pwg_get_thumbnail_ext($file_dir = '.var_export($file_dir, TRUE).', $file_short = '.var_export($file_short, TRUE).') >>>>>'."\n");
+  
+  global $conf;
+  
+  $thumb_ext = '';
+  foreach ($conf['picture_ext'] as $ext)
+  {
+    if (file_exists($file_dir.'/'.$conf['thumbs'].'/'.$conf['prefix_thumbnail'].$file_short.'.'.$ext))
+    {
+      $thumb_ext = $ext;
+      break;
+    }
+  }
+  
+  if ($thumb_ext == '')
+  {
+    if ($conf['thumbnail'])
+    {
+      $log = pwg_icon_file($file_dir, $file_short, $file_ext);
+      if (strpos($log, 'success'))
+      {
+        $thumb_ext = $conf['thumbnail_format'];
+      }
+      $error_log .= $log;  
+    }
+  }
+  
+  //~ pwg_log('<<<<< pwg_get_thumbnail_ext() returns '.var_export($thumb_ext, TRUE).' <<<<<'."\n");
+  return $thumb_ext; 
+}
+
+
+/**
+ * return error logs
+ *
+ * @param string $file_dir
+ * @param string $file_short
+ * @param string $file_ext
+ * @return string
+ */
+function pwg_icon_file($file_dir, $file_short, $file_ext)
+{
+  //~ pwg_log('>>>>> pwg_icon_file($file_dir = '.var_export($file_dir, TRUE).', $file_short = '.var_export($file_short, TRUE).') >>>>>'."\n");
+  
+  global $conf, $pwg_conf;
+  
+  $error_log = '';
+  
+  // Get original properties (width, height)
+  if ($image_size = getimagesize($file_dir.'/'.$file_short.'.'.$file_ext))
+  {
+    $src_width = $image_size[0];
+    $src_height = $image_size[1];
+  }
+  else
+  {
+    $error_log .= '          <code class="failure">Failure -</code> Can not generate icon for <code>';
+    $error_log .= $file_dir.'/'.$file_short.'.'.$file_ext.'</code>';
+    $error_log .= ' <img src="'.$pwg_conf['icon_dir'].'add_tag.png" title="width/height are unreadable" /><br />'."\n";
+    return $error_log;
+  }
+  
+  // Check input format
+  $dst_format = $conf['thumbnail_format'];
+  $src_format = ($file_ext == 'jpg' or $file_ext == 'JPG') ? 'jpeg' : strtolower($file_ext);
+  if (!in_array($src_format, $pwg_conf['gd_supported_format']))
+  {
+    $error_log .= '          <code class="failure">Failure -</code> Can not generate icon for <code>';
+    $error_log .= $file_dir.'/'.$file_short.'.'.$file_ext.'</code>';
+    $error_log .= ' <img src="'.$pwg_conf['icon_dir'].'add_tag.png" title="format not supported" /><br />'."\n";
+    return $error_log;
+  }
+  
+  // Calculate icon properties (width, height)
+  switch ($conf['thumbnail_method'])
+  {
+    case 'fixed':
+    {
+      $dst_width  = $conf['thumbnail_width'];
+      $dst_height = $conf['thumbnail_height'];
+      break;
+    }
+    case 'width':
+    {
+      $dst_width  = $conf['thumbnail_width'];
+      $dst_height = $dst_width * $src_height / $src_width;
+      break;
+    }
+    case 'height':
+    {
+      $dst_height = $conf['thumbnail_height'];
+      $dst_width  = $dst_height * $src_width / $src_height;
+      break;
+    }
+    case 'ratio':
+    {
+      $dst_width  = round($src_width * $conf['thumbnail_ratio']);
+      $dst_height = round($src_height * $conf['thumbnail_ratio']);
+      break;
+    }
+    case 'exif':
+    default:
+    {
+      // Nothing to do
+    }
+  }
+  
+  // Creating icon
+  if ($conf['thumbnail_method'] == 'exif')
+  {
+    $src = exif_thumbnail($file_dir.'/'.$file_short.'.'.$file_ext, $width, $height, $imagetype);
+    if ($src === false)
+    {
+      $error_log .= '          <code class="failure">Failure -</code> No EXIF thumbnail in <code>';
+      $error_log .= $file_dir.'/'.$file_short.'.'.$file_ext.'</code><br />'."\n";
+      return $error_log;
+    }
+    $dst = imagecreatefromstring($src);
+    if ($src === false)
+    {
+      $error_log .= '          <code class="failure">Failure -</code> EXIF thumbnail format not supported in <code>';
+      $error_log .= $file_dir.'/'.$file_short.'.'.$file_ext.'</code><br />'."\n";
+      return $error_log;
+    }
+  }
+  else
+  {
+    if (($pwg_conf['gd_version_major'] != 2)) // or ($conf['thumbnail_format'] == 'gif'))
+    {
+      $dst = imagecreate($dst_width, $dst_height);
+    }
+    else
+    {
+      $dst = imagecreatetruecolor($dst_width, $dst_height);
+    }
+    $src = call_user_func('imagecreatefrom'.$src_format, $file_dir.'/'.$file_short.'.'.$file_ext);
+    if (!$src)
+    {
+      $error_log .= '          <code class="failure">Failure -</code> Internal error for <code>imagecreatefrom'.$src_format.'()</code>';
+      $error_log .= 'with <code>'.$file_dir.'/'.$file_short.'.'.$file_ext.'</code><br />'."\n";
+      return $error_log;
+    }
+     
+    if (($pwg_conf['gd_version_major'] != 2))
+    {
+      if (!imagecopyresized($dst, $src, 0, 0, 0, 0, $dst_width, $dst_height, $src_width, $src_height))
+      {
+        $error_log .= '          <code class="failure">Failure -</code> Internal error for <code>imagecopyresized()</code>';
+        $error_log .= 'with <code>'.$file_dir.'/'.$file_short.'.'.$file_ext.'</code><br />'."\n";
+        return $error_log;
+      }
+    }
+    else
+    {
+      if (!imagecopyresampled($dst, $src, 0, 0, 0, 0, $dst_width, $dst_height, $src_width, $src_height))
+      {
+        $error_log .= '          <code class="failure">Failure -</code> Internal error for <code>imagecopyresampled()</code>';
+        $error_log .= 'with <code>'.$file_dir.'/'.$file_short.'.'.$file_ext.'</code><br />'."\n";
+        return $error_log;
+      }
+    }
+  }
+  
+  if (!call_user_func('image'.$dst_format, $dst, $file_dir.'/'.$conf['thumbs'].'/'.$conf['prefix_thumbnail'].$file_short.'.'.$conf['thumbnail_format']))
+  {
+    $error_log .= '          <code class="failure">Failure -</code> Can not write <code>';
+    $error_log .= $file_dir.'/'.$conf['thumbs'].'/'.$conf['prefix_thumbnail'].$file_short.'.'.$file_ext.'</code> to generate thumbnail<br />'."\n";
+    return $error_log;
+  }
+  
+  $error_log .= '          <code class="success">Success -</code> Thumbnail generated for <code>';
+  $error_log .= $file_dir.'/'.$file_short.'.'.$file_ext.'</code><br />'."\n";
+
+  //~ pwg_log('<<<<< pwg_icon_file() returns '.var_export($error_log, TRUE).' <<<<<'."\n");
+  return $error_log; 
+}
+
+/**
+ * completes xml line <element .../> and returns error log
+ *
+ * @param string $file
+ * @param string &$line
+ * @return string
+ */
+function pwg_scan_file($file_full, &$line)
+{
+  //~ pwg_log('>>>>> pwg_scan_file($file = '.var_export($file_full, TRUE).', $line = '.var_export($line, TRUE).') >>>>>'."\n");
+  
+  global $conf, $pwg_conf;
+  
+  $error_log ='';
+  
+  $file_base  = basename($file_full);
+  $file_short = pwg_get_filename_wo_extension($file_base);
+  $file_ext   = pwg_get_file_extension($file_base);
+  $file_dir   = dirname($file_full);
+
+  $element['file'] = $file_base;
+  $element['path'] = dirname($pwg_conf['this_url']).substr($file_dir, 1).'/'.$file_base;
+  
+  if (in_array($file_ext, $conf['picture_ext']))
+  {
+    // Here we scan a picture : thumbnail is mandatory, high is optionnal, representative is not scanned
+    $element['tn_ext'] = pwg_get_thumbnail_ext($file_dir, $file_short, $file_ext, $error_log);
+    if ($element['tn_ext'] != '')
+    {
+      // picture has a thumbnail, get image width, heigth, size in Mo
+      $element['filesize'] = floor(filesize($file_full) / 1024);
+      if ($image_size = getimagesize($file_full))
+      {
+        $element['width'] = $image_size[0];
+        $element['height'] = $image_size[1];
+      }
+      
+      // get high resolution
+      if (pwg_get_high($file_dir, $file_base))
+      {
+        $element['has_high'] = 'true';
+        
+        $high_file = $file_dir.'/'.$conf['high'].'/'.$file_base;
+        $element['high_filesize'] = floor(filesize($high_file) / 1024);
+      }
+      
+      // get EXIF meta datas
+      if ($conf['use_exif'])
+      {
+        // Verify activation of exif module
+        if (extension_loaded('exif'))
+        {
+          if ($exif = read_exif_data($file_full))
+          {
+            foreach ($conf['use_exif_mapping'] as $pwg_key => $exif_key )
+            {
+              if (isset($exif[$exif_key]))
+              {
+                if ( in_array($pwg_key, array('date_creation','date_available') ) )
+                {
+                  if (preg_match('/^(\d{4}):(\d{2}):(\d{2})/', $exif[$exif_key], $matches))
+                    {
+                      $element[$pwg_key] = $matches[1].'-'.$matches[2].'-'.$matches[3];
+                    }
+                }
+                else
+                {
+                  $element[$pwg_key] = $exif[$exif_key];
+                }
+              }
+            }
+          }
+        }
+      }
+      
+      // get IPTC meta datas
+      if ($conf['use_iptc'])
+      {
+        $iptc = pwg_get_sync_iptc_data($file_full);
+        if (count($iptc) > 0)
+        {
+          foreach (array_keys($iptc) as $key)
+          {
+            $element[$key] = addslashes($iptc[$key]);
+          }
+        }
+      }
+      
+    }
+    else
+    {
+      $error_log .= '          <code class="failure">Failure -</code> Thumbnail is missing for <code>'.$file_dir.'/'.$file_base.'</code>';
+      $error_log .= ' <img src="'.$pwg_conf['icon_dir'].'add_tag.png" title="'.$file_dir.'/thumbnail/'.$conf['prefix_thumbnail'].$file_short;
+      $error_log .= '.xxx ('.implode(', ', $conf['picture_ext']).')" /><br />'."\n";
+    }
+  }
+  else
+  {
+    // Here we scan a non picture file : thumbnail and high are unused, representative is optionnal
+    $element['tn_ext'] = pwg_get_thumbnail_ext($file_dir, $file_short, $file_ext, $log);
+    $ext = pwg_get_representative_ext($file_dir, $file_short);
+    if ($ext != '')
+    {
+      $element['representative_ext'] = $ext;
+    }
+    $element['filesize'] = floor(filesize($file_full) / 1024);
+  }
+  
+  if (strlen($error_log) == 0)
+  {
+    $line = pwg_get_indent('element').'<element ';
+    foreach($element as $key => $value)
+    {
+      $line .= $key.'="'.$value.'" ';
+    }
+    $line .= '/>'."\n";
+  }
+  
+  //~ pwg_log('<<<<< pwg_scan_file() returns '.var_export($error_log, TRUE).' <<<<<'."\n");
+  return $error_log;
+}
+
+/**
+ * returns current level in tree
+ *
+ * @return integer
+ */
+function pwg_get_level($dir)
+{
+  //~ pwg_log('>>>>> pwg_get_level($dir = '.var_export($dir, TRUE).') >>>>>'."\n");
+  
+  $level = substr_count($dir, '/') - 1; // -1 because of ./ at the beginning of path
+  
+  //~ pwg_log('<<<<< pwg_get_level() returns '.var_export($level, TRUE).' <<<<<'."\n");
+  return $level;
+}
+
+/**
+ * returns indentation of element 
+ *
+ * @param string $element_type : 'root', 'element', 'dir'
+ * @return string
+ */
+function pwg_get_indent($element_type)
+{
+  //~ pwg_log('>>>>> pwg_get_indent($element_type = '.var_export($element_type, TRUE).') >>>>>'."\n");
+  
+  $level = substr_count($_SESSION['scan_list_fold'][0], '/') - 1; // because of ./ at the beginning
+  switch($element_type)
+  {
+    case 'dir' :
+    {
+      $indent = str_repeat(' ', 2*pwg_get_level($_SESSION['scan_list_fold'][0]));
+      break;
+    }
+    case 'root' :
+    {
+      $indent = str_repeat(' ', 2*pwg_get_level($_SESSION['scan_list_fold'][0])+2);
+      break;
+    }
+    case 'element' :
+    {
+      $indent = str_repeat(' ', 2*pwg_get_level($_SESSION['scan_list_fold'][0])+4);
+      break;
+    }
+    default :
+    {
+      $indent = '';
+      break;
+    }
+  }
+  
+  //~ pwg_log('<<<<< pwg_get_indent() returns '.var_export(strlen($indent), TRUE).' spaces <<<<<'."\n");
+  return $indent;
+}
+
+/**
+ * create index.php in directory and reserved sub_directories, return logs
+ *
+ * @param string dir
+ * @return string
+ */
+function pwg_protect_directories($directory)
+{
+  //~ pwg_log('>>>>> pwg_protect_directories($directory = '.var_export($directory, true).') >>>>>'."\n");
+  
+  global $conf;
+  
+  $error_log = '';
+  $dirlist = array($directory, $directory.'/'.$conf['thumbs'], $directory.'/'.$conf['high'], $directory.'/'.$conf['represent']);
+  
+  foreach ($dirlist as $dir)
+  {
+    if (file_exists($dir))
+    {
+      if (!file_exists($dir.'/index.php'))
+      {
+        $file = @fopen($dir.'/index.php', 'w');
+        if ($file != false)
+        {
+          fwrite($file, $pwg_conf['protect_content']); // the return code should be verified
+          $error_log .= '          <code class="success">Success -</code> index.php created in directory <a href="'.$dir.'">'.$dir."</a><br />\n";
+        }
+        else
+        {
+          $error_log .= '          <code class="failure">Failure -</code> Can not create index.php in directory <code>'.$dir."</code><br />\n";
+        }
+      }
+      else
+      {
+        if ($conf['protect_warnings'])
+        {
+          $error_log .= '          <code class="warning">Warning -</code> index.php already exists in directory <a href="'.$dir.'">'.$dir."</a><br />\n";
+        }
+      }
+    }
+  }
+  
+  //~ pwg_log('<<<<< pwg_protect_directories() returns '.var_export($error_log, true).' <<<<<'."\n");
+  return $error_log;
+}
+
+/**
+ * returns file extension (.xxx)
+ *
+ * @param string $file
+ * @return string
+ */
+function pwg_get_file_extension($file)
+{
+  //~ pwg_log('>>>>> pwg_get_file_extension($file = '.var_export($file, true).') >>>>>'."\n");
+  
+  $ext = substr(strrchr($file, '.'), 1, strlen ($file));
+  
+  //~ pwg_log('<<<<< pwg_get_file_extension() returns '.var_export($ext, true).' <<<<<'."\n");
+  return $ext;
+}
+
+/**
+ * completes directory list of supported files and returns error logs
+ *
+ * @param string $directory
+ * @return string
+ */
+function pwg_get_file_list($directory)
+{
+  //~ pwg_log('>>>>> pwg_get_file_list($directory = '.var_export($directory, true).') >>>>>'."\n");
+  
+  global $conf, $pwg_conf;
+
+  $errorLog = '';
+  $dir = opendir($directory);
+  while (($file = readdir($dir)) !== false)
+  {
+    switch (filetype($directory."/".$file))
+    {
+      case 'file' :
+      {
+        if (in_array(pwg_get_file_extension($file), $conf['file_ext']))
+        {
+          // The file pointed is a regular file with a supported extension
+          array_push($_SESSION['scan_list_file'], $directory.'/'.$file);
+          //~ pwg_log('--->> Push in $_SESSION[scan_list_file] value "'.$directory.'/'.$file.'"'."\n");
+          if (!preg_match('/^[a-zA-Z0-9-_.]+$/', $file))
+          {
+            $errorLog .= '          <code class="failure">Failure -</code> Invalid file name for <code>'.$file.'</code> in <code>'.$directory.'</code>';
+            $errorLog .= ' <img src="'.$pwg_conf['icon_dir'].'add_tag.png"';
+            $errorLog .= ' title="Name should be composed of letters, figures, -, _ or . ONLY" /><br />'."\n";
+          }
+        }
+        break; // End of filetype FILE
+      }
+      case 'dir' :
+      {
+        if(!in_array($file, $pwg_conf['reserved_directory_names']))
+        {
+          // The file pointed is a directory but neither system directory nor reserved by PWG
+          array_push($_SESSION['scan_list_fold'], $directory.'/'.$file);
+          //~ pwg_log('--->> Push in $_SESSION[scan_list_fold] value "'.$directory.'/'.$file.'"'."\n");
+          if (!preg_match('/^[a-zA-Z0-9-_.]+$/', $file))
+          {
+            $errorLog .= '          <code class="failure">Failure -</code> Invalid directory name for <code>'.$directory.'/'.$file.'</code>';
+            $errorLog .= ' <img src="'.$pwg_conf['icon_dir'].'add_tag.png"';
+            $errorLog .= ' title="Name should be composed of letters, figures, -, _ or . ONLY" /><br />'."\n";
+          }
+        }
+        break; // End of filetype DIR
+      }
+      case 'fifo' :
+      case 'char' :
+      case 'block' :
+      case 'link' :
+      case 'unknown':
+      default :
+      {
+        // PWG does not manage these cases
+        break;
+      }
+    }
+  }
+  closedir($dir);
+  
+  //~ pwg_log('<<<<< pwg_get_file_list() returns '.var_export($errorLog, true).' <<<<<'."\n");
+
+  return $errorLog;
+}
+
+/**
+ * returns a float value coresponding to the number of seconds since the
+ * unix epoch (1st January 1970) and the microseconds are precised :
+ * e.g. 1052343429.89276600
+ *
+ * @return float
+ */
+function pwg_get_moment()
+{
+  //~ pwg_log('>>>>> pwg_get_moment() >>>>>'."\n");
+  
+  $t1 = explode(' ', microtime());
+  $t2 = explode('.', $t1[0]);
+  $t2 = $t1[1].'.'.$t2[1];
+
+  //~ pwg_log('<<<<< pwg_get_moment() returns '.var_export($t2, true).' <<<<<'."\n");
+  return $t2;
+}
+
+/**
+ * return true if HTTP_REFERER and PHP_SELF are similar
+ *
+ * return boolean
+ */
+function pwg_referer_is_me()
+{
+  global $pwg_conf;
+
+  //~ pwg_log('>>>>> pwg_referer_is_me() >>>>>'."\n");
+  
+  $response = false;
+  $caller = (isset($_SERVER['HTTP_REFERER'])) ? $_SERVER['HTTP_REFERER'] : '';
+
+  if (strcasecmp($pwg_conf['this_url'], $caller) == 0) {
+    $response = true;
+  }
+
+  //~ pwg_log('<<<<< pwg_referer_is_me() returns '.var_export($response, true).' <<<<<'."\n");
+  return $response;
+}
+
+// +-----------------------------------------------------------------------+
+// |                                pwg_<ACTION>_<STEP> Functions          |
+// +-----------------------------------------------------------------------+
+
+function pwg_test_start()
+{
+  //~ pwg_log('>>>>> pwg_test_start() >>>>>'."\n");
+
+  global $g_message, $conf;
+  
+  if (isset($_REQUEST['version']))
+  {
+    if ($_REQUEST['version'] != $conf['version'])
+    {
+      $g_message = '0';
+    }
+    else
+    {
+      $g_message = '1';
+    }
+  }
+  else
+  {
+    $g_message  = '1';
+  }
+  $_SESSION['scan_step'] = 'exit';
+  
+  //~ pwg_log('<<<<< pwg_test_start() <<<<<'."\n");
+}
+
+function pwg_test_exit()
+{
+  //~ pwg_log('>>>>> pwg_test_exit() >>>>>'."\n");
+
+  global $g_header, $g_message, $g_footer, $conf, $pwg_conf;
+ 
+  if (pwg_referer_is_me())
+  {
+    $g_header  = ' : <span class="success">Test</span>'."\n";
+    $g_footer  = '<a href="'.$pwg_conf['this_url'].'" title="Main menu"><img src="'.$pwg_conf['icon_dir'].'up.png" /></a>'."\n";
+    
+    // Write version
+    $g_message  = '        <h3>Script version</h3>'."\n";
+    $g_message .= '        This script is tagged : <code class="failure">'.$conf['version'].'</code>'."\n";
+    // write GD support
+    if (!is_callable('gd_info'))
+    {
+      $g_message .= '        <code class="failure">Failure -</code> Your server can not generate imagess<br />'."\n";
+    }
+    else
+    {
+      $info = gd_info();
+      $gd_full_version = ereg_replace('[[:alpha:][:space:]()]+', '', $info['GD Version']);
+      list($gd_version) = preg_split('/[.]+/', $gd_full_version);
+      
+      $g_message .= '        <h3>Image generation</h3>'."\n";
+      $g_message .= '        <code class="success">Success -</code> Your server can generate images<br />'."\n";
+      $g_message .= '        <code class="warning">Warning -</code> Your server support GD'.$gd_version.' (v'.$gd_full_version.')<br />'."\n";
+      $format_list = array();
+      $format = ($info['GIF Create Support']) ? '<code>gif</code>' : NULL;
+      array_push($format_list, $format);
+      $format = ($info['JPG Support']) ? '<code>jpg</code>' : NULL;
+      array_push($format_list, $format);
+      $format = ($info['PNG Support']) ? '<code>png</code>' : NULL;
+      array_push($format_list, $format);
+      $g_message .= '        <code class="warning">Warning -</code> Your server support format: '.implode(', ', $format_list)."\n";
+    }
+    
+    $g_message .= '        <h3>Directory parsing</h3>'."\n";
+    if ($pwg_conf['safe_mode'])
+    {
+      $g_message .= '        <code class="warning">Warning -</code> Your server does not support to resize execution time'."\n";
+    }
+    else
+    {
+      $g_message .= '        <code class="success">Success -</code> Your server supports to resize execution time'."\n";
+    }
+  }
+  else
+  {
+    // compare version in GET parameter with $conf['version'] 
+    if ($g_message == '1')
+    {
+      exit('<pre>PWG-INFO-2: test successful</pre>');
+    }
+    else
+    {
+      exit('<pre>PWG-ERROR-4: Piwigo versions differs</pre>');
+    }
+  }
+  
+  //~ pwg_log('<<<<< pwg_test_exit() <<<<<'."\n");
+}
+
+function pwg_clean_start()
+{
+  //~ pwg_log('>>>>> pwg_clean_start() >>>>>'."\n");
+  
+  global $g_message;
+  
+  if(@unlink('./listing.xml'))
+  {
+    $g_message = '1';
+  }
+  else
+  {
+    $g_message = '0';
+  }
+
+  $_SESSION['scan_step'] = 'exit';
+  
+  //~ pwg_log('<<<<< pwg_clean_start() <<<<<'."\n");
+}
+
+function pwg_clean_exit()
+{
+  //~ pwg_log('>>>>> pwg_clean_exit() >>>>>'."\n");
+
+  global $g_header, $g_message, $g_footer, $conf, $pwg_conf;
+  
+  if(pwg_referer_is_me())
+  {
+    $g_header = ' : <span class="success">Clean</span>';
+    if ($g_message == '1')
+    {
+      $g_message = '        <code class="success">Success -</code> <code>listing.xml</code> file deleted'."\n";
+    }
+    else
+    {
+      $g_message = '        <code class="failure">Failure -</code> <code>listing.xml</code> does not exist or is read only'."\n";
+    }
+    $g_footer = '<a href="'.$pwg_conf['this_url'].'" title="Main menu"><img src="'.$pwg_conf['icon_dir'].'up.png" /></a>';
+  }
+  else
+  {
+    if ($g_message == '1')
+    {
+      exit('<pre>PWG-INFO-3 : listing.xml file deleted</pre>');
+    }
+    else
+    {
+      exit('<pre>PWG-ERROR-3 : listing.xml does not exist</pre>');
+    }
+  }
+  
+  //~ pwg_log('<<<<< pwg_clean_exit() <<<<<'."\n");
+}
+
+function pwg_generate_start()
+{
+  //~ pwg_log('>>>>> pwg_generate_start() >>>>>'."\n");
+  //~ pwg_log("GENARATE start >>>\n".var_export($_SESSION['scan_list_fold'], true)."\n".var_export($_SESSION['scan_list_file'], true)."\nGENERATE start >>>\n");
+
+  global $g_listing, $pwg_conf, $conf;
+  
+  // Flush line <informations>
+  $xml_header_url = dirname($pwg_conf['this_url']);
+  $xml_header_date = date('Y-m-d');
+  $xml_header_version = htmlentities($conf['version']);
+  
+  $attrs = array();
+  if ($conf['use_iptc'])
+  {
+    $attrs = array_merge($attrs, array_keys($conf['use_iptc_mapping']) );
+  }
+  if ($conf['use_exif'])
+  {
+    $attrs = array_merge($attrs, array_keys($conf['use_exif_mapping']) );
+  }
+  $xml_header_metadata = implode(',',array_unique($attrs));
+  
+  $xml_header = '<informations';
+  $xml_header .= ' generation_date="'.$xml_header_date.'"';
+  $xml_header .= ' phpwg_version="'.$xml_header_version.'"';
+  $xml_header .= ' metadata="'.$xml_header_metadata.'"';
+  $xml_header .= ' url="'.$xml_header_url.'/"';
+  $xml_header .= '>'."\n";
+  
+  fwrite($g_listing, $xml_header);
+  
+  // Initialization of directory and file lists
+  $_SESSION['scan_list_fold'] = array();
+  $_SESSION['scan_list_file'] = array();
+  $_SESSION['scan_logs'] .= pwg_get_file_list('.');
+  sort($_SESSION['scan_list_fold']);
+          
+  // Erase first file list because root directory does not contain images.
+  $_SESSION['scan_list_file'] = array();
+            
+  // What are we doing at next step
+  if(count($_SESSION['scan_list_fold']) > 0)
+  {
+    $_SESSION['scan_step'] = 'list';
+  }
+  else
+  {
+    $_SESSION['scan_step'] = 'stop';
+  }
+  
+  //~ pwg_log("GENARATE start <<<\n".var_export($_SESSION['scan_list_fold'], true)."\n".var_export($_SESSION['scan_list_file'], true)."\nGENERATE start <<<\n");
+  //~ pwg_log('<<<<< pwg_generate_start() <<<<<'."\n");
+}
+
+function pwg_generate_list()
+{
+  //~ pwg_log('>>>>> pwg_generate_list() >>>>>'."\n");
+  //~ pwg_log("GENARATE list >>>\n".var_export($_SESSION['scan_list_fold'], true)."\n".var_export($_SESSION['scan_list_file'], true)."\nGENERATE list >>>\n");
+  
+  global $g_listing;
+  
+  // Flush line <dirX name=""> in xml file
+  $dirname = basename($_SESSION['scan_list_fold'][0]);
+  $line = pwg_get_indent('dir').'<dir'.pwg_get_level($_SESSION['scan_list_fold'][0]).' name="'.$dirname.'">'."\n";
+  fwrite($g_listing, $line);
+  
+  // Get list of files and directories
+  $_SESSION['scan_logs'] .= pwg_get_file_list($_SESSION['scan_list_fold'][0]);
+  sort($_SESSION['scan_list_fold']); // Mandatory to keep the tree order
+  sort($_SESSION['scan_list_file']); // Easier to read when sorted
+  
+  // Flush line <root>
+  $line = pwg_get_indent('root').'<root>'."\n";
+  fwrite($g_listing, $line);
+  
+  // What are we doing at next step
+  $_SESSION['scan_step'] = 'scan';
+  
+  //~ pwg_log("GENARATE list <<<\n".var_export($_SESSION['scan_list_fold'], true)."\n".var_export($_SESSION['scan_list_file'], true)."\nGENERATE list <<<\n");
+  //~ pwg_log('<<<<< pwg_generate_list() <<<<<'."\n");
+}
+
+function pwg_generate_scan()
+{
+  //~ pwg_log('>>>>> pwg_generate_scan() >>>>>'."\n");
+  //~ pwg_log("GENARATE scan >>>\n".var_export($_SESSION['scan_list_fold'], true)."\n".var_export($_SESSION['scan_list_file'], true)."\nGENERATE scan >>>\n");
+  
+  global $g_listing, $conf;
+  
+  while (pwg_continue() and count($_SESSION['scan_list_file']) > 0)
+  {
+    $line = '';
+    $_SESSION['scan_logs'] .= pwg_scan_file($_SESSION['scan_list_file'][0], $line);
+    
+    if (strlen($line) > 0)
+    {
+      fwrite($g_listing, $line);
+    }
+    //~ pwg_log('---<< Pull of $_SESSION[scan_list_file] value "'.$_SESSION['scan_list_file'][0].'"'."\n");
+    array_shift($_SESSION['scan_list_file']);
+    $_SESSION['scan_cnt_file']++;
+  }
+          
+  if (count($_SESSION['scan_list_file']) <= 0)
+  {
+    $_SESSION['scan_step'] = 'prot';
+  }
+  
+  //~ pwg_log("GENERATE scan <<<\n".var_export($_SESSION['scan_list_fold'], true)."\n".var_export($_SESSION['scan_list_file'], true)."\nGENERATE scan <<<\n");
+  //~ pwg_log('<<<<< pwg_generate_scan() <<<<<'."\n");
+}
+
+function pwg_generate_prot()
+{
+  //~ pwg_log('>>>>> pwg_generate_prot() >>>>>'."\n");
+  //~ pwg_log("GENARATE prot >>>\n".var_export($_SESSION['scan_list_fold'], true)."\n".var_export($_SESSION['scan_list_file'], true)."\nGENERATE prot >>>\n");
+  
+  global $conf, $g_listing;
+  
+  // Flush line </root>
+  $line = pwg_get_indent('root').'</root>'."\n";
+  fwrite($g_listing, $line);
+  
+  if ($conf['protect'])
+  {
+    $_SESSION['scan_logs'] .= pwg_protect_directories($_SESSION['scan_list_fold'][0]);
+  }
+  
+  // How many directories to close
+  $current_level = pwg_get_level($_SESSION['scan_list_fold'][0]);
+  if (isset($_SESSION['scan_list_fold'][1]))
+  {
+    //~ pwg_log('---<< Pull of $_SESSION[scan_list_fold] value "'.$_SESSION['scan_list_fold'][0].'"'."\n");
+    array_shift($_SESSION['scan_list_fold']);
+    $_SESSION['scan_cnt_fold']++;
+    $next_level = pwg_get_level($_SESSION['scan_list_fold'][0]);
+    $_SESSION['scan_step'] = 'list';
+  }
+  else
+  {
+    $next_level = -1;
+    $_SESSION['scan_cnt_fold']++;
+    $_SESSION['scan_step'] = 'stop';
+  }
+  
+  if ($current_level == $next_level)
+  {
+    fwrite($g_listing, pwg_close_level($current_level, 1));
+  }
+  else
+  {
+    if (($current_level > $next_level))
+    {
+      fwrite($g_listing, pwg_close_level($current_level, $current_level-$next_level+1));
+    } // Nothing to do if current_level < next_level
+  }
+
+  //~ pwg_log("GENERATE prot <<<\n".var_export($_SESSION['scan_list_fold'], true)."\n".var_export($_SESSION['scan_list_file'], true)."\nGENERATE prot <<<\n");
+  //~ pwg_log('<<<<< pwg_generate_prot() <<<<<'."\n");
+}
+
+function pwg_generate_stop()
+{
+  //~ pwg_log('>>>>> pwg_generate_stop() >>>>>'."\n");
+  //~ pwg_log("GENARATE stop >>>\n".var_export($_SESSION['scan_list_fold'], true)."\n".var_export($_SESSION['scan_list_file'], true)."\nGENERATE stop >>>\n");
+  
+  global $pwg_conf, $g_listing, $g_header, $g_message, $g_footer;
+  
+  // Flush line </informations>
+  fwrite($g_listing, '</informations>'."\n");
+  
+  // backup error log before cleaning session
+  $time_elapsed = number_format(pwg_get_moment() - $_SESSION['scan_time'], 3, '.', ' ');
+  
+  $g_header   = ' : <span class="success">Generate</span>';
+  $g_message  = '        <div>'."\n".$_SESSION['scan_logs'].'        </div>'."\n";
+  $g_message .= '        <div><code class="success">'.$_SESSION['scan_cnt_fold'].'</code> directories parsed<br />'."\n";
+  $g_message .= '        <code class="success">'.$_SESSION['scan_cnt_file'].'</code> files scanned</div>'."\n";
+  $g_message .= '        <div>View <a href="listing.xml">listing.xml</a></div>'."\n";
+  $g_message .= '        <div style="{text-align: right;}">Listing generated in : <code>'.$time_elapsed.' s</code></div>';
+  $g_footer   = '<a href="'.$pwg_conf['this_url'].'" title="Main menu"><img src="'.$pwg_conf['icon_dir'].'up.png" /></a>';
+      
+  // What are we doing at next step
+  $_SESSION['scan_step'] = 'exit';
+  
+  //~ pwg_log("GENARATE stop <<<\n".var_export($_SESSION['scan_list_fold'], true)."\n".var_export($_SESSION['scan_list_file'], true)."\nGENERATE stop <<<\n");
+  //~ pwg_log('<<<<< pwg_generate_stop() <<<<<'."\n");
+}
+
+// +-----------------------------------------------------------------------+
+// |                                ALWAYS CALLED FUNCTIONS                |
+// +-----------------------------------------------------------------------+
+
+/**
+ * This function check step and time ellapsed to determine end of loop
+ *
+ * @return bool
+ */
+function pwg_continue()
+{
+  //~ pwg_log('>>>>> pwg_continue() >>>>>'."\n");
+  
+  global $conf, $pwg_conf, $g_refresh, $g_header, $g_message, $g_footer, $start_time;
+  
+  if (!isset($_SESSION['scan_step']) or $_SESSION['scan_step'] == 'exit')
+  {
+    // evident end of process
+    $return = false;
+  }
+  else
+  {
+    if ($pwg_conf['safe_mode'] or $conf['force_refresh_method'])
+    {
+      // can not reset the time
+      $time_elapsed = pwg_get_moment() - $start_time;
+      if ($time_elapsed < $conf['max_execution_time'])
+      {
+        $return = true;
+      }
+      else
+      {
+        $start_time = $_SESSION['scan_time'];
+        $formated_time = number_format(pwg_get_moment() - $start_time, 3, '.', ' ');
+
+        $g_refresh = '<meta http-equiv="Refresh" content="'.$conf['refresh_delay'].'">'."\n";
+        $g_header  = ' : <span class="success">'.ucfirst($_SESSION['scan_action']).'</span>';
+        $g_message = '';
+        if ($_SESSION['scan_cnt_fold'] != 0)
+        {
+          $g_message .= '<code class="success">'.$_SESSION['scan_cnt_fold'].'</code> directories scanned<br />'."\n";
+        }
+        if ($_SESSION['scan_cnt_file'] != 0)
+        {
+          $g_message .= '<code class="success">'.$_SESSION['scan_cnt_file'].'</code> files scanned<br />'."\n";
+        }
+        $nb = count($_SESSION['scan_list_fold']);
+        if ($nb > 0)
+        {
+          $g_message .= '<code class="warning">'.$nb.'</code> directories to scan<br />'."\n";
+        }
+        $nb = count($_SESSION['scan_list_file']);
+        if ($nb > 0)
+        {
+          $g_message .= '<code class="warning">'.$nb.'</code> files to scan<br />'."\n";
+        }
+        $g_message .= '        <div style="{text-align: right;}">Time elapsed : <code>'.$formated_time.' s</code></div>';
+        $g_footer  = '<a href="'.$pwg_conf['this_url'].'?action='.$_SESSION['scan_action'].'" title="Continue"><img src="'.$pwg_conf['icon_dir'].'right.png" /></a>'."\n";
+        
+        $return = false;
+      }
+    }
+    else
+    {
+      // reset the time
+      set_time_limit(intval(ini_get('max_execution_time')));
+      $return = true;
+    }
+  }
+  //~ pwg_log('<<<<< pwg_continue() returns '.var_export($return, true).' <<<<<'."\n");
+  
+  return $return;
+}
+
+/**
+ * This function :
+ * -> Verify the script call
+ * -> Lock the script
+ * -> Open listing.xml if action is 'generate'
+ * -> Initialize output and session variables
+ *
+ * @return nothing
+ */
+function pwg_init()
+{
+  //~ pwg_log('>>>>> pwg_init() >>>>>'."\n");
+
+  global $g_message, $g_listing, $g_footer, $conf, $pwg_conf, $start_time;
+  $init_message = '';
+  
+  // Lock other script sessions, this lock will be remove during 'exit' step
+  if (!isset($_SESSION['scan_step']))
+  {
+    $fp = @fopen(__FILE__.'.lock', 'x+'); // return false if __FILE__.lock exists or if cannot create
+    if ($fp == false)
+    {
+      $g_header   = $_SESSION['scan_action'];
+      $g_message  = '        <code class="failure">Failure -</code> Another script is running';
+      $g_message .= ' <img src="'.$pwg_conf['icon_dir'].'add_tag.png" title="Delete file '.__FILE__.'.lock and retry" />';
+      $g_message .= "\n";
+      $g_footer   = '<a href="'.$pwg_conf['this_url'].'" title="Main menu"><img src="'.$pwg_conf['icon_dir'].'up.png" /></a>'."\n";
+      $_SESSION['scan_step'] = 'exit';
+      //~ pwg_log('<<<<< pwg_init() failure <<<<<'."\n");
+      return;
+    }
+    else
+    {
+      fwrite($fp, session_id()); // Writing session_id to trace lock
+      fclose($fp);
+      $_SESSION['scan_step'] = 'init';
+    }
+  }
+  
+  // Verify and backup parameter action. This backup will be removed during step 'exit'
+  if (isset($_REQUEST['action']))
+  {
+    if (in_array($_REQUEST['action'], $pwg_conf['scan_action']))
+    {
+      if (isset($_SESSION['scan_action']))
+      {
+        if ($_SESSION['scan_action'] != $_REQUEST['action'])
+        {
+          // Fatal error
+          $g_message  = '        <code class="failure">Failure -</code> Parameter <code>action</code> differs between url and session';
+          $g_message .= "\n";
+          $g_footer   = '<a href="'.$pwg_conf['this_url'].'" title="Main menu"><img src="'.$pwg_conf['icon_dir'].'up.png" /></a>'."\n";
+          $_SESSION['scan_step'] = 'exit';
+          //~ pwg_log('<<<<< pwg_init() failure <<<<<'."\n");
+          return;
+        }
+      }
+      else
+      {
+        $_SESSION['scan_action'] = $_REQUEST['action'];
+      }
+    }
+    else
+    {
+      // Fatal error
+      $g_message  = '        <code class="failure">Failure -</code> Problem with <code>action</code> parameter';
+      $g_message .= ' <img src="'.$pwg_conf['icon_dir'].'add_tag.png" title="empty, '.implode(', ', $pwg_conf['scan_action']).'" />';
+      $g_message .= "\n";
+      $g_footer   = '<a href="'.$pwg_conf['this_url'].'" title="Main menu"><img src="'.$pwg_conf['icon_dir'].'up.png" /></a>'."\n";
+      $_SESSION['scan_step'] = 'exit';
+      //~ pwg_log('<<<<< pwg_init() failure <<<<<'."\n");
+      return;
+    }
+  }
+  else
+  {
+    // Here we are on welcome page
+    $g_message  = '        <ul>'."\n";
+    $g_message .= '          <li><a href="'.$pwg_conf['this_url'].'?action=test" title="Display/Compare script version">Test</a></li>'."\n";
+    $g_message .= '          <li><a href="'.$pwg_conf['this_url'].'?action=clean" title="Delete listing.xml if exists">Clean</a></li>'."\n";
+    $g_message .= '          <li><a href="'.$pwg_conf['this_url'].'?action=generate" title="Scan all images from this directory and write informations in listing.xml">Listing</a></li>'."\n";
+    $g_message .= '        </ul>'."\n";
+    $g_footer   = '<a href="'.$conf['gallery'].'/admin.php?page=site_manager" title="Main gallery :: site manager">';
+    $g_footer  .= '<img src="'.$pwg_conf['icon_dir'].'home.png" /></a>'."\n";
+    $_SESSION['scan_step'] = 'exit';
+    $_SESSION['scan_action'] = '';
+  }
+  
+  // Actions to do at the init of generate
+  if ($_SESSION['scan_action'] == 'generate')
+  {
+    // Open XML file
+    $mode = ($_SESSION['scan_step'] == 'init') ? 'w' : 'a'; // Erase old listing.xml at the beginning of generation (mode w)
+    $g_listing = @fopen('listing.xml', $mode);
+    if ($g_listing === false)
+    {
+      $g_header   = $_SESSION['scan_action'];
+      $g_message  = '        <code class="failure">Failure -</code> Can not write file <code>listing.xml</code>';
+      $g_message .= "\n";
+      $g_footer   = '<a href="'.$pwg_conf['this_url'].'" title="Main menu"><img src="'.$pwg_conf['icon_dir'].'up.png" /></a>'."\n";
+      $_SESSION['scan_step'] = 'exit';
+      //~ pwg_log('<<<<< pwg_init() failure <<<<<'."\n");
+      return;
+    }
+    
+    // Check graphical capabilities
+    $init_message = pwg_check_graphics();
+  }
+    
+  // Initializing session counters. This counters will be completely unset during step 'exit'
+  if ($_SESSION['scan_step'] == 'init')
+  {
+    $_SESSION['scan_list_file'] = array();
+    $_SESSION['scan_list_fold'] = array();
+    $_SESSION['scan_cnt_file'] = 0;
+    $_SESSION['scan_cnt_fold'] = 0;
+    $_SESSION['scan_time'] = $start_time;
+    $_SESSION['scan_step'] = 'start';
+    $_SESSION['scan_logs'] = $init_message;
+  }
+  
+  //~ pwg_log('<<<<< pwg_init() success <<<<<'."\n");
+}
+
+/**
+ * This function :
+ * -> Close listing.xml if action is 'generate'
+ * -> Unlock the script
+ * -> Erase session variables
+ *
+ * @return nothing
+ */
+function pwg_exit()
+{
+  //~ pwg_log('>>>>> pwg_exit() >>>>>'."\n");
+  
+  global $g_listing;
+  
+  // Close XML file
+  if ($_SESSION['scan_action'] == 'generate' and $g_listing != false)
+  {
+    fclose($g_listing);
+  }
+  
+  // Unlock script
+  unlink(__FILE__.'.lock');
+  
+  // Erase session counters
+  unset($_SESSION['scan_list_file']);
+  unset($_SESSION['scan_list_fold']);
+  unset($_SESSION['scan_cnt_file']);
+  unset($_SESSION['scan_cnt_fold']);
+  unset($_SESSION['scan_time']);
+  unset($_SESSION['scan_step']);
+  $local_action = $_SESSION['scan_action'];
+  unset($_SESSION['scan_action']);
+  unset($_SESSION['scan_logs']);
+  session_destroy();
+  
+  // Call specific action post process
+  if (is_callable('pwg_'.$local_action.'_exit'))
+  {
+    call_user_func('pwg_'.$local_action.'_exit');
+  }
+  
+  //~ pwg_log('<<<<< pwg_exit() <<<<<'."\n");
+}
+
+// +-----------------------------------------------------------------------+
+// |                                Script                                 |
+// +-----------------------------------------------------------------------+
+session_save_path('.');
+session_start();
+
+$start_time = pwg_get_moment();
+
+// Initializing message for web page
+$g_refresh = '';
+$g_header  = '';
+$g_message = '';
+$g_footer  = '';
+$g_listing = '';
+
+pwg_init();
+
+while(pwg_continue())
+{
+  if (is_callable('pwg_'.$_SESSION['scan_action'].'_'.$_SESSION['scan_step']))
+  {
+    call_user_func('pwg_'.$_SESSION['scan_action'].'_'.$_SESSION['scan_step']); // Run the step : start, list, scan, stop are available
+  }
+  else
+  {
+    $g_header   = $_SESSION['scan_action'];
+    $g_message  = '        <code class="failure">Failure -</code> INTERNAL STEP ERROR : <code>pwg_'.$_SESSION['scan_action'].'_'.$_SESSION['scan_step'].'()</code> undefined';
+    $g_message .= "\n";
+    $g_footer   = '<a href="'.$pwg_conf['this_url'].'" title="Main menu"><img src="'.$pwg_conf['icon_dir'].'up.png" /></a>'."\n";
+    $_SESSION['scan_step'] = 'exit';
+  }
+}
+
+if ($_SESSION['scan_step'] == 'exit')
+{
+  pwg_exit();
+}
+
+?>
+<html>
+  <head>
+  <?php echo $g_refresh; ?>
+  <title>Manage remote gallery</title>
+  </head>
+    <style type="text/css">
+      code {font-weight: bold}
+      img {border-style: none; vertical-align: middle}
+      ul {list-style-image: url(<?php echo $pwg_conf['icon_dir']; ?>add_tag.png)}
+      .success {color: green}
+      .warning {color: orange}
+      .failure {color: red}
+      .header {text-align: center; font-variant: small-caps; font-weight: bold;}
+      .p {color: #F93;}
+      .w {color: #ccc;}
+      .g {color: #69C;}
+      .pwg {text-decoration: none; border-bottom-style: dotted; border-bottom-width: 1px;}
+      .content {width: 75%; position: absolute; top: 10%; left: 12%;}
+      .footer {text-align: right;}
+      .pwg_block {float: left;}
+    </style>
+  <body>
+    <div class="content">
+      <fieldset class="header">
+        <span class="p">Pi</span>
+        <span class="w">wi</span>
+        <span class="g">go</span>
+        &nbsp;remote site<? echo $g_header; ?>
+      </fieldset>
+      <fieldset>
+<?php echo $g_message; ?>
+      </fieldset>
+      <fieldset class="footer">
+        <div class="pwg_block">
+          Powered by <a href="http://piwigo.org" class="pwg">Piwigo</a>
+        </div>
+        <?php echo $g_footer; ?>
+      </fieldset>
+    </div>
+  </body>
+</html>
Index: /tags/2.0.2/tools/create_listing_file_local.inc.php
===================================================================
--- /tags/2.0.2/tools/create_listing_file_local.inc.php	(revision 3278)
+++ /tags/2.0.2/tools/create_listing_file_local.inc.php	(revision 3278)
@@ -0,0 +1,14 @@
+<?php
+// this file is provided as an example.
+// Move it to "create_listing_file.php"
+// directory if you want to modify default configuration.
+
+// URL of main gallery
+// Example : http://www.my.domain/my/directory
+$conf['gallery'] = 'http://demo.piwigo.net/';
+
+$conf['file_ext'] = array_merge($conf['file_ext'], array('flv', 'FLV'));
+
+$conf['force_refresh_method'] =  true;
+
+?>
Index: /tags/2.0.2/tools/fill_history.pl
===================================================================
--- /tags/2.0.2/tools/fill_history.pl	(revision 3278)
+++ /tags/2.0.2/tools/fill_history.pl	(revision 3278)
@@ -0,0 +1,336 @@
+#!/usr/bin/perl
+
+use warnings;
+use strict;
+use Getopt::Long;
+use DBI;
+use File::Basename;
+use Time::Local;
+use List::Util qw/shuffle min/;
+
+my %opt;
+GetOptions(
+    \%opt,
+    qw/dbname=s dbuser=s dbpass=s prefix=s
+       total=i start_date=s end_date=s
+       help/
+   );
+
+if (defined($opt{help}))
+{
+  print <<FIN;
+
+Fill the user comments table of Piwigo.
+
+Usage: pwg_fill_comments.pl --dbname=<database_name>
+                            --dbuser=<username>
+                            --dbpass=<password>
+                            --tagfile=<tags filename>
+                            [--prefix=<tables prefix>]
+                            [--help]
+
+--dbname, --dbuser and --dbpass are connexion parameters.
+
+--tagfile
+
+--prefix : determines the prefix for your table names.
+
+--help : show this help
+
+FIN
+
+  exit(0);
+}
+
+my $usage = "\n\n".basename($0)." --help for help\n\n";
+
+foreach my $option (qw/dbname dbuser dbpass start_date end_date/) {
+  if (not exists $opt{$option}) {
+    die 'Error: '.$option.' is a mandatory option', $usage;
+  }
+}
+
+$opt{prefix} = 'piwigo_' if (not defined $opt{prefix});
+my $dbh = DBI->connect(
+    'DBI:mysql:'.$opt{dbname},
+    $opt{dbuser},
+    $opt{dbpass}
+);
+
+my $query;
+my $sth;
+
+
+# retrieve all available users
+$query = '
+SELECT id
+  FROM '.$opt{prefix}.'users
+';
+my @user_ids = keys %{ $dbh->selectall_hashref($query, 'id') };
+
+# set a list of IP addresses for each users
+my %user_IPs = ();
+foreach my $user_id (@user_ids) {
+    for (1 .. 1 + int rand 5) {
+        push(
+            @{ $user_IPs{$user_id} },
+            join(
+                '.',
+                map {1 + int rand 255} 1..4
+            )
+        );
+    }
+}
+
+# use Data::Dumper; print Dumper(\%user_IPs); exit();
+
+# start and end dates
+my ($year,$month,$day,$hour,$min,$sec)
+     = ($opt{start_date} =~ m/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/);
+my $start_unixtime = timelocal(0,0,0,$day,$month-1,$year);
+
+($year,$month,$day,$hour,$min,$sec)
+     = ($opt{end_date} =~ m/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/);
+my $end_unixtime = timelocal(0,0,0,$day,$month-1,$year);
+
+# "tags from image" and "images from tag"
+$query = '
+SELECT image_id, tag_id
+  FROM '.$opt{prefix}.'image_tag
+';
+my %image_tags = ();
+my %tag_images = ();
+my %related_tag_of = ();
+my @tags = ();
+$sth = $dbh->prepare($query);
+$sth->execute();
+while (my $row = $sth->fetchrow_hashref()) {
+    push(
+        @{$image_tags{$row->{image_id}}},
+        $row->{tag_id}
+    );
+
+    push(
+        @{$tag_images{$row->{tag_id}}},
+        $row->{image_id}
+    );
+
+    push (
+        @tags,
+        $row->{tag_id}
+    );
+}
+
+# foreach my $tag_id (keys %tag_images) {
+#     printf(
+#         "tag %5u: %5u images\n",
+#         $tag_id,
+#         scalar @{$tag_images{$tag_id}}
+#     );
+# }
+# exit();
+
+# use Data::Dumper; print Dumper(\%tag_images); exit();
+
+# categories from image_id
+$query = '
+SELECT image_id, category_id
+  FROM '.$opt{prefix}.'image_category
+';
+my %image_categories = ();
+my %category_images =();
+my %categories = ();
+$sth = $dbh->prepare($query);
+$sth->execute();
+while (my $row = $sth->fetchrow_hashref()) {
+    push(
+        @{$image_categories{$row->{image_id}}},
+        $row->{category_id}
+    );
+
+    push(
+        @{$category_images{$row->{category_id}}},
+        $row->{image_id}
+    );
+
+    $categories{ $row->{category_id} }++;
+}
+
+my @images = keys %image_categories;
+my @categories = keys %categories;
+
+# use Data::Dumper;
+# print Dumper(\%image_categories);
+
+my @sections = (
+    'categories',
+#     'tags',
+#     'search',
+#     'list',
+#     'favorites',
+#     'most_visited',
+#     'best_rated',
+#     'recent_pics',
+#     'recent_cats',
+);
+
+my @inserts = ();
+
+USER : foreach my $user_id (@user_ids) {
+    print 'user_id: ', $user_id, "\n";
+
+    my $current_unixtime = $start_unixtime;
+    my @IPs = @{ $user_IPs{$user_id} };
+
+    VISIT : foreach my $visit_num (1..100_000) {
+        print 'visit: ', $visit_num, "\n";
+        my @temp_inserts = ();
+        my $IP = (@IPs)[int rand @IPs];
+        my $current_page = 0;
+        my $visit_size = 10 + int rand 90;
+        $current_unixtime+= 86_400 + int rand(86_400 * 30);
+
+        my $section = $sections[int rand scalar @sections];
+        # print 'section: ', $section, "\n";
+
+        push(
+            @temp_inserts,
+            {
+                section => $section,
+            }
+        );
+
+        if ($section eq 'categories') {
+            CATEGORY : foreach my $category_id (
+                (shuffle @categories)[1..int rand scalar @categories]
+            ) {
+                # print 'category: ', $category_id, "\n";
+                push(
+                    @temp_inserts,
+                    {
+                        category_id => $category_id,
+                    }
+                );
+
+                my @images = @{$category_images{$category_id}};
+                IMAGE : foreach my $image_id (
+                    (shuffle @images)[1..min(10, scalar @images)]
+                ) {
+                    push(
+                        @temp_inserts,
+                        {
+                            category_id => $category_id,
+                            image_id => $image_id,
+                        }
+                    );
+                }
+            }
+        }
+
+        if ($section eq 'tags') {
+            # TODO
+        }
+
+        # transfert @temp_inserts to @inserts
+        print 'temp_insert size: ', scalar @temp_inserts, "\n";
+        foreach my $temp_insert (@temp_inserts) {
+            $current_unixtime+= 5 + int rand 25;
+            next VISIT if ++$current_page == $visit_size;
+            last VISIT if $current_unixtime >= $end_unixtime;
+
+            my $date = unixtime_to_mysqldate($current_unixtime);
+            my $time = unixtime_to_mysqltime($current_unixtime);
+
+            my ($year, $month, $day) = split '-', $date;
+            my ($hour) = split ':', $time;
+
+            $temp_insert->{date} = $date;
+            $temp_insert->{time} = $time;
+            $temp_insert->{year} = $year;
+            $temp_insert->{month} = $month;
+            $temp_insert->{day} = $day;
+            $temp_insert->{hour} = $hour;
+            $temp_insert->{IP} = $IP;
+            $temp_insert->{section} = $section;
+            $temp_insert->{user_id} = $user_id;
+
+            push(@inserts, $temp_insert);
+        }
+    }
+}
+
+@inserts = sort {
+    $a->{date} cmp $b->{date}
+    or $a->{time} cmp $b->{time}
+} @inserts;
+
+if (scalar @inserts) {
+    my @columns =
+        qw/
+              date time year month day hour
+              user_id IP
+              section category_id image_id
+          /;
+
+    my $question_marks_string = '(';
+    $question_marks_string.= join(
+        ',',
+        map {'?'} @columns
+    );
+    $question_marks_string.= ')';
+
+    my $query = '
+INSERT INTO '.$opt{prefix}.'history
+  ('.join(', ', @columns).')
+  VALUES
+';
+    $query.= join(
+        ',',
+        map {$question_marks_string} (1 .. scalar @inserts)
+    );
+    $query.= '
+';
+
+    # print $query, "\n";
+
+    my @values = ();
+
+    foreach my $insert (@inserts) {
+        push(
+            @values,
+            map {
+                $insert->{$_}
+            } @columns
+        );
+    }
+
+    $sth = $dbh->prepare($query);
+    $sth->execute(@values)
+        or die 'cannot execute insert query';
+}
+
+sub unixtime_to_mysqldate {
+    my ($unixtime) = @_;
+
+    ($sec,$min,$hour,$day,$month,$year) = localtime($unixtime);
+
+    return sprintf(
+        '%d-%02d-%02d',
+        $year+1900,
+        $month+1,
+        $day,
+    );
+}
+
+sub unixtime_to_mysqltime {
+    my ($unixtime) = @_;
+
+    ($sec,$min,$hour,$day,$month,$year) = localtime($unixtime);
+
+    return sprintf(
+        '%d:%d:%d',
+        $hour,
+        $min,
+        $sec
+    );
+}
Index: /tags/2.0.2/tools/index.php
===================================================================
--- /tags/2.0.2/tools/index.php	(revision 3278)
+++ /tags/2.0.2/tools/index.php	(revision 3278)
@@ -0,0 +1,30 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: /tags/2.0.2/tools/local-layout.css
===================================================================
--- /tags/2.0.2/tools/local-layout.css	(revision 3278)
+++ /tags/2.0.2/tools/local-layout.css	(revision 3278)
@@ -0,0 +1,10 @@
+/* Add background picture */
+BODY {
+  background-image:url(background.gif);
+  background-attachment:fixed;
+}
+
+.content UL.thumbnails SPAN.wrap2 {
+  height: 200px; /* max thumbnail height + 2px */
+}
+
Index: /tags/2.0.2/tools/metadata.php
===================================================================
--- /tags/2.0.2/tools/metadata.php	(revision 3278)
+++ /tags/2.0.2/tools/metadata.php	(revision 3278)
@@ -0,0 +1,97 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+$filename = 'sample.jpg';
+echo 'Informations are read from '.$filename.'<br /><br /><br />';
+
+/**
+ * return a cleaned IPTC value
+ *
+ * @param string value
+ * @return string
+ */
+function clean_iptc_value($value)
+{
+  // strip leading zeros (weird Kodak Scanner software)
+  while ( isset($value[0]) and $value[0] == chr(0))
+  {
+    $value = substr($value, 1);
+  }
+  // remove binary nulls
+  $value = str_replace(chr(0x00), ' ', $value);
+
+  return $value;
+}
+
+$iptc_result = array();
+$imginfo = array();
+getimagesize($filename, $imginfo);
+if (isset($imginfo['APP13']))
+{
+  $iptc = iptcparse($imginfo['APP13']);
+  if (is_array($iptc))
+  {
+    foreach (array_keys($iptc) as $iptc_key)
+    {
+      if (isset($iptc[$iptc_key][0]))
+      {
+        if ($iptc_key == '2#025')
+        {
+          $value = implode(
+            ',',
+            array_map(
+              'clean_iptc_value',
+              $iptc[$iptc_key]
+              )
+            );
+        }
+        else
+        {
+          $value = clean_iptc_value($iptc[$iptc_key][0]);
+        }
+        
+        $iptc_result[$iptc_key] = $value;
+      }
+    }
+  }
+
+  echo 'IPTC Fields in '.$filename.'<br />';
+  $keys = array_keys($iptc_result);
+  sort($keys);
+  foreach ($keys as $key)
+  {
+    echo '<br />'.$key.' = '.$iptc_result[$key];
+  }
+}
+else
+{
+  echo 'no IPTC information';
+}
+
+echo '<br /><br /><br />';
+echo 'EXIF Fields in '.$filename.'<br />';
+$exif = read_exif_data($filename);
+echo '<pre>';
+print_r($exif);
+echo '</pre>';
+?>
Index: /tags/2.0.2/tools/piwigo_remote.pl
===================================================================
--- /tags/2.0.2/tools/piwigo_remote.pl	(revision 3278)
+++ /tags/2.0.2/tools/piwigo_remote.pl	(revision 3278)
@@ -0,0 +1,297 @@
+#!/usr/bin/perl
+
+####
+# Usage examples
+#
+# time perl piwigo_remote.pl \
+#   --action=pwg.images.add \
+#   --file=erwann_rocher-web.jpg \
+#   --thumb=erwann_rocher-thumb.jpg \
+#   --high=erwann_rocher-high.jpg \
+#   --original=erwann_rocher-high.jpg \
+#   --define categories=9 \
+#   --chunk_size=200_000
+
+use strict;
+use warnings;
+
+use JSON;
+use LWP::UserAgent;
+use Getopt::Long;
+use Encode qw/is_utf8 decode/;
+use POSIX qw(ceil floor);
+
+my %opt = ();
+GetOptions(
+    \%opt,
+    qw/action=s file=s thumbnail=s high=s original=s categories=s chunk_size=i define=s%/
+);
+
+our $ua = LWP::UserAgent->new;
+$ua->cookie_jar({});
+
+my %conf;
+$conf{base_url} = 'http://localhost/piwigo/2.0';
+$conf{response_format} = 'json';
+$conf{username} = 'plg';
+$conf{password} = 'plg';
+$conf{limit} = 10;
+$conf{chunk_size} = defined $opt{chunk_size} ? $opt{chunk_size} : 500_000;
+
+my $result = undef;
+my $query = undef;
+
+binmode STDOUT, ":encoding(utf-8)";
+
+# TODO : don't connect at each script call, use the session duration instead.
+my $form = {
+    method => 'pwg.session.login',
+    username => $conf{username},
+    password => $conf{password},
+};
+
+$result = $ua->post(
+    $conf{base_url}.'/ws.php?format=json',
+    $form
+);
+
+# print "\n", $ua->cookie_jar->as_string, "\n";
+
+if ($opt{action} eq 'pwg.images.add') {
+    use MIME::Base64 qw(encode_base64);
+    use Digest::MD5::File qw/file_md5_hex/;
+    use File::Slurp;
+
+    $form = {};
+    $form->{method} = 'pwg.images.add';
+
+    my $original_sum = file_md5_hex($opt{original});
+    $form->{original_sum} = $original_sum;
+
+    send_chunks(
+        filepath => $opt{file},
+        type => 'file',
+        original_sum => $original_sum,
+    );
+    $form->{file_sum} = file_md5_hex($opt{file});
+
+    send_chunks(
+        filepath => $opt{thumbnail},
+        type => 'thumb',
+        original_sum => $original_sum,
+    );
+    $form->{thumbnail_sum} = file_md5_hex($opt{thumbnail});
+
+    if (defined $opt{high}) {
+        send_chunks(
+            filepath => $opt{high},
+            type => 'high',
+            original_sum => $original_sum,
+        );
+        $form->{high_sum} = file_md5_hex($opt{high});
+    }
+
+    foreach my $key (keys %{ $opt{define} }) {
+        $form->{$key} = $opt{define}{$key};
+    }
+
+    my $response = $ua->post(
+        $conf{base_url}.'/ws.php?format=json',
+        $form
+    );
+
+    print "-" x 50, "\n";
+    printf("response code    : %u\n", $response->code);
+    printf("response message : %s\n", $response->message);
+    print "-" x 50, "\n";
+    print "\n";
+
+#     use Data::Dumper;
+#     print Dumper($response->content);
+#     print Dumper(from_json($response->content));
+
+    if ($response->is_success) {
+        print "upload successful\n";
+    }
+    else {
+        warn 'A problem has occured during upload', "\n";
+        warn $response->decoded_content, "\n";
+        die $response->status_line;
+    }
+}
+
+if ($opt{action} eq 'pwg.tags.list') {
+    use Text::ASCIITable;
+
+    $query = pwg_ws_get_query(
+        method => 'pwg.tags.getList',
+        sort_by_counter => 'true',
+    );
+
+    $result = $ua->get($query);
+    my $tag_result = from_json($result->content);
+    my $t = Text::ASCIITable->new({ headingText => 'Tags' });
+    $t->setCols('id','counter','name');
+
+    my $tag_number = 1;
+    foreach my $tag_href (@{ $tag_result->{result}{tags} }) {
+        $t->addRow(
+            $tag_href->{id},
+            $tag_href->{counter},
+            $tag_href->{name}
+        );
+
+        last if $tag_number++ >= $conf{limit};
+    }
+    print $t;
+}
+
+if ($opt{action} eq 'pwg.tags.getAdminList') {
+    $query = pwg_ws_get_query(
+        method => 'pwg.tags.getAdminList'
+    );
+
+    $result = $ua->get($query);
+    my $tags = from_json($result->content)->{result}{tags};
+
+    foreach my $tag (@{$tags}) {
+        # print join(',', keys %{$tag}), "\n"; exit();
+        printf(
+            '{%u} %s ',
+            $tag->{id},
+            $tag->{name}
+        );
+    }
+
+    print "\n";
+}
+
+if ($opt{action} eq 'pwg.categories.add') {
+    $form = {
+        method => 'pwg.categories.add',
+        name => $opt{define}{name},
+        parent => $opt{define}{parent},
+    };
+
+    my $response = $ua->post(
+        $conf{base_url}.'/ws.php?format=json',
+        $form
+    );
+
+    use Data::Dumper;
+    print Dumper(from_json($response->content));
+}
+
+if ($opt{action} eq 'pwg.tags.add') {
+    $form = {
+        method => 'pwg.tags.add',
+        name => $opt{define}{name},
+    };
+
+    my $response = $ua->post(
+        $conf{base_url}.'/ws.php?format=json',
+        $form
+    );
+
+    use Data::Dumper;
+    print Dumper(from_json($response->content));
+}
+
+if ($opt{action} eq 'pwg.images.exist') {
+    $form = {
+        method => $opt{action},
+    };
+
+    foreach my $key (keys %{ $opt{define} }) {
+        $form->{$key} = $opt{define}{$key};
+    }
+
+    my $response = $ua->post(
+        $conf{base_url}.'/ws.php?format=json',
+        $form
+    );
+
+    use Data::Dumper;
+    print Dumper(from_json($response->content)->{result});
+    # print Dumper($response);
+}
+
+if ($opt{action} eq 'pwg.images.setInfo') {
+    $form = {
+        method => $opt{action},
+    };
+
+    foreach my $key (keys %{ $opt{define} }) {
+        $form->{$key} = $opt{define}{$key};
+    }
+
+    my $response = $ua->post(
+        $conf{base_url}.'/ws.php?format=json',
+        $form
+    );
+
+    use Data::Dumper;
+    # print Dumper(from_json($response->content)->{result});
+    print Dumper($response);
+}
+
+$query = pwg_ws_get_query(
+    method => 'pwg.session.logout'
+);
+$ua->get($query);
+
+sub pwg_ws_get_query {
+    my %params = @_;
+
+    my $query = $conf{base_url}.'/ws.php?format='.$conf{response_format};
+
+    foreach my $key (keys %params) {
+        $query .= '&'.$key.'='.$params{$key};
+    }
+
+    return $query;
+}
+
+sub send_chunks {
+    my %params = @_;
+
+    my $content = read_file($params{filepath});
+    my $content_length = length($content);
+    my $nb_chunks = ceil($content_length / $conf{chunk_size});
+
+    my $chunk_pos = 0;
+    my $chunk_id = 1;
+    while ($chunk_pos < $content_length) {
+        my $chunk = substr(
+            $content,
+            $chunk_pos,
+            $conf{chunk_size}
+        );
+        $chunk_pos += $conf{chunk_size};
+
+        my $response = $ua->post(
+            $conf{base_url}.'/ws.php?format=json',
+            {
+                method => 'pwg.images.addChunk',
+                data => encode_base64($chunk),
+                original_sum => $params{original_sum},
+                position => $chunk_id,
+                type => $params{type},
+            }
+        );
+
+        printf(
+            'chunk %05u of %05u for %s "%s"'."\n",
+            $chunk_id,
+            $nb_chunks,
+            $params{type},
+            $params{filepath}
+        );
+        if ($response->code != 200) {
+            printf("response code    : %u\n", $response->code);
+            printf("response message : %s\n", $response->message);
+        }
+
+        $chunk_id++;
+    }
+}
Index: /tags/2.0.2/tools/prototype.js
===================================================================
--- /tags/2.0.2/tools/prototype.js	(revision 3278)
+++ /tags/2.0.2/tools/prototype.js	(revision 3278)
@@ -0,0 +1,4221 @@
+/*  Prototype JavaScript framework, version 1.6.0.2
+ *  (c) 2005-2008 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/
+ *
+ *--------------------------------------------------------------------------*/
+
+var Prototype = {
+  Version: '1.6.0.2',
+
+  Browser: {
+    IE:     !!(window.attachEvent && !window.opera),
+    Opera:  !!window.opera,
+    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,
+    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(x) { return x }
+};
+
+if (Prototype.Browser.MobileSafari)
+  Prototype.BrowserFeatures.SpecificElementExtensions = false;
+
+
+/* Based on Alex Arnell's inheritance implementation. */
+var Class = {
+  create: function() {
+    var parent = null, properties = $A(arguments);
+    if (Object.isFunction(properties[0]))
+      parent = properties.shift();
+
+    function klass() {
+      this.initialize.apply(this, arguments);
+    }
+
+    Object.extend(klass, Class.Methods);
+    klass.superclass = parent;
+    klass.subclasses = [];
+
+    if (parent) {
+      var subclass = function() { };
+      subclass.prototype = parent.prototype;
+      klass.prototype = new subclass;
+      parent.subclasses.push(klass);
+    }
+
+    for (var i = 0; i < properties.length; i++)
+      klass.addMethods(properties[i]);
+
+    if (!klass.prototype.initialize)
+      klass.prototype.initialize = Prototype.emptyFunction;
+
+    klass.prototype.constructor = klass;
+
+    return klass;
+  }
+};
+
+Class.Methods = {
+  addMethods: function(source) {
+    var ancestor   = this.superclass && this.superclass.prototype;
+    var properties = Object.keys(source);
+
+    if (!Object.keys({ toString: true }).length)
+      properties.push("toString", "valueOf");
+
+    for (var i = 0, length = properties.length; i < length; i++) {
+      var property = properties[i], value = source[property];
+      if (ancestor && Object.isFunction(value) &&
+          value.argumentNames().first() == "$super") {
+        var method = value, value = Object.extend((function(m) {
+          return function() { return ancestor[m].apply(this, arguments) };
+        })(property).wrap(method), {
+          valueOf:  function() { return method },
+          toString: function() { return method.toString() }
+        });
+      }
+      this.prototype[property] = value;
+    }
+
+    return this;
+  }
+};
+
+var Abstract = { };
+
+Object.extend = function(destination, source) {
+  for (var property in source)
+    destination[property] = source[property];
+  return destination;
+};
+
+Object.extend(Object, {
+  inspect: function(object) {
+    try {
+      if (Object.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) {
+    var type = typeof object;
+    switch (type) {
+      case 'undefined':
+      case 'function':
+      case 'unknown': return;
+      case 'boolean': return object.toString();
+    }
+
+    if (object === null) return 'null';
+    if (object.toJSON) return object.toJSON();
+    if (Object.isElement(object)) return;
+
+    var results = [];
+    for (var property in object) {
+      var value = Object.toJSON(object[property]);
+      if (!Object.isUndefined(value))
+        results.push(property.toJSON() + ': ' + value);
+    }
+
+    return '{' + results.join(', ') + '}';
+  },
+
+  toQueryString: function(object) {
+    return $H(object).toQueryString();
+  },
+
+  toHTML: function(object) {
+    return object && object.toHTML ? object.toHTML() : String.interpret(object);
+  },
+
+  keys: function(object) {
+    var keys = [];
+    for (var property in object)
+      keys.push(property);
+    return keys;
+  },
+
+  values: function(object) {
+    var values = [];
+    for (var property in object)
+      values.push(object[property]);
+    return values;
+  },
+
+  clone: function(object) {
+    return Object.extend({ }, object);
+  },
+
+  isElement: function(object) {
+    return object && object.nodeType == 1;
+  },
+
+  isArray: function(object) {
+    return object != null && typeof object == "object" &&
+      'splice' in object && 'join' in object;
+  },
+
+  isHash: function(object) {
+    return object instanceof Hash;
+  },
+
+  isFunction: function(object) {
+    return typeof object == "function";
+  },
+
+  isString: function(object) {
+    return typeof object == "string";
+  },
+
+  isNumber: function(object) {
+    return typeof object == "number";
+  },
+
+  isUndefined: function(object) {
+    return typeof object == "undefined";
+  }
+});
+
+Object.extend(Function.prototype, {
+  argumentNames: function() {
+    var names = this.toString().match(/^[\s\(]*function[^(]*\((.*?)\)/)[1].split(",").invoke("strip");
+    return names.length == 1 && !names[0] ? [] : names;
+  },
+
+  bind: function() {
+    if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this;
+    var __method = this, args = $A(arguments), object = args.shift();
+    return function() {
+      return __method.apply(object, args.concat($A(arguments)));
+    }
+  },
+
+  bindAsEventListener: function() {
+    var __method = this, args = $A(arguments), object = args.shift();
+    return function(event) {
+      return __method.apply(object, [event || window.event].concat(args));
+    }
+  },
+
+  curry: function() {
+    if (!arguments.length) return this;
+    var __method = this, args = $A(arguments);
+    return function() {
+      return __method.apply(this, args.concat($A(arguments)));
+    }
+  },
+
+  delay: function() {
+    var __method = this, args = $A(arguments), timeout = args.shift() * 1000;
+    return window.setTimeout(function() {
+      return __method.apply(__method, args);
+    }, timeout);
+  },
+
+  wrap: function(wrapper) {
+    var __method = this;
+    return function() {
+      return wrapper.apply(this, [__method.bind(this)].concat($A(arguments)));
+    }
+  },
+
+  methodize: function() {
+    if (this._methodized) return this._methodized;
+    var __method = this;
+    return this._methodized = function() {
+      return __method.apply(null, [this].concat($A(arguments)));
+    };
+  }
+});
+
+Function.prototype.defer = Function.prototype.delay.curry(0.01);
+
+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 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;
+    this.frequency = frequency;
+    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(value) {
+    return value == null ? '' : String(value);
+  },
+  specialChar: {
+    '\b': '\\b',
+    '\t': '\\t',
+    '\n': '\\n',
+    '\f': '\\f',
+    '\r': '\\r',
+    '\\': '\\\\'
+  }
+});
+
+Object.extend(String.prototype, {
+  gsub: function(pattern, replacement) {
+    var result = '', source = this, match;
+    replacement = arguments.callee.prepareReplacement(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;
+  },
+
+  sub: function(pattern, replacement, count) {
+    replacement = this.gsub.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) {
+    this.gsub(pattern, iterator);
+    return String(this);
+  },
+
+  truncate: function(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() {
+    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 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() {
+    return this.extractScripts().map(function(script) { return eval(script) });
+  },
+
+  escapeHTML: function() {
+    var self = arguments.callee;
+    self.text.data = this;
+    return self.div.innerHTML;
+  },
+
+  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) {
+    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;
+    });
+  },
+
+  toArray: function() {
+    return this.split('');
+  },
+
+  succ: function() {
+    return this.slice(0, this.length - 1) +
+      String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
+  },
+
+  times: function(count) {
+    return count < 1 ? '' : new Array(count + 1).join(this);
+  },
+
+  camelize: function() {
+    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;
+  },
+
+  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(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);
+    });
+    if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"';
+    return "'" + escapedString.replace(/'/g, '\\\'') + "'";
+  },
+
+  toJSON: function() {
+    return this.inspect(true);
+  },
+
+  unfilterJSON: function(filter) {
+    return this.sub(filter || Prototype.JSONFilter, '#{1}');
+  },
+
+  isJSON: function() {
+    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) {
+    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) {
+    return this.indexOf(pattern) > -1;
+  },
+
+  startsWith: function(pattern) {
+    return this.indexOf(pattern) === 0;
+  },
+
+  endsWith: function(pattern) {
+    var d = this.length - pattern.length;
+    return d >= 0 && this.lastIndexOf(pattern) === d;
+  },
+
+  empty: function() {
+    return this == '';
+  },
+
+  blank: function() {
+    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.replace(/&amp;/g,'&').replace(/&lt;/g,'<').replace(/&gt;/g,'>');
+  }
+});
+
+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('')
+});
+
+with (String.prototype.escapeHTML) div.appendChild(text);
+
+var Template = Class.create({
+  initialize: function(template, pattern) {
+    this.template = template.toString();
+    this.pattern = pattern || Template.Pattern;
+  },
+
+  evaluate: function(object) {
+    if (Object.isFunction(object.toTemplateReplacements))
+      object = object.toTemplateReplacements();
+
+    return this.template.gsub(this.pattern, function(match) {
+      if (object == null) return '';
+
+      var before = match[1] || '';
+      if (before == '\\') return match[2];
+
+      var ctx = object, expr = match[3];
+      var pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;
+      match = pattern.exec(expr);
+      if (match == null) return before;
+
+      while (match != null) {
+        var comp = match[1].startsWith('[') ? match[2].gsub('\\\\]', ']') : match[1];
+        ctx = ctx[comp];
+        if (null == ctx || '' == match[3]) break;
+        expr = expr.substring('[' == match[3] ? match[1].length : match[0].length);
+        match = pattern.exec(expr);
+      }
+
+      return before + String.interpret(ctx);
+    });
+  }
+});
+Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
+
+var $break = { };
+
+var Enumerable = {
+  each: function(iterator, context) {
+    var index = 0;
+    iterator = iterator.bind(context);
+    try {
+      this._each(function(value) {
+        iterator(value, index++);
+      });
+    } catch (e) {
+      if (e != $break) throw e;
+    }
+    return this;
+  },
+
+  eachSlice: function(number, iterator, context) {
+    iterator = iterator ? iterator.bind(context) : Prototype.K;
+    var index = -number, slices = [], array = this.toArray();
+    while ((index += number) < array.length)
+      slices.push(array.slice(index, index+number));
+    return slices.collect(iterator, context);
+  },
+
+  all: function(iterator, context) {
+    iterator = iterator ? iterator.bind(context) : Prototype.K;
+    var result = true;
+    this.each(function(value, index) {
+      result = result && !!iterator(value, index);
+      if (!result) throw $break;
+    });
+    return result;
+  },
+
+  any: function(iterator, context) {
+    iterator = iterator ? iterator.bind(context) : Prototype.K;
+    var result = false;
+    this.each(function(value, index) {
+      if (result = !!iterator(value, index))
+        throw $break;
+    });
+    return result;
+  },
+
+  collect: function(iterator, context) {
+    iterator = iterator ? iterator.bind(context) : Prototype.K;
+    var results = [];
+    this.each(function(value, index) {
+      results.push(iterator(value, index));
+    });
+    return results;
+  },
+
+  detect: function(iterator, context) {
+    iterator = iterator.bind(context);
+    var result;
+    this.each(function(value, index) {
+      if (iterator(value, index)) {
+        result = value;
+        throw $break;
+      }
+    });
+    return result;
+  },
+
+  findAll: function(iterator, context) {
+    iterator = iterator.bind(context);
+    var results = [];
+    this.each(function(value, index) {
+      if (iterator(value, index))
+        results.push(value);
+    });
+    return results;
+  },
+
+  grep: function(filter, iterator, context) {
+    iterator = iterator ? iterator.bind(context) : Prototype.K;
+    var results = [];
+
+    if (Object.isString(filter))
+      filter = new RegExp(filter);
+
+    this.each(function(value, index) {
+      if (filter.match(value))
+        results.push(iterator(value, index));
+    });
+    return results;
+  },
+
+  include: function(object) {
+    if (Object.isFunction(this.indexOf))
+      if (this.indexOf(object) != -1) return true;
+
+    var found = false;
+    this.each(function(value) {
+      if (value == object) {
+        found = true;
+        throw $break;
+      }
+    });
+    return found;
+  },
+
+  inGroupsOf: function(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) {
+    iterator = iterator.bind(context);
+    this.each(function(value, index) {
+      memo = iterator(memo, value, index);
+    });
+    return memo;
+  },
+
+  invoke: function(method) {
+    var args = $A(arguments).slice(1);
+    return this.map(function(value) {
+      return value[method].apply(value, args);
+    });
+  },
+
+  max: function(iterator, context) {
+    iterator = iterator ? iterator.bind(context) : Prototype.K;
+    var result;
+    this.each(function(value, index) {
+      value = iterator(value, index);
+      if (result == null || value >= result)
+        result = value;
+    });
+    return result;
+  },
+
+  min: function(iterator, context) {
+    iterator = iterator ? iterator.bind(context) : Prototype.K;
+    var result;
+    this.each(function(value, index) {
+      value = iterator(value, index);
+      if (result == null || value < result)
+        result = value;
+    });
+    return result;
+  },
+
+  partition: function(iterator, context) {
+    iterator = iterator ? iterator.bind(context) : Prototype.K;
+    var trues = [], falses = [];
+    this.each(function(value, index) {
+      (iterator(value, index) ?
+        trues : falses).push(value);
+    });
+    return [trues, falses];
+  },
+
+  pluck: function(property) {
+    var results = [];
+    this.each(function(value) {
+      results.push(value[property]);
+    });
+    return results;
+  },
+
+  reject: function(iterator, context) {
+    iterator = iterator.bind(context);
+    var results = [];
+    this.each(function(value, index) {
+      if (!iterator(value, index))
+        results.push(value);
+    });
+    return results;
+  },
+
+  sortBy: function(iterator, context) {
+    iterator = iterator.bind(context);
+    return this.map(function(value, index) {
+      return {value: value, criteria: iterator(value, index)};
+    }).sort(function(left, right) {
+      var a = left.criteria, b = right.criteria;
+      return a < b ? -1 : a > b ? 1 : 0;
+    }).pluck('value');
+  },
+
+  toArray: function() {
+    return this.map();
+  },
+
+  zip: function() {
+    var iterator = Prototype.K, args = $A(arguments);
+    if (Object.isFunction(args.last()))
+      iterator = args.pop();
+
+    var collections = [this].concat(args).map($A);
+    return this.map(function(value, index) {
+      return iterator(collections.pluck(index));
+    });
+  },
+
+  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(iterable) {
+  if (!iterable) return [];
+  if (iterable.toArray) 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 [];
+    if (!(Object.isFunction(iterable) && iterable == '[object NodeList]') &&
+        iterable.toArray) return iterable.toArray();
+    var length = iterable.length || 0, results = new Array(length);
+    while (length--) results[length] = iterable[length];
+    return results;
+  };
+}
+
+Array.from = $A;
+
+Object.extend(Array.prototype, Enumerable);
+
+if (!Array.prototype._reverse) Array.prototype._reverse = Array.prototype.reverse;
+
+Object.extend(Array.prototype, {
+  _each: function(iterator) {
+    for (var i = 0, length = this.length; i < length; i++)
+      iterator(this[i]);
+  },
+
+  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(value) {
+      return value != null;
+    });
+  },
+
+  flatten: function() {
+    return this.inject([], function(array, value) {
+      return array.concat(Object.isArray(value) ?
+        value.flatten() : [value]);
+    });
+  },
+
+  without: function() {
+    var values = $A(arguments);
+    return this.select(function(value) {
+      return !values.include(value);
+    });
+  },
+
+  reverse: function(inline) {
+    return (inline !== false ? this : this.toArray())._reverse();
+  },
+
+  reduce: function() {
+    return this.length > 1 ? this : this[0];
+  },
+
+  uniq: function(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) {
+    return this.uniq().findAll(function(item) {
+      return array.detect(function(value) { return item === value });
+    });
+  },
+
+  clone: function() {
+    return [].concat(this);
+  },
+
+  size: function() {
+    return this.length;
+  },
+
+  inspect: function() {
+    return '[' + this.map(Object.inspect).join(', ') + ']';
+  },
+
+  toJSON: function() {
+    var results = [];
+    this.each(function(object) {
+      var value = Object.toJSON(object);
+      if (!Object.isUndefined(value)) results.push(value);
+    });
+    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 $w(string) {
+  if (!Object.isString(string)) return [];
+  string = string.strip();
+  return string ? string.split(/\s+/) : [];
+}
+
+if (Prototype.Browser.Opera){
+  Array.prototype.concat = function() {
+    var array = [];
+    for (var i = 0, length = this.length; i < length; i++) array.push(this[i]);
+    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]);
+      } else {
+        array.push(arguments[i]);
+      }
+    }
+    return array;
+  };
+}
+Object.extend(Number.prototype, {
+  toColorPart: function() {
+    return this.toPaddedString(2, 16);
+  },
+
+  succ: function() {
+    return this + 1;
+  },
+
+  times: function(iterator) {
+    $R(0, this, true).each(iterator);
+    return this;
+  },
+
+  toPaddedString: function(length, radix) {
+    var string = this.toString(radix || 10);
+    return '0'.times(length - string.length) + string;
+  },
+
+  toJSON: function() {
+    return isFinite(this) ? this.toString() : 'null';
+  }
+});
+
+$w('abs round ceil floor').each(function(method){
+  Number.prototype[method] = Math[method].methodize();
+});
+function $H(object) {
+  return new Hash(object);
+};
+
+var Hash = Class.create(Enumerable, (function() {
+
+  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);
+    },
+
+    _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;
+    },
+
+    get: function(key) {
+      return this._object[key];
+    },
+
+    unset: function(key) {
+      var value = this._object[key];
+      delete this._object[key];
+      return value;
+    },
+
+    toObject: function() {
+      return Object.clone(this._object);
+    },
+
+    keys: function() {
+      return this.pluck('key');
+    },
+
+    values: function() {
+      return this.pluck('value');
+    },
+
+    index: function(value) {
+      var match = this.detect(function(pair) {
+        return pair.value === value;
+      });
+      return match && match.key;
+    },
+
+    merge: function(object) {
+      return this.clone().update(object);
+    },
+
+    update: function(object) {
+      return new Hash(object).inject(this, function(result, pair) {
+        result.set(pair.key, pair.value);
+        return result;
+      });
+    },
+
+    toQueryString: function() {
+      return this.map(function(pair) {
+        var key = encodeURIComponent(pair.key), values = pair.value;
+
+        if (values && typeof values == 'object') {
+          if (Object.isArray(values))
+            return values.map(toQueryPair.curry(key)).join('&');
+        }
+        return toQueryPair(key, values);
+      }).join('&');
+    },
+
+    inspect: function() {
+      return '#<Hash:{' + this.map(function(pair) {
+        return pair.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(start, end, exclusive) {
+    this.start = start;
+    this.end = end;
+    this.exclusive = exclusive;
+  },
+
+  _each: function(iterator) {
+    var value = this.start;
+    while (this.include(value)) {
+      iterator(value);
+      value = value.succ();
+    }
+  },
+
+  include: function(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);
+};
+
+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(iterator) {
+    this.responders._each(iterator);
+  },
+
+  register: function(responder) {
+    if (!this.include(responder))
+      this.responders.push(responder);
+  },
+
+  unregister: function(responder) {
+    this.responders = this.responders.without(responder);
+  },
+
+  dispatch: function(callback, request, transport, json) {
+    this.each(function(responder) {
+      if (Object.isFunction(responder[callback])) {
+        try {
+          responder[callback].apply(responder, [request, transport, json]);
+        } catch (e) { }
+      }
+    });
+  }
+};
+
+Object.extend(Ajax.Responders, Enumerable);
+
+Ajax.Responders.register({
+  onCreate:   function() { Ajax.activeRequestCount++ },
+  onComplete: function() { Ajax.activeRequestCount-- }
+});
+
+Ajax.Base = Class.create({
+  initialize: function(options) {
+    this.options = {
+      method:       'post',
+      asynchronous: true,
+      contentType:  'application/x-www-form-urlencoded',
+      encoding:     'UTF-8',
+      parameters:   '',
+      evalJSON:     true,
+      evalJS:       true
+    };
+    Object.extend(this.options, options || { });
+
+    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, url, options) {
+    $super(options);
+    this.transport = Ajax.getTransport();
+    this.request(url);
+  },
+
+  request: function(url) {
+    this.url = url;
+    this.method = this.options.method;
+    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';
+    }
+
+    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))
+        params += '&_=';
+    }
+
+    try {
+      var response = new Ajax.Response(this);
+      if (this.options.onCreate) this.options.onCreate(response);
+      Ajax.Responders.dispatch('onCreate', this, response);
+
+      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 || params) : null;
+      this.transport.send(this.body);
+
+      /* Force Firefox to handle ready state 4 for synchronous requests */
+      if (!this.options.asynchronous && this.transport.overrideMimeType)
+        this.onStateChange();
+
+    }
+    catch (e) {
+      this.dispatchException(e);
+    }
+  },
+
+  onStateChange: function() {
+    var readyState = this.transport.readyState;
+    if (readyState > 1 && !((readyState == 4) && this._complete))
+      this.respondToReadyState(this.transport.readyState);
+  },
+
+  setRequestHeaders: function() {
+    var headers = {
+      'X-Requested-With': 'XMLHttpRequest',
+      'X-Prototype-Version': Prototype.Version,
+      'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
+    };
+
+    if (this.method == 'post') {
+      headers['Content-type'] = this.options.contentType +
+        (this.options.encoding ? '; charset=' + this.options.encoding : '');
+
+      /* Force "Connection: close" for older Mozilla browsers to work
+       * around a bug where XMLHttpRequest sends an incorrect
+       * Content-length header. See Mozilla Bugzilla #246651.
+       */
+      if (this.transport.overrideMimeType &&
+          (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005)
+            headers['Connection'] = 'close';
+    }
+
+    // user-defined headers
+    if (typeof this.options.requestHeaders == 'object') {
+      var extras = this.options.requestHeaders;
+
+      if (Object.isFunction(extras.push))
+        for (var i = 0, length = extras.length; i < length; i += 2)
+          headers[extras[i]] = extras[i+1];
+      else
+        $H(extras).each(function(pair) { headers[pair.key] = pair.value });
+    }
+
+    for (var name in headers)
+      this.transport.setRequestHeader(name, headers[name]);
+  },
+
+  success: function() {
+    var status = this.getStatus();
+    return !status || (status >= 200 && status < 300);
+  },
+
+  getStatus: function() {
+    try {
+      return this.transport.status || 0;
+    } catch (e) { return 0 }
+  },
+
+  respondToReadyState: function(readyState) {
+    var state = Ajax.Request.Events[readyState], response = new Ajax.Response(this);
+
+    if (state == 'Complete') {
+      try {
+        this._complete = true;
+        (this.options['on' + response.status]
+         || this.options['on' + (this.success() ? 'Success' : 'Failure')]
+         || Prototype.emptyFunction)(response, response.headerJSON);
+      } catch (e) {
+        this.dispatchException(e);
+      }
+
+      var contentType = response.getHeader('Content-type');
+      if (this.options.evalJS == 'force'
+          || (this.options.evalJS && this.isSameOrigin() && contentType
+          && contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i)))
+        this.evalResponse();
+    }
+
+    try {
+      (this.options['on' + state] || Prototype.emptyFunction)(response, response.headerJSON);
+      Ajax.Responders.dispatch('on' + state, this, response, response.headerJSON);
+    } catch (e) {
+      this.dispatchException(e);
+    }
+
+    if (state == 'Complete') {
+      // avoid memory leak in MSIE: clean up
+      this.transport.onreadystatechange = Prototype.emptyFunction;
+    }
+  },
+
+  isSameOrigin: function() {
+    var m = this.url.match(/^\s*https?:\/\/[^\/]*/);
+    return !m || (m[0] == '#{protocol}//#{domain}#{port}'.interpolate({
+      protocol: location.protocol,
+      domain: document.domain,
+      port: location.port ? ':' + location.port : ''
+    }));
+  },
+
+  getHeader: function(name) {
+    try {
+      return this.transport.getResponseHeader(name) || null;
+    } catch (e) { return null }
+  },
+
+  evalResponse: function() {
+    try {
+      return eval((this.transport.responseText || '').unfilterJSON());
+    } catch (e) {
+      this.dispatchException(e);
+    }
+  },
+
+  dispatchException: function(exception) {
+    (this.options.onException || Prototype.emptyFunction)(this, exception);
+    Ajax.Responders.dispatch('onException', this, exception);
+  }
+});
+
+Ajax.Request.Events =
+  ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
+
+Ajax.Response = Class.create({
+  initialize: function(request){
+    this.request = request;
+    var transport  = this.transport  = request.transport,
+        readyState = this.readyState = transport.readyState;
+
+    if((readyState > 2 && !Prototype.Browser.IE) || readyState == 4) {
+      this.status       = this.getStatus();
+      this.statusText   = this.getStatusText();
+      this.responseText = String.interpret(transport.responseText);
+      this.headerJSON   = this._getHeaderJSON();
+    }
+
+    if(readyState == 4) {
+      var xml = transport.responseXML;
+      this.responseXML  = Object.isUndefined(xml) ? null : xml;
+      this.responseJSON = this._getResponseJSON();
+    }
+  },
+
+  status:      0,
+  statusText: '',
+
+  getStatus: Ajax.Request.prototype.getStatus,
+
+  getStatusText: function() {
+    try {
+      return this.transport.statusText || '';
+    } catch (e) { return '' }
+  },
+
+  getHeader: Ajax.Request.prototype.getHeader,
+
+  getAllHeaders: function() {
+    try {
+      return this.getAllResponseHeaders();
+    } catch (e) { return null }
+  },
+
+  getResponseHeader: function(name) {
+    return this.transport.getResponseHeader(name);
+  },
+
+  getAllResponseHeaders: function() {
+    return this.transport.getAllResponseHeaders();
+  },
+
+  _getHeaderJSON: function() {
+    var json = this.getHeader('X-JSON');
+    if (!json) return null;
+    json = decodeURIComponent(escape(json));
+    try {
+      return json.evalJSON(this.request.options.sanitizeJSON ||
+        !this.request.isSameOrigin());
+    } catch (e) {
+      this.request.dispatchException(e);
+    }
+  },
+
+  _getResponseJSON: function() {
+    var options = this.request.options;
+    if (!options.evalJSON || (options.evalJSON != 'force' &&
+      !(this.getHeader('Content-type') || '').include('application/json')) ||
+        this.responseText.blank())
+          return null;
+    try {
+      return this.responseText.evalJSON(options.sanitizeJSON ||
+        !this.request.isSameOrigin());
+    } catch (e) {
+      this.request.dispatchException(e);
+    }
+  }
+});
+
+Ajax.Updater = Class.create(Ajax.Request, {
+  initialize: function($super, container, url, options) {
+    this.container = {
+      success: (container.success || container),
+      failure: (container.failure || (container.success ? null : container))
+    };
+
+    options = Object.clone(options);
+    var onComplete = options.onComplete;
+    options.onComplete = (function(response, json) {
+      this.updateContent(response.responseText);
+      if (Object.isFunction(onComplete)) onComplete(response, json);
+    }).bind(this);
+
+    $super(url, options);
+  },
+
+  updateContent: function(responseText) {
+    var receiver = this.container[this.success() ? 'success' : 'failure'],
+        options = this.options;
+
+    if (!options.evalScripts) responseText = responseText.stripScripts();
+
+    if (receiver = $(receiver)) {
+      if (options.insertion) {
+        if (Object.isString(options.insertion)) {
+          var insertion = { }; insertion[options.insertion] = responseText;
+          receiver.insert(insertion);
+        }
+        else options.insertion(receiver, responseText);
+      }
+      else receiver.update(responseText);
+    }
+  }
+});
+
+Ajax.PeriodicalUpdater = Class.create(Ajax.Base, {
+  initialize: function($super, container, url, options) {
+    $super(options);
+    this.onComplete = this.options.onComplete;
+
+    this.frequency = (this.options.frequency || 2);
+    this.decay = (this.options.decay || 1);
+
+    this.updater = { };
+    this.container = container;
+    this.url = url;
+
+    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(response) {
+    if (this.options.decay) {
+      this.decay = (response.responseText == this.lastText ?
+        this.decay * this.options.decay : 1);
+
+      this.lastText = response.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 $(element) {
+  if (arguments.length > 1) {
+    for (var i = 0, elements = [], length = arguments.length; i < length; i++)
+      elements.push($(arguments[i]));
+    return elements;
+  }
+  if (Object.isString(element))
+    element = document.getElementById(element);
+  return Element.extend(element);
+}
+
+if (Prototype.BrowserFeatures.XPath) {
+  document._getElementsByXPath = function(expression, parentElement) {
+    var results = [];
+    var query = document.evaluate(expression, $(parentElement) || document,
+      null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
+    for (var i = 0, length = query.snapshotLength; i < length; i++)
+      results.push(Element.extend(query.snapshotItem(i)));
+    return results;
+  };
+}
+
+/*--------------------------------------------------------------------------*/
+
+if (!window.Node) var Node = { };
+
+if (!Node.ELEMENT_NODE) {
+  // DOM level 2 ECMAScript Language Binding
+  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 element = this.Element;
+  this.Element = function(tagName, attributes) {
+    attributes = attributes || { };
+    tagName = tagName.toLowerCase();
+    var cache = Element.cache;
+    if (Prototype.Browser.IE && attributes.name) {
+      tagName = '<' + tagName + ' name="' + attributes.name + '">';
+      delete attributes.name;
+      return Element.writeAttribute(document.createElement(tagName), attributes);
+    }
+    if (!cache[tagName]) cache[tagName] = Element.extend(document.createElement(tagName));
+    return Element.writeAttribute(cache[tagName].cloneNode(false), attributes);
+  };
+  Object.extend(this.Element, element || { });
+}).call(window);
+
+Element.cache = { };
+
+Element.Methods = {
+  visible: function(element) {
+    return $(element).style.display != 'none';
+  },
+
+  toggle: function(element) {
+    element = $(element);
+    Element[Element.visible(element) ? 'hide' : 'show'](element);
+    return element;
+  },
+
+  hide: function(element) {
+    $(element).style.display = 'none';
+    return element;
+  },
+
+  show: function(element) {
+    $(element).style.display = '';
+    return element;
+  },
+
+  remove: function(element) {
+    element = $(element);
+    element.parentNode.removeChild(element);
+    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;
+  },
+
+  replace: function(element, content) {
+    element = $(element);
+    if (content && content.toElement) content = content.toElement();
+    else if (!Object.isElement(content)) {
+      content = Object.toHTML(content);
+      var range = element.ownerDocument.createRange();
+      range.selectNode(element);
+      content.evalScripts.bind(content).defer();
+      content = range.createContextualFragment(content.stripScripts());
+    }
+    element.parentNode.replaceChild(content, element);
+    return element;
+  },
+
+  insert: function(element, insertions) {
+    element = $(element);
+
+    if (Object.isString(insertions) || Object.isNumber(insertions) ||
+        Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML)))
+          insertions = {bottom:insertions};
+
+    var content, insert, tagName, childNodes;
+
+    for (var position in insertions) {
+      content  = insertions[position];
+      position = position.toLowerCase();
+      insert = Element._insertionTranslations[position];
+
+      if (content && content.toElement) content = content.toElement();
+      if (Object.isElement(content)) {
+        insert(element, content);
+        continue;
+      }
+
+      content = Object.toHTML(content);
+
+      tagName = ((position == 'before' || position == 'after')
+        ? element.parentNode : element).tagName.toUpperCase();
+
+      childNodes = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
+
+      if (position == 'top' || position == 'after') childNodes.reverse();
+      childNodes.each(insert.curry(element));
+
+      content.evalScripts.bind(content).defer();
+    }
+
+    return element;
+  },
+
+  wrap: function(element, wrapper, attributes) {
+    element = $(element);
+    if (Object.isElement(wrapper))
+      $(wrapper).writeAttribute(attributes || { });
+    else if (Object.isString(wrapper)) wrapper = new Element(wrapper, attributes);
+    else wrapper = new Element('div', wrapper);
+    if (element.parentNode)
+      element.parentNode.replaceChild(wrapper, element);
+    wrapper.appendChild(element);
+    return wrapper;
+  },
+
+  inspect: function(element) {
+    element = $(element);
+    var result = '<' + element.tagName.toLowerCase();
+    $H({'id': 'id', 'className': 'class'}).each(function(pair) {
+      var property = pair.first(), attribute = pair.last();
+      var value = (element[property] || '').toString();
+      if (value) result += ' ' + attribute + '=' + value.inspect(true);
+    });
+    return result + '>';
+  },
+
+  recursivelyCollect: function(element, property) {
+    element = $(element);
+    var elements = [];
+    while (element = element[property])
+      if (element.nodeType == 1)
+        elements.push(Element.extend(element));
+    return elements;
+  },
+
+  ancestors: function(element) {
+    return $(element).recursivelyCollect('parentNode');
+  },
+
+  descendants: function(element) {
+    return $(element).select("*");
+  },
+
+  firstDescendant: function(element) {
+    element = $(element).firstChild;
+    while (element && element.nodeType != 1) element = element.nextSibling;
+    return $(element);
+  },
+
+  immediateDescendants: function(element) {
+    if (!(element = $(element).firstChild)) return [];
+    while (element && element.nodeType != 1) element = element.nextSibling;
+    if (element) return [element].concat($(element).nextSiblings());
+    return [];
+  },
+
+  previousSiblings: function(element) {
+    return $(element).recursivelyCollect('previousSibling');
+  },
+
+  nextSiblings: function(element) {
+    return $(element).recursivelyCollect('nextSibling');
+  },
+
+  siblings: function(element) {
+    element = $(element);
+    return element.previousSiblings().reverse().concat(element.nextSiblings());
+  },
+
+  match: function(element, selector) {
+    if (Object.isString(selector))
+      selector = new Selector(selector);
+    return selector.match($(element));
+  },
+
+  up: function(element, expression, index) {
+    element = $(element);
+    if (arguments.length == 1) return $(element.parentNode);
+    var ancestors = element.ancestors();
+    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] :
+      element.select(expression)[index || 0];
+  },
+
+  previous: function(element, expression, index) {
+    element = $(element);
+    if (arguments.length == 1) return $(Selector.handlers.previousElementSibling(element));
+    var previousSiblings = element.previousSiblings();
+    return Object.isNumber(expression) ? previousSiblings[expression] :
+      Selector.findElement(previousSiblings, expression, index);
+  },
+
+  next: function(element, expression, index) {
+    element = $(element);
+    if (arguments.length == 1) return $(Selector.handlers.nextElementSibling(element));
+    var nextSiblings = element.nextSiblings();
+    return Object.isNumber(expression) ? nextSiblings[expression] :
+      Selector.findElement(nextSiblings, expression, index);
+  },
+
+  select: function() {
+    var args = $A(arguments), element = $(args.shift());
+    return Selector.findChildElements(element, args);
+  },
+
+  adjacent: function() {
+    var args = $A(arguments), element = $(args.shift());
+    return Selector.findChildElements(element.parentNode, args).without(element);
+  },
+
+  identify: function(element) {
+    element = $(element);
+    var id = element.readAttribute('id'), self = arguments.callee;
+    if (id) return id;
+    do { id = 'anonymous_element_' + self.counter++ } while ($(id));
+    element.writeAttribute('id', id);
+    return id;
+  },
+
+  readAttribute: function(element, name) {
+    element = $(element);
+    if (Prototype.Browser.IE) {
+      var t = Element._attributeTranslations.read;
+      if (t.values[name]) return t.values[name](element, name);
+      if (t.names[name]) name = t.names[name];
+      if (name.include(':')) {
+        return (!element.attributes || !element.attributes[name]) ? null :
+         element.attributes[name].value;
+      }
+    }
+    return element.getAttribute(name);
+  },
+
+  writeAttribute: function(element, name, value) {
+    element = $(element);
+    var attributes = { }, t = Element._attributeTranslations.write;
+
+    if (typeof name == 'object') attributes = name;
+    else attributes[name] = Object.isUndefined(value) ? true : value;
+
+    for (var attr in attributes) {
+      name = t.names[attr] || attr;
+      value = attributes[attr];
+      if (t.values[attr]) name = t.values[attr](element, value);
+      if (value === false || value === null)
+        element.removeAttribute(name);
+      else if (value === true)
+        element.setAttribute(name, name);
+      else element.setAttribute(name, value);
+    }
+    return element;
+  },
+
+  getHeight: function(element) {
+    return $(element).getDimensions().height;
+  },
+
+  getWidth: function(element) {
+    return $(element).getDimensions().width;
+  },
+
+  classNames: function(element) {
+    return new Element.ClassNames(element);
+  },
+
+  hasClassName: function(element, className) {
+    if (!(element = $(element))) return;
+    var elementClassName = element.className;
+    return (elementClassName.length > 0 && (elementClassName == className ||
+      new RegExp("(^|\\s)" + className + "(\\s|$)").test(elementClassName)));
+  },
+
+  addClassName: function(element, className) {
+    if (!(element = $(element))) return;
+    if (!element.hasClassName(className))
+      element.className += (element.className ? ' ' : '') + className;
+    return element;
+  },
+
+  removeClassName: function(element, className) {
+    if (!(element = $(element))) return;
+    element.className = element.className.replace(
+      new RegExp("(^|\\s+)" + className + "(\\s+|$)"), ' ').strip();
+    return element;
+  },
+
+  toggleClassName: function(element, className) {
+    if (!(element = $(element))) return;
+    return element[element.hasClassName(className) ?
+      'removeClassName' : 'addClassName'](className);
+  },
+
+  // removes whitespace-only text node children
+  cleanWhitespace: function(element) {
+    element = $(element);
+    var node = element.firstChild;
+    while (node) {
+      var nextNode = node.nextSibling;
+      if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
+        element.removeChild(node);
+      node = nextNode;
+    }
+    return element;
+  },
+
+  empty: function(element) {
+    return $(element).innerHTML.blank();
+  },
+
+  descendantOf: function(element, ancestor) {
+    element = $(element), ancestor = $(ancestor);
+    var originalAncestor = ancestor;
+
+    if (element.compareDocumentPosition)
+      return (element.compareDocumentPosition(ancestor) & 8) === 8;
+
+    if (element.sourceIndex && !Prototype.Browser.Opera) {
+      var e = element.sourceIndex, a = ancestor.sourceIndex,
+       nextAncestor = ancestor.nextSibling;
+      if (!nextAncestor) {
+        do { ancestor = ancestor.parentNode; }
+        while (!(nextAncestor = ancestor.nextSibling) && ancestor.parentNode);
+      }
+      if (nextAncestor && nextAncestor.sourceIndex)
+       return (e > a && e < nextAncestor.sourceIndex);
+    }
+
+    while (element = element.parentNode)
+      if (element == originalAncestor) return true;
+    return false;
+  },
+
+  scrollTo: function(element) {
+    element = $(element);
+    var pos = element.cumulativeOffset();
+    window.scrollTo(pos[0], pos[1]);
+    return element;
+  },
+
+  getStyle: function(element, style) {
+    element = $(element);
+    style = style == 'float' ? 'cssFloat' : style.camelize();
+    var value = element.style[style];
+    if (!value) {
+      var css = document.defaultView.getComputedStyle(element, null);
+      value = css ? css[style] : null;
+    }
+    if (style == 'opacity') return value ? parseFloat(value) : 1.0;
+    return value == 'auto' ? null : value;
+  },
+
+  getOpacity: function(element) {
+    return $(element).getStyle('opacity');
+  },
+
+  setStyle: function(element, styles) {
+    element = $(element);
+    var elementStyle = element.style, match;
+    if (Object.isString(styles)) {
+      element.style.cssText += ';' + styles;
+      return styles.include('opacity') ?
+        element.setOpacity(styles.match(/opacity:\s*(\d?\.?\d*)/)[1]) : element;
+    }
+    for (var property in styles)
+      if (property == 'opacity') element.setOpacity(styles[property]);
+      else
+        elementStyle[(property == 'float' || property == 'cssFloat') ?
+          (Object.isUndefined(elementStyle.styleFloat) ? 'cssFloat' : 'styleFloat') :
+            property] = styles[property];
+
+    return element;
+  },
+
+  setOpacity: function(element, value) {
+    element = $(element);
+    element.style.opacity = (value == 1 || value === '') ? '' :
+      (value < 0.00001) ? 0 : value;
+    return element;
+  },
+
+  getDimensions: function(element) {
+    element = $(element);
+    var display = $(element).getStyle('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';
+    els.display = 'block';
+    var originalWidth = element.clientWidth;
+    var originalHeight = element.clientHeight;
+    els.display = originalDisplay;
+    els.position = originalPosition;
+    els.visibility = originalVisibility;
+    return {width: originalWidth, height: originalHeight};
+  },
+
+  makePositioned: function(element) {
+    element = $(element);
+    var pos = Element.getStyle(element, 'position');
+    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 (window.opera) {
+        element.style.top = 0;
+        element.style.left = 0;
+      }
+    }
+    return element;
+  },
+
+  undoPositioned: function(element) {
+    element = $(element);
+    if (element._madePositioned) {
+      element._madePositioned = undefined;
+      element.style.position =
+        element.style.top =
+        element.style.left =
+        element.style.bottom =
+        element.style.right = '';
+    }
+    return element;
+  },
+
+  makeClipping: function(element) {
+    element = $(element);
+    if (element._overflow) return element;
+    element._overflow = Element.getStyle(element, 'overflow') || 'auto';
+    if (element._overflow !== 'hidden')
+      element.style.overflow = 'hidden';
+    return element;
+  },
+
+  undoClipping: function(element) {
+    element = $(element);
+    if (!element._overflow) return element;
+    element.style.overflow = element._overflow == 'auto' ? '' : element._overflow;
+    element._overflow = null;
+    return element;
+  },
+
+  cumulativeOffset: function(element) {
+    var valueT = 0, valueL = 0;
+    do {
+      valueT += element.offsetTop  || 0;
+      valueL += element.offsetLeft || 0;
+      element = element.offsetParent;
+    } while (element);
+    return Element._returnOffset(valueL, valueT);
+  },
+
+  positionedOffset: function(element) {
+    var valueT = 0, valueL = 0;
+    do {
+      valueT += element.offsetTop  || 0;
+      valueL += element.offsetLeft || 0;
+      element = element.offsetParent;
+      if (element) {
+        if (element.tagName == 'BODY') break;
+        var p = Element.getStyle(element, 'position');
+        if (p !== 'static') break;
+      }
+    } while (element);
+    return Element._returnOffset(valueL, valueT);
+  },
+
+  absolutize: function(element) {
+    element = $(element);
+    if (element.getStyle('position') == 'absolute') return;
+    // Position.prepare(); // To be done manually by Scripty when it needs it.
+
+    var offsets = element.positionedOffset();
+    var top     = offsets[1];
+    var left    = offsets[0];
+    var width   = element.clientWidth;
+    var height  = element.clientHeight;
+
+    element._originalLeft   = left - parseFloat(element.style.left  || 0);
+    element._originalTop    = top  - parseFloat(element.style.top || 0);
+    element._originalWidth  = element.style.width;
+    element._originalHeight = element.style.height;
+
+    element.style.position = 'absolute';
+    element.style.top    = top + 'px';
+    element.style.left   = left + 'px';
+    element.style.width  = width + 'px';
+    element.style.height = height + 'px';
+    return element;
+  },
+
+  relativize: function(element) {
+    element = $(element);
+    if (element.getStyle('position') == 'relative') return;
+    // Position.prepare(); // To be done manually by Scripty when it needs it.
+
+    element.style.position = 'relative';
+    var top  = parseFloat(element.style.top  || 0) - (element._originalTop || 0);
+    var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);
+
+    element.style.top    = top + 'px';
+    element.style.left   = left + 'px';
+    element.style.height = element._originalHeight;
+    element.style.width  = element._originalWidth;
+    return element;
+  },
+
+  cumulativeScrollOffset: function(element) {
+    var valueT = 0, valueL = 0;
+    do {
+      valueT += element.scrollTop  || 0;
+      valueL += element.scrollLeft || 0;
+      element = element.parentNode;
+    } while (element);
+    return Element._returnOffset(valueL, valueT);
+  },
+
+  getOffsetParent: function(element) {
+    if (element.offsetParent) return $(element.offsetParent);
+    if (element == document.body) return $(element);
+
+    while ((element = element.parentNode) && element != document.body)
+      if (Element.getStyle(element, 'position') != 'static')
+        return $(element);
+
+    return $(document.body);
+  },
+
+  viewportOffset: function(forElement) {
+    var valueT = 0, valueL = 0;
+
+    var element = forElement;
+    do {
+      valueT += element.offsetTop  || 0;
+      valueL += element.offsetLeft || 0;
+
+      // Safari fix
+      if (element.offsetParent == document.body &&
+        Element.getStyle(element, 'position') == 'absolute') break;
+
+    } while (element = element.offsetParent);
+
+    element = forElement;
+    do {
+      if (!Prototype.Browser.Opera || element.tagName == 'BODY') {
+        valueT -= element.scrollTop  || 0;
+        valueL -= element.scrollLeft || 0;
+      }
+    } while (element = element.parentNode);
+
+    return Element._returnOffset(valueL, valueT);
+  },
+
+  clonePosition: function(element, source) {
+    var options = Object.extend({
+      setLeft:    true,
+      setTop:     true,
+      setWidth:   true,
+      setHeight:  true,
+      offsetTop:  0,
+      offsetLeft: 0
+    }, arguments[2] || { });
+
+    // find page position of source
+    source = $(source);
+    var p = source.viewportOffset();
+
+    // 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();
+    }
+
+    // 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';
+    if (options.setHeight) element.style.height = source.offsetHeight + 'px';
+    return element;
+  }
+};
+
+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(proceed, element, style) {
+      switch (style) {
+        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()])
+            return dim + 'px';
+
+          var properties;
+          if (style === 'height') {
+            properties = ['border-top-width', 'padding-top',
+             'padding-bottom', 'border-bottom-width'];
+          }
+          else {
+            properties = ['border-left-width', 'padding-left',
+             'padding-right', 'border-right-width'];
+          }
+          return properties.inject(dim, function(memo, property) {
+            var val = proceed(element, property);
+            return val === null ? memo : memo - parseInt(val, 10);
+          }) + 'px';
+        default: return proceed(element, style);
+      }
+    }
+  );
+
+  Element.Methods.readAttribute = Element.Methods.readAttribute.wrap(
+    function(proceed, element, attribute) {
+      if (attribute === 'title') return element.title;
+      return proceed(element, attribute);
+    }
+  );
+}
+
+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);
+      var position = element.getStyle('position');
+      if (position !== 'static') return proceed(element);
+      element.setStyle({ position: 'relative' });
+      var value = proceed(element);
+      element.setStyle({ position: position });
+      return value;
+    }
+  );
+
+  $w('positionedOffset viewportOffset').each(function(method) {
+    Element.Methods[method] = Element.Methods[method].wrap(
+      function(proceed, element) {
+        element = $(element);
+        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 });
+        element.setStyle({ position: 'relative' });
+        var value = proceed(element);
+        element.setStyle({ position: position });
+        return value;
+      }
+    );
+  });
+
+  Element.Methods.getStyle = function(element, style) {
+    element = $(element);
+    style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize();
+    var value = element.style[style];
+    if (!value && element.currentStyle) value = element.currentStyle[style];
+
+    if (style == 'opacity') {
+      if (value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/))
+        if (value[1]) return parseFloat(value[1]) / 100;
+      return 1.0;
+    }
+
+    if (value == 'auto') {
+      if ((style == 'width' || style == 'height') && (element.getStyle('display') != 'none'))
+        return element['offset' + style.capitalize()] + 'px';
+      return null;
+    }
+    return value;
+  };
+
+  Element.Methods.setOpacity = function(element, value) {
+    function stripAlpha(filter){
+      return filter.replace(/alpha\([^\)]*\)/gi,'');
+    }
+    element = $(element);
+    var currentStyle = element.currentStyle;
+    if ((currentStyle && !currentStyle.hasLayout) ||
+      (!currentStyle && element.style.zoom == 'normal'))
+        element.style.zoom = 1;
+
+    var filter = element.getStyle('filter'), style = element.style;
+    if (value == 1 || value === '') {
+      (filter = stripAlpha(filter)) ?
+        style.filter = filter : style.removeAttribute('filter');
+      return element;
+    } else if (value < 0.00001) value = 0;
+    style.filter = stripAlpha(filter) +
+      'alpha(opacity=' + (value * 100) + ')';
+    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();
+        },
+        title: function(element) {
+          return element.title;
+        }
+      }
+    }
+  };
+
+  Element._attributeTranslations.write = {
+    names: Object.extend({
+      cellpadding: 'cellPadding',
+      cellspacing: 'cellSpacing'
+    }, Element._attributeTranslations.read.names),
+    values: {
+      checked: function(element, value) {
+        element.checked = !!value;
+      },
+
+      style: function(element, value) {
+        element.style.cssText = value ? value : '';
+      }
+    }
+  };
+
+  Element._attributeTranslations.has = {};
+
+  $w('colSpan rowSpan vAlign dateTime accessKey tabIndex ' +
+      'encType maxLength readOnly longDesc').each(function(attr) {
+    Element._attributeTranslations.write.names[attr.toLowerCase()] = attr;
+    Element._attributeTranslations.has[attr.toLowerCase()] = attr;
+  });
+
+  (function(v) {
+    Object.extend(v, {
+      href:        v._getAttr,
+      src:         v._getAttr,
+      type:        v._getAttr,
+      action:      v._getAttrNode,
+      disabled:    v._flag,
+      checked:     v._flag,
+      readonly:    v._flag,
+      multiple:    v._flag,
+      onload:      v._getEv,
+      onunload:    v._getEv,
+      onclick:     v._getEv,
+      ondblclick:  v._getEv,
+      onmousedown: v._getEv,
+      onmouseup:   v._getEv,
+      onmouseover: v._getEv,
+      onmousemove: v._getEv,
+      onmouseout:  v._getEv,
+      onfocus:     v._getEv,
+      onblur:      v._getEv,
+      onkeypress:  v._getEv,
+      onkeydown:   v._getEv,
+      onkeyup:     v._getEv,
+      onsubmit:    v._getEv,
+      onreset:     v._getEv,
+      onselect:    v._getEv,
+      onchange:    v._getEv
+    });
+  })(Element._attributeTranslations.read.values);
+}
+
+else if (Prototype.Browser.Gecko && /rv:1\.8\.0/.test(navigator.userAgent)) {
+  Element.Methods.setOpacity = function(element, value) {
+    element = $(element);
+    element.style.opacity = (value == 1) ? 0.999999 :
+      (value === '') ? '' : (value < 0.00001) ? 0 : value;
+    return element;
+  };
+}
+
+else if (Prototype.Browser.WebKit) {
+  Element.Methods.setOpacity = function(element, value) {
+    element = $(element);
+    element.style.opacity = (value == 1 || value === '') ? '' :
+      (value < 0.00001) ? 0 : value;
+
+    if (value == 1)
+      if(element.tagName == 'IMG' && element.width) {
+        element.width++; element.width--;
+      } else try {
+        var n = document.createTextNode(' ');
+        element.appendChild(n);
+        element.removeChild(n);
+      } catch (e) { }
+
+    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 {
+      valueT += element.offsetTop  || 0;
+      valueL += element.offsetLeft || 0;
+      if (element.offsetParent == document.body)
+        if (Element.getStyle(element, 'position') == 'absolute') break;
+
+      element = element.offsetParent;
+    } while (element);
+
+    return Element._returnOffset(valueL, valueT);
+  };
+}
+
+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')) {
+  Element.Methods.replace = function(element, content) {
+    element = $(element);
+
+    if (content && content.toElement) content = content.toElement();
+    if (Object.isElement(content)) {
+      element.parentNode.replaceChild(content, element);
+      return element;
+    }
+
+    content = Object.toHTML(content);
+    var parent = element.parentNode, tagName = parent.tagName.toUpperCase();
+
+    if (Element._insertionTranslations.tags[tagName]) {
+      var nextSibling = element.next();
+      var fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
+      parent.removeChild(element);
+      if (nextSibling)
+        fragments.each(function(node) { parent.insertBefore(node, nextSibling) });
+      else
+        fragments.each(function(node) { parent.appendChild(node) });
+    }
+    else element.outerHTML = content.stripScripts();
+
+    content.evalScripts.bind(content).defer();
+    return element;
+  };
+}
+
+Element._returnOffset = function(l, t) {
+  var result = [l, t];
+  result.left = l;
+  result.top = t;
+  return result;
+};
+
+Element._getContentFromAnonymousElement = function(tagName, html) {
+  var div = new Element('div'), t = Element._insertionTranslations.tags[tagName];
+  if (t) {
+    div.innerHTML = t[0] + html + t[1];
+    t[2].times(function() { div = div.firstChild });
+  } else div.innerHTML = html;
+  return $A(div.childNodes);
+};
+
+Element._insertionTranslations = {
+  before: function(element, node) {
+    element.parentNode.insertBefore(node, element);
+  },
+  top: function(element, node) {
+    element.insertBefore(node, element.firstChild);
+  },
+  bottom: function(element, node) {
+    element.appendChild(node);
+  },
+  after: function(element, node) {
+    element.parentNode.insertBefore(node, element.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(element, attribute) {
+    attribute = Element._attributeTranslations.has[attribute] || attribute;
+    var node = $(element).getAttributeNode(attribute);
+    return node && node.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 Methods = { }, ByTag = Element.Methods.ByTag;
+
+  var extend = Object.extend(function(element) {
+    if (!element || element._extendedByPrototype ||
+        element.nodeType != 1 || element == window) return element;
+
+    var methods = Object.clone(Methods),
+      tagName = element.tagName, property, value;
+
+    // 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();
+    }
+
+    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);
+      }
+    }
+  });
+
+  extend.refresh();
+  return extend;
+})();
+
+Element.hasAttribute = function(element, attribute) {
+  if (element.hasAttribute) return element.hasAttribute(attribute);
+  return Element.Methods.Simulated.hasAttribute(element, attribute);
+};
+
+Element.addMethods = function(methods) {
+  var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag;
+
+  if (!methods) {
+    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 tagName = methods;
+    methods = arguments[1];
+  }
+
+  if (!tagName) Object.extend(Element.Methods, methods || { });
+  else {
+    if (Object.isArray(tagName)) tagName.each(extend);
+    else extend(tagName);
+  }
+
+  function extend(tagName) {
+    tagName = tagName.toUpperCase();
+    if (!Element.Methods.ByTag[tagName])
+      Element.Methods.ByTag[tagName] = { };
+    Object.extend(Element.Methods.ByTag[tagName], methods);
+  }
+
+  function copy(methods, destination, onlyIfAbsent) {
+    onlyIfAbsent = onlyIfAbsent || false;
+    for (var property in methods) {
+      var value = methods[property];
+      if (!Object.isFunction(value)) continue;
+      if (!onlyIfAbsent || !(property in destination))
+        destination[property] = value.methodize();
+    }
+  }
+
+  function findDOMClass(tagName) {
+    var klass;
+    var trans = {
+      "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 (trans[tagName]) klass = 'HTML' + trans[tagName] + 'Element';
+    if (window[klass]) return window[klass];
+    klass = 'HTML' + tagName + 'Element';
+    if (window[klass]) return window[klass];
+    klass = 'HTML' + tagName.capitalize() + 'Element';
+    if (window[klass]) return window[klass];
+
+    window[klass] = { };
+    window[klass].prototype = document.createElement(tagName).__proto__;
+    return window[klass];
+  }
+
+  if (F.ElementExtensions) {
+    copy(Element.Methods, HTMLElement.prototype);
+    copy(Element.Methods.Simulated, HTMLElement.prototype, true);
+  }
+
+  if (F.SpecificElementExtensions) {
+    for (var tag in Element.Methods.ByTag) {
+      var klass = findDOMClass(tag);
+      if (Object.isUndefined(klass)) continue;
+      copy(T[tag], klass.prototype);
+    }
+  }
+
+  Object.extend(Element, Element.Methods);
+  delete Element.ByTag;
+
+  if (Element.extend.refresh) Element.extend.refresh();
+  Element.cache = { };
+};
+
+document.viewport = {
+  getDimensions: function() {
+    var dimensions = { };
+    var B = Prototype.Browser;
+    $w('width height').each(function(d) {
+      var D = d.capitalize();
+      dimensions[d] = (B.WebKit && !document.evaluate) ? self['inner' + D] :
+        (B.Opera) ? document.body['client' + D] : document.documentElement['client' + D];
+    });
+    return dimensions;
+  },
+
+  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);
+  }
+};
+/* 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. */
+
+var Selector = Class.create({
+  initialize: function(expression) {
+    this.expression = expression.strip();
+    this.compileMatcher();
+  },
+
+  shouldUseXPath: function() {
+    if (!Prototype.BrowserFeatures.XPath) return false;
+
+    var e = this.expression;
+
+    // Safari 3 chokes on :*-of-type and :empty
+    if (Prototype.Browser.WebKit &&
+     (e.include("-of-type") || e.include(":empty")))
+      return false;
+
+    // XPath can't do namespaced attributes, nor can it read
+    // the "checked" property from DOM nodes
+    if ((/(\[[\w-]*?:|:checked)/).test(this.expression))
+      return false;
+
+    return true;
+  },
+
+  compileMatcher: function() {
+    if (this.shouldUseXPath())
+      return this.compileXPathMatcher();
+
+    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 e = this.expression, ps = Selector.patterns,
+        x = Selector.xpath, le, m;
+
+    if (Selector._cache[e]) {
+      this.xpath = Selector._cache[e]; return;
+    }
+
+    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));
+          e = e.replace(m[0], '');
+          break;
+        }
+      }
+    }
+
+    this.xpath = this.matcher.join('');
+    Selector._cache[this.expression] = this.xpath;
+  },
+
+  findElements: function(root) {
+    root = root || document;
+    if (this.xpath) return document._getElementsByXPath(this.xpath, root);
+    return this.matcher(root);
+  },
+
+  match: function(element) {
+    this.tokens = [];
+
+    var e = this.expression, ps = Selector.patterns, as = Selector.assertions;
+    var le, p, m;
+
+    while (e && le !== e && (/\S/).test(e)) {
+      le = e;
+      for (var i in ps) {
+        p = ps[i];
+        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)]);
+            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);
+          }
+        }
+      }
+    }
+
+    var match = true, name, matches;
+    for (var i = 0, token; token = this.tokens[i]; i++) {
+      name = token[0], matches = token[1];
+      if (!Selector.assertions[name](element, matches)) {
+        match = false; break;
+      }
+    }
+
+    return match;
+  },
+
+  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(m) {
+      if (m[1] == '*') return '';
+      return "[local-name()='" + m[1].toLowerCase() +
+             "' or local-name()='" + m[1].toUpperCase() + "']";
+    },
+    className:    "[contains(concat(' ', @class, ' '), ' #{1} ')]",
+    id:           "[@id='#{1}']",
+    attrPresence: function(m) {
+      m[1] = m[1].toLowerCase();
+      return new Template("[@#{1}]").evaluate(m);
+    },
+    attr: function(m) {
+      m[1] = m[1].toLowerCase();
+      m[3] = m[5] || m[6];
+      return new Template(Selector.xpath.operators[m[2]]).evaluate(m);
+    },
+    pseudo: function(m) {
+      var h = Selector.xpath.pseudos[m[1]];
+      if (!h) return '';
+      if (Object.isFunction(h)) return h(m);
+      return new Template(Selector.xpath.pseudos[m[1]]).evaluate(m);
+    },
+    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 or translate(text(), ' \t\r\n', '') = '')]",
+      'checked':     "[@checked]",
+      'disabled':    "[@disabled]",
+      'enabled':     "[not(@disabled)]",
+      'not': function(m) {
+        var e = m[6], p = Selector.patterns,
+            x = Selector.xpath, le, v;
+
+        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);
+              exclusion.push("(" + v.substring(1, v.length - 1) + ")");
+              e = e.replace(m[0], '');
+              break;
+            }
+          }
+        }
+        return "[not(" + exclusion.join(" and ") + ")]";
+      },
+      'nth-child':      function(m) {
+        return Selector.xpath.pseudos.nth("(count(./preceding-sibling::*) + 1) ", m);
+      },
+      'nth-last-child': function(m) {
+        return Selector.xpath.pseudos.nth("(count(./following-sibling::*) + 1) ", m);
+      },
+      'nth-of-type':    function(m) {
+        return Selector.xpath.pseudos.nth("position() ", m);
+      },
+      'nth-last-of-type': function(m) {
+        return Selector.xpath.pseudos.nth("(last() + 1 - position()) ", m);
+      },
+      'first-of-type':  function(m) {
+        m[6] = "1"; return Selector.xpath.pseudos['nth-of-type'](m);
+      },
+      'last-of-type':   function(m) {
+        m[6] = "1"; return Selector.xpath.pseudos['nth-last-of-type'](m);
+      },
+      'only-of-type':   function(m) {
+        var p = Selector.xpath.pseudos; return p['first-of-type'](m) + p['last-of-type'](m);
+      },
+      nth: function(fragment, m) {
+        var mm, formula = m[6], predicate;
+        if (formula == 'even') formula = '2n+0';
+        if (formula == 'odd')  formula = '2n+1';
+        if (mm = formula.match(/^(\d+)$/)) // digit only
+          return '[' + fragment + "= " + mm[1] + ']';
+        if (mm = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b
+          if (mm[1] == "-") mm[1] = -1;
+          var a = mm[1] ? Number(mm[1]) : 1;
+          var b = mm[2] ? Number(mm[2]) : 0;
+          predicate = "[((#{fragment} - #{b}) mod #{a} = 0) and " +
+          "((#{fragment} - #{b}) div #{a} >= 0)]";
+          return new Template(predicate).evaluate({
+            fragment: fragment, a: a, b: b });
+        }
+      }
+    }
+  },
+
+  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(m) {
+      m[3] = (m[5] || m[6]);
+      return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}", c); c = false;').evaluate(m);
+    },
+    pseudo: function(m) {
+      if (m[6]) m[6] = m[6].replace(/"/g, '\\"');
+      return new Template('n = h.pseudo(n, "#{1}", "#{6}", r, c); c = false;').evaluate(m);
+    },
+    descendant:   'c = "descendant";',
+    child:        'c = "child";',
+    adjacent:     'c = "adjacent";',
+    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/,
+
+    // 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]+)\]/,
+    attr:         /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/
+  },
+
+  // for Selector.match and Element#match
+  assertions: {
+    tagName: function(element, matches) {
+      return matches[1].toUpperCase() == element.tagName.toUpperCase();
+    },
+
+    className: function(element, matches) {
+      return Element.hasClassName(element, matches[1]);
+    },
+
+    id: function(element, matches) {
+      return element.id === matches[1];
+    },
+
+    attrPresence: function(element, matches) {
+      return Element.hasAttribute(element, matches[1]);
+    },
+
+    attr: function(element, matches) {
+      var nodeValue = Element.readAttribute(element, matches[1]);
+      return nodeValue && Selector.operators[matches[2]](nodeValue, matches[5] || matches[6]);
+    }
+  },
+
+  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++)
+        node._countedByPrototype = _true;
+      return nodes;
+    },
+
+    unmark: function(nodes) {
+      for (var i = 0, node; node = nodes[i]; i++)
+        node._countedByPrototype = undefined;
+      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) {
+        for (var nodes = parentNode.childNodes, i = nodes.length - 1, j = 1; i >= 0; i--) {
+          var node = nodes[i];
+          if (node.nodeType == 1 && (!ofType || node._countedByPrototype)) node.nodeIndex = j++;
+        }
+      } else {
+        for (var i = 0, j = 1, nodes = parentNode.childNodes; node = nodes[i]; i++)
+          if (node.nodeType == 1 && (!ofType || node._countedByPrototype)) node.nodeIndex = j++;
+      }
+    },
+
+    // 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) {
+          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++)
+        h.concat(results, node.getElementsByTagName('*'));
+      return results;
+    },
+
+    child: function(nodes) {
+      var h = Selector.handlers;
+      for (var i = 0, results = [], node; node = nodes[i]; i++) {
+        for (var j = 0, child; child = node.childNodes[j]; j++)
+          if (child.nodeType == 1 && child.tagName != '!') results.push(child);
+      }
+      return results;
+    },
+
+    adjacent: function(nodes) {
+      for (var i = 0, results = [], node; node = nodes[i]; i++) {
+        var next = this.nextElementSibling(node);
+        if (next) results.push(next);
+      }
+      return results;
+    },
+
+    laterSibling: function(nodes) {
+      var h = Selector.handlers;
+      for (var i = 0, results = [], node; node = nodes[i]; i++)
+        h.concat(results, Element.nextSiblings(node));
+      return results;
+    },
+
+    nextElementSibling: function(node) {
+      while (node = node.nextSibling)
+	      if (node.nodeType == 1) return node;
+      return null;
+    },
+
+    previousElementSibling: function(node) {
+      while (node = node.previousSibling)
+        if (node.nodeType == 1) return node;
+      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));
+            return results;
+          } else nodes = this[combinator](nodes);
+          if (tagName == "*") return nodes;
+        }
+        for (var i = 0, node; node = nodes[i]; i++)
+          if (node.tagName.toUpperCase() === uTagName) results.push(node);
+        return results;
+      } else return root.getElementsByTagName(tagName);
+    },
+
+    id: function(nodes, root, id, combinator) {
+      var targetNode = $(id), h = Selector.handlers;
+      if (!targetNode) return [];
+      if (!nodes && root == document) return [targetNode];
+      if (nodes) {
+        if (combinator) {
+          if (combinator == 'child') {
+            for (var i = 0, node; node = nodes[i]; i++)
+              if (targetNode.parentNode == node) return [targetNode];
+          } else if (combinator == 'descendant') {
+            for (var i = 0, node; node = nodes[i]; i++)
+              if (Element.descendantOf(targetNode, node)) return [targetNode];
+          } else if (combinator == 'adjacent') {
+            for (var i = 0, node; node = nodes[i]; i++)
+              if (Selector.handlers.previousElementSibling(targetNode) == node)
+                return [targetNode];
+          } else nodes = h[combinator](nodes);
+        }
+        for (var i = 0, node; node = nodes[i]; i++)
+          if (node == targetNode) return [targetNode];
+        return [];
+      }
+      return (targetNode && Element.descendantOf(targetNode, root)) ? [targetNode] : [];
+    },
+
+    className: function(nodes, root, className, combinator) {
+      if (nodes && combinator) nodes = this[combinator](nodes);
+      return Selector.handlers.byClassName(nodes, root, className);
+    },
+
+    byClassName: function(nodes, root, className) {
+      if (!nodes) nodes = Selector.handlers.descendant([root]);
+      var needle = ' ' + className + ' ';
+      for (var i = 0, results = [], node, nodeClassName; node = nodes[i]; i++) {
+        nodeClassName = node.className;
+        if (nodeClassName.length == 0) continue;
+        if (nodeClassName == className || (' ' + nodeClassName + ' ').include(needle))
+          results.push(node);
+      }
+      return results;
+    },
+
+    attrPresence: function(nodes, root, attr, combinator) {
+      if (!nodes) nodes = root.getElementsByTagName("*");
+      if (nodes && combinator) nodes = this[combinator](nodes);
+      var results = [];
+      for (var i = 0, node; node = nodes[i]; i++)
+        if (Element.hasAttribute(node, attr)) results.push(node);
+      return results;
+    },
+
+    attr: function(nodes, root, attr, value, operator, combinator) {
+      if (!nodes) nodes = root.getElementsByTagName("*");
+      if (nodes && combinator) nodes = this[combinator](nodes);
+      var handler = Selector.operators[operator], results = [];
+      for (var i = 0, node; node = nodes[i]; i++) {
+        var nodeValue = Element.readAttribute(node, attr);
+        if (nodeValue === null) continue;
+        if (handler(nodeValue, value)) results.push(node);
+      }
+      return results;
+    },
+
+    pseudo: function(nodes, name, value, root, combinator) {
+      if (nodes && combinator) nodes = this[combinator](nodes);
+      if (!nodes) nodes = root.getElementsByTagName("*");
+      return Selector.pseudos[name](nodes, value, root);
+    }
+  },
+
+  pseudos: {
+    'first-child': function(nodes, value, root) {
+      for (var i = 0, results = [], node; node = nodes[i]; i++) {
+        if (Selector.handlers.previousElementSibling(node)) continue;
+          results.push(node);
+      }
+      return results;
+    },
+    'last-child': function(nodes, value, root) {
+      for (var i = 0, results = [], node; node = nodes[i]; i++) {
+        if (Selector.handlers.nextElementSibling(node)) continue;
+          results.push(node);
+      }
+      return results;
+    },
+    'only-child': function(nodes, value, root) {
+      var h = Selector.handlers;
+      for (var i = 0, results = [], node; node = nodes[i]; i++)
+        if (!h.previousElementSibling(node) && !h.nextElementSibling(node))
+          results.push(node);
+      return results;
+    },
+    'nth-child':        function(nodes, formula, root) {
+      return Selector.pseudos.nth(nodes, formula, root);
+    },
+    'nth-last-child':   function(nodes, formula, root) {
+      return Selector.pseudos.nth(nodes, formula, root, true);
+    },
+    'nth-of-type':      function(nodes, formula, root) {
+      return Selector.pseudos.nth(nodes, formula, root, false, true);
+    },
+    'nth-last-of-type': function(nodes, formula, root) {
+      return Selector.pseudos.nth(nodes, formula, root, true, true);
+    },
+    'first-of-type':    function(nodes, formula, root) {
+      return Selector.pseudos.nth(nodes, "1", root, false, true);
+    },
+    'last-of-type':     function(nodes, formula, root) {
+      return Selector.pseudos.nth(nodes, "1", root, true, true);
+    },
+    'only-of-type':     function(nodes, formula, root) {
+      var p = Selector.pseudos;
+      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) {
+        if (0 == (i - b) % a && (i - b) / a >= 0) memo.push(i);
+        return memo;
+      });
+    },
+
+    // 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';
+      if (formula == 'odd')  formula = '2n+1';
+      var h = Selector.handlers, results = [], indexed = [], m;
+      h.mark(nodes);
+      for (var i = 0, node; node = nodes[i]; i++) {
+        if (!node.parentNode._countedByPrototype) {
+          h.index(node.parentNode, reverse, ofType);
+          indexed.push(node.parentNode);
+        }
+      }
+      if (formula.match(/^\d+$/)) { // just a number
+        formula = Number(formula);
+        for (var i = 0, node; node = nodes[i]; i++)
+          if (node.nodeIndex == formula) results.push(node);
+      } else if (m = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b
+        if (m[1] == "-") m[1] = -1;
+        var a = m[1] ? Number(m[1]) : 1;
+        var b = m[2] ? Number(m[2]) : 0;
+        var indices = Selector.pseudos.getIndices(a, b, nodes.length);
+        for (var i = 0, node, l = indices.length; node = nodes[i]; i++) {
+          for (var j = 0; j < l; j++)
+            if (node.nodeIndex == indices[j]) results.push(node);
+        }
+      }
+      h.unmark(nodes);
+      h.unmark(indexed);
+      return results;
+    },
+
+    '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 && !node.innerHTML.match(/^\s*$/))) continue;
+        results.push(node);
+      }
+      return results;
+    },
+
+    'not': function(nodes, selector, root) {
+      var h = Selector.handlers, selectorType, m;
+      var exclusions = new Selector(selector).findElements(root);
+      h.mark(exclusions);
+      for (var i = 0, results = [], node; node = nodes[i]; i++)
+        if (!node._countedByPrototype) results.push(node);
+      h.unmark(exclusions);
+      return results;
+    },
+
+    'enabled': function(nodes, value, root) {
+      for (var i = 0, results = [], node; node = nodes[i]; i++)
+        if (!node.disabled) results.push(node);
+      return results;
+    },
+
+    'disabled': function(nodes, value, root) {
+      for (var i = 0, results = [], node; node = nodes[i]; i++)
+        if (node.disabled) results.push(node);
+      return results;
+    },
+
+    'checked': function(nodes, value, root) {
+      for (var i = 0, results = [], node; node = nodes[i]; i++)
+        if (node.checked) results.push(node);
+      return results;
+    }
+  },
+
+  operators: {
+    '=':  function(nv, v) { return nv == v; },
+    '!=': function(nv, v) { return nv != v; },
+    '^=': function(nv, v) { return nv.startsWith(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() + '-'); }
+  },
+
+  split: function(expression) {
+    var expressions = [];
+    expression.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) {
+      expressions.push(m[1].strip());
+    });
+    return expressions;
+  },
+
+  matchElements: function(elements, expression) {
+    var matches = $$(expression), h = Selector.handlers;
+    h.mark(matches);
+    for (var i = 0, results = [], element; element = elements[i]; i++)
+      if (element._countedByPrototype) results.push(element);
+    h.unmark(matches);
+    return results;
+  },
+
+  findElement: function(elements, expression, index) {
+    if (Object.isNumber(expression)) {
+      index = expression; expression = false;
+    }
+    return Selector.matchElements(elements, expression || '*')[index || 0];
+  },
+
+  findChildElements: function(element, expressions) {
+    expressions = Selector.split(expressions.join(','));
+    var results = [], h = Selector.handlers;
+    for (var i = 0, l = expressions.length, selector; i < l; i++) {
+      selector = new Selector(expressions[i].strip());
+      h.concat(results, selector.findElements(element));
+    }
+    return (l > 1) ? h.unique(results) : results;
+  }
+});
+
+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;
+    }
+  });
+}
+
+function $$() {
+  return Selector.findChildElements(document, $A(arguments));
+}
+var Form = {
+  reset: function(form) {
+    $(form).reset();
+    return form;
+  },
+
+  serializeElements: function(elements, options) {
+    if (typeof options != 'object') options = { hash: !!options };
+    else if (Object.isUndefined(options.hash)) options.hash = true;
+    var key, value, submitted = false, submit = options.submit;
+
+    var data = elements.inject({ }, function(result, element) {
+      if (!element.disabled && element.name) {
+        key = element.name; value = $(element).getValue();
+        if (value != null && (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);
+          }
+          else result[key] = value;
+        }
+      }
+      return result;
+    });
+
+    return options.hash ? data : Object.toQueryString(data);
+  }
+};
+
+Form.Methods = {
+  serialize: function(form, options) {
+    return Form.serializeElements(Form.getElements(form), options);
+  },
+
+  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;
+      }
+    );
+  },
+
+  getInputs: function(form, typeName, name) {
+    form = $(form);
+    var inputs = form.getElementsByTagName('input');
+
+    if (!typeName && !name) return $A(inputs).map(Element.extend);
+
+    for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) {
+      var input = inputs[i];
+      if ((typeName && input.type != typeName) || (name && input.name != name))
+        continue;
+      matchingInputs.push(Element.extend(input));
+    }
+
+    return matchingInputs;
+  },
+
+  disable: function(form) {
+    form = $(form);
+    Form.getElements(form).invoke('disable');
+    return form;
+  },
+
+  enable: function(form) {
+    form = $(form);
+    Form.getElements(form).invoke('enable');
+    return form;
+  },
+
+  findFirstElement: function(form) {
+    var elements = $(form).getElements().findAll(function(element) {
+      return 'hidden' != element.type && !element.disabled;
+    });
+    var firstByIndex = elements.findAll(function(element) {
+      return element.hasAttribute('tabIndex') && element.tabIndex >= 0;
+    }).sortBy(function(element) { return element.tabIndex }).first();
+
+    return firstByIndex ? firstByIndex : elements.find(function(element) {
+      return ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
+    });
+  },
+
+  focusFirstElement: function(form) {
+    form = $(form);
+    form.findFirstElement().activate();
+    return form;
+  },
+
+  request: function(form, options) {
+    form = $(form), options = Object.clone(options || { });
+
+    var params = options.parameters, action = form.readAttribute('action') || '';
+    if (action.blank()) action = window.location.href;
+    options.parameters = form.serialize(true);
+
+    if (params) {
+      if (Object.isString(params)) params = params.toQueryParams();
+      Object.extend(options.parameters, params);
+    }
+
+    if (form.hasAttribute('method') && !options.method)
+      options.method = form.method;
+
+    return new Ajax.Request(action, options);
+  }
+};
+
+/*--------------------------------------------------------------------------*/
+
+Form.Element = {
+  focus: function(element) {
+    $(element).focus();
+    return element;
+  },
+
+  select: function(element) {
+    $(element).select();
+    return element;
+  }
+};
+
+Form.Element.Methods = {
+  serialize: function(element) {
+    element = $(element);
+    if (!element.disabled && element.name) {
+      var value = element.getValue();
+      if (value != undefined) {
+        var pair = { };
+        pair[element.name] = value;
+        return Object.toQueryString(pair);
+      }
+    }
+    return '';
+  },
+
+  getValue: function(element) {
+    element = $(element);
+    var method = element.tagName.toLowerCase();
+    return Form.Element.Serializers[method](element);
+  },
+
+  setValue: function(element, value) {
+    element = $(element);
+    var method = element.tagName.toLowerCase();
+    Form.Element.Serializers[method](element, value);
+    return element;
+  },
+
+  clear: function(element) {
+    $(element).value = '';
+    return element;
+  },
+
+  present: function(element) {
+    return $(element).value != '';
+  },
+
+  activate: function(element) {
+    element = $(element);
+    try {
+      element.focus();
+      if (element.select && (element.tagName.toLowerCase() != 'input' ||
+          !['button', 'reset', 'submit'].include(element.type)))
+        element.select();
+    } catch (e) { }
+    return element;
+  },
+
+  disable: function(element) {
+    element = $(element);
+    element.blur();
+    element.disabled = true;
+    return element;
+  },
+
+  enable: function(element) {
+    element = $(element);
+    element.disabled = false;
+    return element;
+  }
+};
+
+/*--------------------------------------------------------------------------*/
+
+var Field = Form.Element;
+var $F = Form.Element.Methods.getValue;
+
+/*--------------------------------------------------------------------------*/
+
+Form.Element.Serializers = {
+  input: function(element, value) {
+    switch (element.type.toLowerCase()) {
+      case 'checkbox':
+      case 'radio':
+        return Form.Element.Serializers.inputSelector(element, value);
+      default:
+        return Form.Element.Serializers.textarea(element, value);
+    }
+  },
+
+  inputSelector: function(element, value) {
+    if (Object.isUndefined(value)) return element.checked ? element.value : null;
+    else element.checked = !!value;
+  },
+
+  textarea: function(element, value) {
+    if (Object.isUndefined(value)) return element.value;
+    else element.value = value;
+  },
+
+  select: function(element, index) {
+    if (Object.isUndefined(index))
+      return this[element.type == 'select-one' ?
+        'selectOne' : 'selectMany'](element);
+    else {
+      var opt, value, single = !Object.isArray(index);
+      for (var i = 0, length = element.length; i < length; i++) {
+        opt = element.options[i];
+        value = this.optionValue(opt);
+        if (single) {
+          if (value == index) {
+            opt.selected = true;
+            return;
+          }
+        }
+        else opt.selected = index.include(value);
+      }
+    }
+  },
+
+  selectOne: function(element) {
+    var index = element.selectedIndex;
+    return index >= 0 ? this.optionValue(element.options[index]) : null;
+  },
+
+  selectMany: function(element) {
+    var values, length = element.length;
+    if (!length) return null;
+
+    for (var i = 0, values = []; i < length; i++) {
+      var opt = element.options[i];
+      if (opt.selected) values.push(this.optionValue(opt));
+    }
+    return values;
+  },
+
+  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);
+    this.element   = $(element);
+    this.lastValue = this.getValue();
+  },
+
+  execute: function() {
+    var value = this.getValue();
+    if (Object.isString(this.lastValue) && Object.isString(value) ?
+        this.lastValue != value : String(this.lastValue) != String(value)) {
+      this.callback(this.element, value);
+      this.lastValue = value;
+    }
+  }
+});
+
+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(element, callback) {
+    this.element  = $(element);
+    this.callback = callback;
+
+    this.lastValue = this.getValue();
+    if (this.element.tagName.toLowerCase() == 'form')
+      this.registerFormCallbacks();
+    else
+      this.registerCallback(this.element);
+  },
+
+  onElementEvent: function() {
+    var value = this.getValue();
+    if (this.lastValue != value) {
+      this.callback(this.element, value);
+      this.lastValue = value;
+    }
+  },
+
+  registerFormCallbacks: function() {
+    Form.getElements(this.element).each(this.registerCallback, this);
+  },
+
+  registerCallback: function(element) {
+    if (element.type) {
+      switch (element.type.toLowerCase()) {
+        case 'checkbox':
+        case 'radio':
+          Event.observe(element, 'click', this.onElementEvent.bind(this));
+          break;
+        default:
+          Event.observe(element, '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(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);
+  }
+});
+
+Event.Methods = (function() {
+  var isButton;
+
+  if (Prototype.Browser.IE) {
+    var buttonMap = { 0: 1, 1: 4, 2: 2 };
+    isButton = function(event, code) {
+      return event.button == buttonMap[code];
+    };
+
+  } else if (Prototype.Browser.WebKit) {
+    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) {
+      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) {
+      var node = Event.extend(event).target;
+      return Element.extend(node.nodeType == Node.TEXT_NODE ? node.parentNode : node);
+    },
+
+    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);
+    },
+
+    pointer: function(event) {
+      return {
+        x: event.pageX || (event.clientX +
+          (document.documentElement.scrollLeft || document.body.scrollLeft)),
+        y: event.pageY || (event.clientY +
+          (document.documentElement.scrollTop || document.body.scrollTop))
+      };
+    },
+
+    pointerX: function(event) { return Event.pointer(event).x },
+    pointerY: function(event) { return Event.pointer(event).y },
+
+    stop: function(event) {
+      Event.extend(event);
+      event.preventDefault();
+      event.stopPropagation();
+      event.stopped = true;
+    }
+  };
+})();
+
+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) {
+    Object.extend(methods, {
+      stopPropagation: function() { this.cancelBubble = true },
+      preventDefault:  function() { this.returnValue = false },
+      inspect: function() { return "[object Event]" }
+    });
+
+    return function(event) {
+      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),
+        pageX:  pointer.x,
+        pageY:  pointer.y
+      });
+      return Object.extend(event, methods);
+    };
+
+  } else {
+    Event.prototype = Event.prototype || document.createEvent("HTMLEvents").__proto__;
+    Object.extend(Event.prototype, methods);
+    return Prototype.K;
+  }
+})();
+
+Object.extend(Event, (function() {
+  var cache = Event.cache;
+
+  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;
+  }
+
+  function getCacheForID(id) {
+    return cache[id] = cache[id] || { };
+  }
+
+  function getWrappersForEventName(id, eventName) {
+    var c = getCacheForID(id);
+    return c[eventName] = c[eventName] || [];
+  }
+
+  function createWrapper(element, eventName, handler) {
+    var id = getEventID(element);
+    var c = getWrappersForEventName(id, eventName);
+    if (c.pluck("handler").include(handler)) return false;
+
+    var wrapper = function(event) {
+      if (!Event || !Event.extend ||
+        (event.eventName && event.eventName != eventName))
+          return false;
+
+      Event.extend(event);
+      handler.call(element, event);
+    };
+
+    wrapper.handler = handler;
+    c.push(wrapper);
+    return wrapper;
+  }
+
+  function findWrapper(id, eventName, handler) {
+    var c = getWrappersForEventName(id, eventName);
+    return c.find(function(wrapper) { return wrapper.handler == handler });
+  }
+
+  function destroyWrapper(id, eventName, handler) {
+    var c = getCacheForID(id);
+    if (!c[eventName]) return false;
+    c[eventName] = c[eventName].without(findWrapper(id, eventName, handler));
+  }
+
+  function destroyCache() {
+    for (var id in cache)
+      for (var eventName in cache[id])
+        cache[id][eventName] = null;
+  }
+
+  if (window.attachEvent) {
+    window.attachEvent("onunload", destroyCache);
+  }
+
+  return {
+    observe: function(element, eventName, handler) {
+      element = $(element);
+      var name = getDOMEventName(eventName);
+
+      var wrapper = createWrapper(element, eventName, handler);
+      if (!wrapper) return element;
+
+      if (element.addEventListener) {
+        element.addEventListener(name, wrapper, false);
+      } else {
+        element.attachEvent("on" + name, wrapper);
+      }
+
+      return element;
+    },
+
+    stopObserving: function(element, eventName, handler) {
+      element = $(element);
+      var id = getEventID(element), name = getDOMEventName(eventName);
+
+      if (!handler && eventName) {
+        getWrappersForEventName(id, eventName).each(function(wrapper) {
+          element.stopObserving(eventName, wrapper.handler);
+        });
+        return element;
+
+      } else if (!eventName) {
+        Object.keys(getCacheForID(id)).each(function(eventName) {
+          element.stopObserving(eventName);
+        });
+        return element;
+      }
+
+      var wrapper = findWrapper(id, eventName, handler);
+      if (!wrapper) return element;
+
+      if (element.removeEventListener) {
+        element.removeEventListener(name, wrapper, false);
+      } else {
+        element.detachEvent("on" + name, wrapper);
+      }
+
+      destroyWrapper(id, eventName, handler);
+
+      return element;
+    },
+
+    fire: function(element, eventName, memo) {
+      element = $(element);
+      if (element == document && document.createEvent && !element.dispatchEvent)
+        element = document.documentElement;
+
+      var event;
+      if (document.createEvent) {
+        event = document.createEvent("HTMLEvents");
+        event.initEvent("dataavailable", true, true);
+      } else {
+        event = document.createEventObject();
+        event.eventType = "ondataavailable";
+      }
+
+      event.eventName = eventName;
+      event.memo = memo || { };
+
+      if (document.createEvent) {
+        element.dispatchEvent(event);
+      } else {
+        element.fireEvent(event.eventType, event);
+      }
+
+      return Event.extend(event);
+    }
+  };
+})());
+
+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() {
+  /* Support for the DOMContentLoaded event is based on work by Dan Webb,
+     Matthias Miller, Dean Edwards and John Resig. */
+
+  var timer;
+
+  function fireContentLoadedEvent() {
+    if (document.loaded) return;
+    if (timer) window.clearInterval(timer);
+    document.fire("dom:loaded");
+    document.loaded = true;
+  }
+
+  if (document.addEventListener) {
+    if (Prototype.Browser.WebKit) {
+      timer = window.setInterval(function() {
+        if (/loaded|complete/.test(document.readyState))
+          fireContentLoadedEvent();
+      }, 0);
+
+      Event.observe(window, "load", fireContentLoadedEvent);
+
+    } else {
+      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();
+      }
+    };
+  }
+})();
+/*------------------------------- DEPRECATED -------------------------------*/
+
+Hash.toQueryString = Object.toQueryString;
+
+var Toggle = { display: Element.toggle };
+
+Element.Methods.childOf = Element.Methods.descendantOf;
+
+var Insertion = {
+  Before: function(element, content) {
+    return Element.insert(element, {before:content});
+  },
+
+  Top: function(element, content) {
+    return Element.insert(element, {top:content});
+  },
+
+  Bottom: function(element, content) {
+    return Element.insert(element, {bottom:content});
+  },
+
+  After: function(element, content) {
+    return Element.insert(element, {after:content});
+  }
+};
+
+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
+                || document.body.scrollLeft
+                || 0;
+    this.deltaY =  window.pageYOffset
+                || document.documentElement.scrollTop
+                || document.body.scrollTop
+                || 0;
+  },
+
+  // caches x/y coordinate pair to use with overlap
+  within: function(element, x, y) {
+    if (this.includeScrollOffsets)
+      return this.withinIncludingScrolloffsets(element, x, y);
+    this.xcomp = x;
+    this.ycomp = y;
+    this.offset = Element.cumulativeOffset(element);
+
+    return (y >= this.offset[1] &&
+            y <  this.offset[1] + element.offsetHeight &&
+            x >= this.offset[0] &&
+            x <  this.offset[0] + element.offsetWidth);
+  },
+
+  withinIncludingScrolloffsets: function(element, x, y) {
+    var offsetcache = Element.cumulativeScrollOffset(element);
+
+    this.xcomp = x + offsetcache[0] - this.deltaX;
+    this.ycomp = y + offsetcache[1] - this.deltaY;
+    this.offset = Element.cumulativeOffset(element);
+
+    return (this.ycomp >= this.offset[1] &&
+            this.ycomp <  this.offset[1] + element.offsetHeight &&
+            this.xcomp >= this.offset[0] &&
+            this.xcomp <  this.offset[0] + element.offsetWidth);
+  },
+
+  // within must be called directly before
+  overlap: function(mode, element) {
+    if (!mode) return 0;
+    if (mode == 'vertical')
+      return ((this.offset[1] + element.offsetHeight) - this.ycomp) /
+        element.offsetHeight;
+    if (mode == 'horizontal')
+      return ((this.offset[0] + element.offsetWidth) - this.xcomp) /
+        element.offsetWidth;
+  },
+
+  // Deprecation layer -- use newer Element methods now (1.5.2).
+
+  cumulativeOffset: Element.Methods.cumulativeOffset,
+
+  positionedOffset: Element.Methods.positionedOffset,
+
+  absolutize: function(element) {
+    Position.prepare();
+    return Element.absolutize(element);
+  },
+
+  relativize: function(element) {
+    Position.prepare();
+    return Element.relativize(element);
+  },
+
+  realOffset: Element.Methods.cumulativeScrollOffset,
+
+  offsetParent: Element.Methods.getOffsetParent,
+
+  page: Element.Methods.viewportOffset,
+
+  clone: function(source, target, options) {
+    options = options || { };
+    return Element.clonePosition(target, source, options);
+  }
+};
+
+/*--------------------------------------------------------------------------*/
+
+if (!document.getElementsByClassName) document.getElementsByClassName = function(instanceMethods){
+  function iter(name) {
+    return name.blank() ? null : "[contains(concat(' ', @class, ' '), ' " + name + " ')]";
+  }
+
+  instanceMethods.getElementsByClassName = Prototype.BrowserFeatures.XPath ?
+  function(element, className) {
+    className = className.toString().strip();
+    var cond = /\s/.test(className) ? $w(className).map(iter).join('') : iter(className);
+    return cond ? document._getElementsByXPath('.//*' + cond, element) : [];
+  } : function(element, className) {
+    className = className.toString().strip();
+    var elements = [], classNames = (/\s/.test(className) ? $w(className) : null);
+    if (!classNames && !className) return elements;
+
+    var nodes = $(element).getElementsByTagName('*');
+    className = ' ' + className + ' ';
+
+    for (var i = 0, child, cn; child = nodes[i]; i++) {
+      if (child.className && (cn = ' ' + child.className + ' ') && (cn.include(className) ||
+          (classNames && classNames.all(function(name) {
+            return !name.toString().blank() && cn.include(' ' + name + ' ');
+          }))))
+        elements.push(Element.extend(child));
+    }
+    return elements;
+  };
+
+  return function(className, parentElement) {
+    return $(parentElement || document.body).getElementsByClassName(className);
+  };
+}(Element.Methods);
+
+/*--------------------------------------------------------------------------*/
+
+Element.ClassNames = Class.create();
+Element.ClassNames.prototype = {
+  initialize: function(element) {
+    this.element = $(element);
+  },
+
+  _each: function(iterator) {
+    this.element.className.split(/\s+/).select(function(name) {
+      return name.length > 0;
+    })._each(iterator);
+  },
+
+  set: function(className) {
+    this.element.className = className;
+  },
+
+  add: function(classNameToAdd) {
+    if (this.include(classNameToAdd)) return;
+    this.set($A(this).concat(classNameToAdd).join(' '));
+  },
+
+  remove: function(classNameToRemove) {
+    if (!this.include(classNameToRemove)) return;
+    this.set($A(this).without(classNameToRemove).join(' '));
+  },
+
+  toString: function() {
+    return $A(this).join(' ');
+  }
+};
+
+Object.extend(Element.ClassNames.prototype, Enumerable);
+
+/*--------------------------------------------------------------------------*/
+
+Element.addMethods();
Index: /tags/2.0.2/tools/pwg_rel_create.sh
===================================================================
--- /tags/2.0.2/tools/pwg_rel_create.sh	(revision 3278)
+++ /tags/2.0.2/tools/pwg_rel_create.sh	(revision 3278)
@@ -0,0 +1,61 @@
+#!/bin/bash
+
+# +--------------------------------------------------------------------------+
+# |                            pwg_rel_create.sh                             |
+# +--------------------------------------------------------------------------+
+# | author        : Pierrick LE GALL <http://le-gall.net/pierrick>           |
+# | project       : Piwigo                                                   |
+# +--------------------------------------------------------------------------+
+
+if [ $# -lt 2 ]
+then
+  echo
+  echo 'usage : '$(basename $0)' <tag> <version number>'
+  echo
+  exit 1
+fi
+
+tag=$1
+version=$2
+
+name=piwigo-$version
+
+cd /tmp
+if [ -e $name ]
+then
+  rm -rf $name
+fi
+
+if [ -e $version ]
+then
+  rm -rf $version
+fi
+mkdir $version
+
+# cvs export -r $tag -d $version phpwebgallery
+svn export http://svn.gna.org/svn/phpwebgallery/tags/$tag $name
+# creating mysql.inc.php empty and writeable
+touch $name/include/mysql.inc.php
+chmod a+w $name/include/mysql.inc.php
+
+# find $name -name "*.php" \
+#   | xargs grep -l 'branch 1.7' \
+#   | xargs perl -pi -e "s/branch 1.7/${version}/g"
+
+cd /tmp
+for ext in zip # tar.gz tar.bz2
+do
+  file=$version/$name.$ext
+  if [ -f $file ]
+  then
+    rm $name
+  fi
+done
+
+
+zip -r   $version/$name.zip     $name
+# tar -czf $version/$name.tar.gz  $name
+# tar -cjf $version/$name.tar.bz2 $name
+
+cd /tmp/$version
+# md5sum p* >MD5SUMS
Index: /tags/2.0.2/tools/release_creation.readme
===================================================================
--- /tags/2.0.2/tools/release_creation.readme	(revision 3278)
+++ /tags/2.0.2/tools/release_creation.readme	(revision 3278)
@@ -0,0 +1,50 @@
+=====================================
+ Piwigo release creation guide
+=====================================
+
+Technical creation
+==================
+
+I take release 1.7.0 as an example. In URLs "plg" is my personnal Gna!
+username, so use yours.
+
+- tag creation tags/release-1_7_0 :
+
+$ svn copy \
+  -r 1999 \
+  -m "Create release 1.7.0 from branch 1.7 r1999" \
+  svn+ssh://plg@svn.gna.org/svn/phpwebgallery/branch/branch-1_7 \
+  svn+ssh://plg@svn.gna.org/svn/phpwebgallery/tags/release-1_7_0
+
+- checkout new Subversion release 1.7.0
+
+$ svn co svn+ssh://plg@svn.gna.org/svn/phpwebgallery/tags/release-1_7_0 1.7.0
+$ cd 1.7.0
+
+- in include/config_default.inc.php, change the following parameters:
+  - $conf['check_upgrade_feed'] = false;
+  - $conf['show_version'] = false;
+  - $conf['show_gt'] = false;
+  - $conf['die_on_sql_error'] = false;
+
+- in include/constants.php, change the PHPWG_VERSION to 1.7.0
+
+- commit your changes to tags/release-1_7_0, with the following comment:
+
+> New version 1.7.0 hard coded.
+> 
+> Stable release required modifications: don't show version and generation
+> time in footer, don't check the upgrade feed, don't die on sql errors.
+
+$ svn commit
+
+- create the release (pwg_rel_create.sh is in tools directory)
+
+$ mkdir /tmp/1.7.0
+$ cd /tmp/1.7.0
+$ pwg_rel_create.sh release-1_7_0 1.7.0
+$ md5sum p* > MD5SUMS
+
+- upload the release to Gna! download area
+
+$ scp -r /tmp/1.7.0 plg@download.gna.org:/upload/phpwebgallery/release/1.7/
Index: /tags/2.0.2/tools/ws.htm
===================================================================
--- /tags/2.0.2/tools/ws.htm	(revision 3278)
+++ /tags/2.0.2/tools/ws.htm	(revision 3278)
@@ -0,0 +1,402 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<title>PWG web service explorer</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<script type="text/javascript" src="prototype.js" ></script>
+
+<script type="text/javascript">
+
+function setVisibility(id, vis)
+{
+  $(id).style.visibility = vis;
+}
+
+function dumpError(err)
+{
+	var s= 'Error ';
+	if ('string' === typeof err )
+	 s += err;
+	else
+	{
+    s += err.name+'<br/>';
+	 s += err.message;
+	 if (err.stack!=null)
+	 {//mozilla only
+	 	s += '<br/><small><pre>'+ err.stack + '</pre></small>';
+	 }
+	}
+  $("error").update(s);
+}
+
+var gServiceUrl;
+var gCachedMethods;
+
+Ajax.Responders.register({
+
+onException: function(req, err) {
+	try {
+		document.pwgError = err;
+		dumpError(err);
+	}
+	catch (e)
+	{
+		alert (err);
+		alert (err.message);
+	}
+},
+
+onComplete: function(req, transport) {
+	if (!req.responseIsSuccess())
+	{
+		var s = 'Completion failure\n' + transport.status + ' ' + transport.statusText;
+		if (transport.status>=300)
+		{
+			s += '\n';
+			s += transport.responseText.substr(0,1000);
+		}
+		dumpError(s);
+	}
+ }
+}
+);
+
+
+function pwgGetJsonResult(transport)
+{
+  var resp;
+  try {
+		eval('resp = ' + transport.responseText);
+	}
+	catch (e)
+	{
+		var s = e.message;
+		s += '\n' + transport.responseText.substr(0,1000).escapeHTML();
+		throw new Error( s );
+	}
+  if (resp==null || resp.result==null || resp.stat==null || resp.stat!='ok')
+  {
+    var s = 'JSON evaluation error';
+    if (resp)
+    {
+			if (resp.stat!=null) s+= '\n'+resp.stat;
+      if (resp.message!=null) s+= '\n'+ resp.message;
+    }
+    throw new Error(s);
+  }
+  return resp.result;
+}
+
+function pwgChangeUrl()
+{
+  $("error").update("");
+  setVisibility("methodListWrapper", "hidden");
+  $("methodList").update("");
+  setVisibility("methodWrapper", "hidden");
+  setVisibility("methodDetailWrapper", "hidden");
+
+  gServiceUrl = $F('ws_url');
+  gCachedMethods = new Hash();
+
+  try {
+		var ajaxReq = new Ajax.Request(
+				gServiceUrl,
+				{method:'get', parameters:'format=json&method=reflection.getMethodList',
+				 onSuccess: function (r) { onSuccess_getMethodList(r); }
+				}
+			)
+  }catch (e)
+  {
+    dumpError(e);
+  }
+  return false;
+}
+
+function onSuccess_getMethodList(transport)
+{
+	var result = pwgGetJsonResult(transport);
+	var ml = '';
+	for (var i=0; i<result.methods.length; i++)
+	{
+		ml += '<li><a href="#" onclick="return pwgSelectMethod(this.innerHTML)">'+ result.methods[i]+'</a></li>';
+	}
+	$("methodList").update(ml);
+	setVisibility("methodListWrapper", "visible");
+}
+
+function pwgSelectMethod(methodName)
+{
+  $("error").update("");
+  $("methodName").update(methodName);
+  setVisibility("methodDetailWrapper", "hidden");
+  setVisibility("methodWrapper", "visible");
+
+  if ( gCachedMethods[methodName] )
+    fillNewMethod( gCachedMethods[methodName] );
+  else
+  {
+    try {
+  		var ajaxReq = new Ajax.Request(
+  				gServiceUrl,
+  				{method:'get', parameters:'format=json&method=reflection.getMethodDetails&methodName='+methodName,
+  				 onSuccess: function (r) { onSuccess_getMethodDetails(r); }
+  				}
+  			)
+    }catch (e)
+    {
+      dumpError( e );
+    }
+  }
+  return false;
+}
+
+function onSuccess_getMethodDetails(transport)
+{
+	var result = pwgGetJsonResult(transport);
+  fillNewMethod( gCachedMethods[result.name] = result );
+}
+
+function fillNewMethod(method)
+{
+	var methodParamsElt = $("methodParams");
+	while (methodParamsElt.tBodies[0].rows.length)
+		methodParamsElt.tBodies[0].deleteRow(methodParamsElt.tBodies[0].rows.length-1);
+
+	if (method.params && method.params.length>0)
+	{
+  		for (var i=0; i<method.params.length; i++)
+  		{
+  			var row = methodParamsElt.tBodies[0].insertRow(-1);
+  			var isOptional = method.params[i].optional;
+  			var acceptArray = method.params[i].acceptArray;
+  			var defaultValue = method.params[i].defaultValue == null ? '' : method.params[i].defaultValue;
+
+  			row.insertCell(0).innerHTML = method.params[i].name;
+  			row.insertCell(1).innerHTML = '<span title="parameter is '+(isOptional ? 'optional':'required') +'">'+(isOptional ? '?':'*')+'</span>'
+          + (method.params[i].acceptArray ? ' <span title="parameter can be an array; use | (pipe) character to split values">[ ]</span>':'');
+  			row.insertCell(2).innerHTML = '<input id="methodParameterSend_'+i+'" type="checkbox" '+(isOptional ? '':'checked="checked"')+'/>';
+  			row.insertCell(3).innerHTML = '<input id="methodParameterValue_'+i+'"" value="'+defaultValue+'" style="width:99%" onchange="$(\'methodParameterSend_'+i+'\').checked=true;"/>';
+  		}
+ 	}
+	$("methodDescription").update(method.description);
+	setVisibility("methodDetailWrapper", "visible");
+}
+
+function pwgInvokeMethod( newWindow )
+{
+	var methodName = $('methodName').innerHTML;
+	var method = gCachedMethods[methodName];
+
+  var reqUrl = gServiceUrl;
+  reqUrl += "?format="+$F('responseFormat');
+
+  if ($('requestFormat').value == 'get')
+  {
+    reqUrl += "&method="+methodName;
+    for ( var i=0; i<method.params.length; i++)
+    {
+      if (! $('methodParameterSend_'+i).checked)
+        continue;
+
+      if ( method.params[i].acceptArray &&  $F('methodParameterValue_'+i).split('|').length > 1 )
+      {
+        $F('methodParameterValue_'+i).split('|').each(
+            function(v) {
+              reqUrl += '&'+method.params[i].name+'[]='+v;
+            }
+          );
+      }
+      else
+        reqUrl += '&'+method.params[i].name+'='+$F('methodParameterValue_'+i);
+    }
+    if ( !newWindow )
+      $("invokeFrame").src = reqUrl;
+    else
+      window.open(reqUrl);
+  }
+  else
+  {
+    var form = $("invokeForm");
+    form.action = reqUrl;
+    var t = '<input type="hidden" name="'+'method'+'" value="'+methodName+'"/>';
+    for ( var i=0; i<method.params.length; i++)
+    {
+      if (! $('methodParameterSend_'+i).checked)
+        continue;
+
+      if ( method.params[i].acceptArray &&  $F('methodParameterValue_'+i).split('|').length > 1 )
+      {
+        $F('methodParameterValue_'+i).split('|').each(
+            function(v) {
+              t += '<input type="hidden" name="'+method.params[i].name+'[]" value="'+v+'"/>';
+            }
+          );
+      }
+      else
+        t += '<input type="hidden" name="'+method.params[i].name+'" value="'+$F('methodParameterValue_'+i)+'"/>';
+    }
+    form.innerHTML = t;
+    form.target = newWindow ? "_blank" : "invokeFrame";
+    form.submit();
+  }
+  return false;
+}
+</script>
+
+
+<style>
+#methodListWrapper {
+  width: 13em;
+  float: left;
+  display: inline;
+  visibility: hidden;
+}
+
+#methodList {
+  padding-left: 10px;
+  margin-left: 15px;
+}
+
+#methodWrapper {
+  margin-left: 14em;
+  visibility: hidden;
+}
+
+#methodName {
+  margin-top: 0;
+  margin-bottom: 3px;
+}
+
+
+#error {
+  height: 90px;
+  overflow: scroll;
+  color: red;
+}
+
+#methodParams {
+  border-collapse: collapse;
+  font-size: small;
+}
+
+#methodParams input {
+  font-size: 90%;
+  border: 1px solid black;
+  text-indent: 2px;
+}
+
+
+a {
+  color: #02f;
+  background-color: white;
+  text-decoration: underline;
+}
+
+a:hover {
+  color: white;
+  background-color: #02f;
+  text-decoration: none;
+  cursor:pointer;
+}
+
+</style>
+
+</head>
+
+
+<body>
+
+<div>
+ <label>PWG Web service url
+  <input name="ws_url" id="ws_url" size="64"/>
+<script type="text/javascript">
+  var match = document.location.toString().match(/^(https?.*\/)tools\/ws\.html?$/);
+  if (match!=null) $('ws_url').value = match[1]+'ws.php';
+</script>
+ </label>
+ <a href="#" onclick="return pwgChangeUrl();">Go!</a>
+</div>
+
+<div id="error">
+</div>
+
+<div>
+
+<div id="methodListWrapper"><h2>Methods</h2>
+  <ul id="methodList">
+    <li><a href="#" onclick="return pwgSelectMethod(this.innerHTML)">getVersion</a></li>
+  </ul>
+</div>
+
+<div id="methodWrapper">
+  <h2 id="methodName"></h2>
+  <div id="methodDetailWrapper">
+
+    <table>
+    <tr style="vertical-align:top">
+
+    <td>
+      <div id="methodDescription"></div>
+      <table>
+        <tr>
+          <td>Request format:</td>
+          <td>
+            <select id="requestFormat">
+              <option value="get" selected="selected">GET</option>
+              <option value="post">POST</option>
+            </select>
+          </td>
+        </tr>
+
+        <tr>
+          <td>Response format:</td>
+          <td>
+            <select id="responseFormat">
+              <option value="rest" selected="selected">REST (xml)</option>
+              <option value="json">JSON</option>
+              <option value="php">PHP serial</option>
+              <option value="xmlrpc">XML RPC</option>
+            </select>
+          </td>
+        </tr>
+      </table>
+      <p>
+        <a href="#" onclick="return pwgInvokeMethod(false)">Invoke</a>
+        <a href="#" onclick="return pwgInvokeMethod(true)">Invoke (new Window)</a>
+      </p>
+    </td>
+
+
+    <td>
+      <table id="methodParams"  border="1" cellspacing="0" cellpadding="2px">
+        <thead>
+          <tr>
+            <td style="width:150px">Parameter</td>
+            <td>Extra</td>
+            <td>Send</td>
+            <td style="width:160px">Value</td>
+          </tr>
+        </thead>
+        <tbody>
+        </tbody>
+      </table>
+    </td>
+
+    </tr>
+    </table>
+
+		<div style="display:none;">
+			<!-- hiddenForm for POST -->
+			<form method="post" action="" target="invokeFrame" id="invokeForm">
+				<input type="submit" value="submit"/>
+			</form>
+		</div>
+
+    <iframe width="100%" height="400px" id="invokeFrame" name="invokeFrame" style="clear:both"></iframe>
+  </div> <!-- methodDetailWrapper -->
+</div> <!-- methodWrapper -->
+
+</div>
+
+</body>
+</html>
Index: /tags/2.0.2/upgrade.php
===================================================================
--- /tags/2.0.2/upgrade.php	(revision 3278)
+++ /tags/2.0.2/upgrade.php	(revision 3278)
@@ -0,0 +1,383 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+define('PHPWG_ROOT_PATH', './');
+
+// load config file
+$config_file = PHPWG_ROOT_PATH.'include/mysql.inc.php';
+$config_file_contents = @file_get_contents($config_file);
+if ($config_file_contents === false)
+{
+  die('Cannot load '.$config_file);
+}
+$php_end_tag = strrpos($config_file_contents, '?'.'>');
+if ($php_end_tag === false)
+{
+  die('Cannot find php end tag in '.$config_file);
+}
+
+include_once(PHPWG_ROOT_PATH.'include/functions.inc.php');
+include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+include_once(PHPWG_ROOT_PATH.'admin/include/functions_upgrade.php');
+
+include(PHPWG_ROOT_PATH.'include/mysql.inc.php');
+include(PHPWG_ROOT_PATH . 'include/config_default.inc.php');
+@include(PHPWG_ROOT_PATH. 'include/config_local.inc.php');
+
+prepare_conf_upgrade();
+
+include_once(PHPWG_ROOT_PATH.'include/constants.php');
+define('PREFIX_TABLE', $prefixeTable);
+
+// Database connection
+mysql_connect( $cfgHote, $cfgUser, $cfgPassword ) or die ( "Could not connect to database server" );
+mysql_select_db( $cfgBase ) or die ( "Could not connect to database" );
+if ( version_compare(mysql_get_server_info(), '4.1.0', '>=')
+    and defined('DB_CHARSET') and DB_CHARSET!='' )
+{
+  pwg_query('SET NAMES "'.DB_CHARSET.'"');
+}
+
+// +-----------------------------------------------------------------------+
+// |                              functions                                |
+// +-----------------------------------------------------------------------+
+
+/**
+ * list all tables in an array
+ *
+ * @return array
+ */
+function get_tables()
+{
+  $tables = array();
+
+  $query = '
+SHOW TABLES
+;';
+  $result = pwg_query($query);
+
+  while ($row = mysql_fetch_row($result))
+  {
+    if (preg_match('/^'.PREFIX_TABLE.'/', $row[0]))
+    {
+      array_push($tables, $row[0]);
+    }
+  }
+
+  return $tables;
+}
+
+/**
+ * list all columns of each given table
+ *
+ * @return array of array
+ */
+function get_columns_of($tables)
+{
+  $columns_of = array();
+
+  foreach ($tables as $table)
+  {
+    $query = '
+DESC '.$table.'
+;';
+    $result = pwg_query($query);
+
+    $columns_of[$table] = array();
+
+    while ($row = mysql_fetch_row($result))
+    {
+      array_push($columns_of[$table], $row[0]);
+    }
+  }
+
+  return $columns_of;
+}
+
+/**
+ */
+function print_time($message)
+{
+  global $last_time;
+
+  $new_time = get_moment();
+  echo '<pre>['.get_elapsed_time($last_time, $new_time).']';
+  echo ' '.$message;
+  echo '</pre>';
+  flush();
+  $last_time = $new_time;
+}
+
+// +-----------------------------------------------------------------------+
+// |                             playing zone                              |
+// +-----------------------------------------------------------------------+
+
+// echo implode('<br>', get_tables());
+// echo '<pre>'; print_r(get_columns_of(get_tables())); echo '</pre>';
+
+// foreach (get_available_upgrade_ids() as $upgrade_id)
+// {
+//   echo $upgrade_id, '<br>';
+// }
+
+// +-----------------------------------------------------------------------+
+// |                             language                                  |
+// +-----------------------------------------------------------------------+
+if (isset($_GET['language']))
+{
+  $language = strip_tags($_GET['language']);
+}
+else
+{
+  $language = 'en_UK';
+  // Try to get browser language
+  foreach (get_languages('utf-8') as $language_code => $language_name)
+  {
+    if (substr($language_code,0,2) == @substr($_SERVER["HTTP_ACCEPT_LANGUAGE"],0,2))
+    {
+      $language = $language_code;
+      break;
+    }
+  }
+}
+
+if ('fr_FR' == $language) {
+  define('PHPWG_DOMAIN', 'fr.piwigo.org');
+}
+else {
+  define('PHPWG_DOMAIN', 'piwigo.org');
+}
+define('PHPWG_URL', 'http://'.PHPWG_DOMAIN);
+
+load_language( 'common.lang', '', array('language'=>$language, 'target_charset'=>'utf-8', 'no_fallback' => true) );
+load_language( 'admin.lang', '', array('language'=>$language, 'target_charset'=>'utf-8', 'no_fallback' => true) );
+load_language( 'install.lang', '', array('language'=>$language, 'target_charset'=>'utf-8', 'no_fallback' => true) );
+load_language( 'upgrade.lang', '', array('language'=>$language, 'target_charset'=>'utf-8', 'no_fallback' => true) );
+
+// check php version
+if (version_compare(PHP_VERSION, REQUIRED_PHP_VERSION, '<'))
+{
+  include(PHPWG_ROOT_PATH.'install/php5_apache_configuration.php');
+}
+
+// +-----------------------------------------------------------------------+
+// |                        template initialization                        |
+// +-----------------------------------------------------------------------+
+
+include( PHPWG_ROOT_PATH .'include/template.class.php');
+$template = new Template(PHPWG_ROOT_PATH.'admin/template/goto', 'roma');
+$template->set_filenames(array('upgrade'=>'upgrade.tpl'));
+$template->assign(array(
+  'RELEASE' => PHPWG_VERSION,
+  'L_UPGRADE_HELP' => sprintf(l10n('install_help'), PHPWG_URL.'/forum'),
+  )
+);
+
+// +-----------------------------------------------------------------------+
+// |                            upgrade choice                             |
+// +-----------------------------------------------------------------------+
+
+$tables = get_tables();
+$columns_of = get_columns_of($tables);
+
+// find the current release
+if (!in_array('param', $columns_of[PREFIX_TABLE.'config']))
+{
+  // we're in branch 1.3, important upgrade, isn't it?
+  if (in_array(PREFIX_TABLE.'user_category', $tables))
+  {
+    $current_release = '1.3.1';
+  }
+  else
+  {
+    $current_release = '1.3.0';
+  }
+}
+else if (!in_array(PREFIX_TABLE.'user_cache', $tables))
+{
+  $current_release = '1.4.0';
+}
+else if (!in_array(PREFIX_TABLE.'tags', $tables))
+{
+  $current_release = '1.5.0';
+}
+else if ( !in_array(PREFIX_TABLE.'plugins', $tables) )
+{
+  if (!in_array('auto_login_key', $columns_of[PREFIX_TABLE.'user_infos']))
+  {
+    $current_release = '1.6.0';
+  }
+  else
+  {
+    $current_release = '1.6.2';
+  }
+}
+else if (!in_array('md5sum', $columns_of[PREFIX_TABLE.'images']))
+{
+  $current_release = '1.7.0';
+}
+else
+{
+  die('No upgrade required, the database structure is up to date');
+}
+
+// +-----------------------------------------------------------------------+
+// |                            upgrade launch                             |
+// +-----------------------------------------------------------------------+
+$page['infos'] = array();
+$page['errors'] = array();
+$mysql_changes = array();
+
+if (isset($_POST['username']) and isset($_POST['password']))
+{
+  check_upgrade_access_rights($current_release, $_POST['username'], $_POST['password']);
+}
+
+if (isset($_POST['submit']) and check_upgrade())
+{
+  $upgrade_file = PHPWG_ROOT_PATH.'install/upgrade_'.$current_release.'.php';
+  if (is_file($upgrade_file))
+  {
+    $page['upgrade_start'] = get_moment();
+    $conf['die_on_sql_error'] = false;
+    include($upgrade_file);
+
+    // Something to add in mysql.inc.php?
+    if (!empty($mysql_changes))
+    {
+      $config_file_contents = 
+        substr($config_file_contents, 0, $php_end_tag) . "\r\n"
+        . implode("\r\n" , $mysql_changes) . "\r\n"
+        . substr($config_file_contents, $php_end_tag);
+
+      if (!@file_put_contents($config_file, $config_file_contents))
+      {
+        array_push($page['infos'],
+          l10n('in include/mysql.inc.php, before ?>, insert:') . '
+<p><textarea rows="4" cols="40">'.implode("\r\n" , $mysql_changes).'</textarea></p>'
+          );
+      }
+    }
+
+    // Plugins deactivation
+    if (in_array(PREFIX_TABLE.'plugins', $tables))
+    {
+      deactivate_non_standard_plugins();
+    }
+
+    // Create empty local files to avoid log errors
+    create_empty_local_files();
+
+    $page['upgrade_end'] = get_moment();
+
+    $template->assign(
+      'upgrade',
+      array(
+        'VERSION' => $current_release,
+        'TOTAL_TIME' => get_elapsed_time(
+          $page['upgrade_start'],
+          $page['upgrade_end']
+          ),
+        'SQL_TIME' => number_format(
+          $page['queries_time'],
+          3,
+          '.',
+          ' '
+          ).' s',
+        'NB_QUERIES' => $page['count_queries']
+        )
+      );
+
+    array_push($page['infos'],
+      l10n('perform a maintenance check')
+      );
+
+    // Save $page['infos'] in order to restore after maintenance actions
+    $page['infos_sav'] = $page['infos'];
+    $page['infos'] = array();
+
+    // c13y_upgrade plugin means "check integrity after upgrade", so it
+    // becomes useful just after an upgrade
+    $query = '
+REPLACE INTO '.PLUGINS_TABLE.'
+  (id, state)
+  VALUES (\'c13y_upgrade\', \'active\')
+;';
+    pwg_query($query);
+
+    // Delete cache data
+    invalidate_user_cache(true);
+    $template->delete_compiled_templates();
+
+    // Tables Maintenance
+    // Disabled optimization table for branch 2.0 only
+    //do_maintenance_all_tables();
+
+    // Restore $page['infos'] in order to hide informations messages from functions calles
+    // errors messages are not hide
+    $page['infos'] = $page['infos_sav'];
+
+  }
+}
+
+// +-----------------------------------------------------------------------+
+// |                          start template output                        |
+// +-----------------------------------------------------------------------+
+else
+{
+  foreach (get_languages('utf-8') as $language_code => $language_name)
+  {
+    if ($language == $language_code)
+    {
+      $template->assign('language_selection', $language_code);
+    }
+    $languages_options[$language_code] = $language_name;
+  }
+  $template->assign('language_options', $languages_options);
+
+  $template->assign('introduction', array(
+    'CURRENT_RELEASE' => $current_release,
+    'F_ACTION' => 'upgrade.php?language=' . $language));
+
+  if (!check_upgrade())
+  {
+    $template->assign('login', true);
+  }
+}
+
+if (count($page['errors']) != 0)
+{
+  $template->assign('errors', $page['errors']);
+}
+
+if (count($page['infos']) != 0)
+{
+  $template->assign('infos', $page['infos']);
+}
+
+// +-----------------------------------------------------------------------+
+// |                          sending html code                            |
+// +-----------------------------------------------------------------------+
+
+$template->pparse('upgrade');
+?>
Index: /tags/2.0.2/upgrade_feed.php
===================================================================
--- /tags/2.0.2/upgrade_feed.php	(revision 3278)
+++ /tags/2.0.2/upgrade_feed.php	(revision 3278)
@@ -0,0 +1,109 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+//check php version
+if (version_compare(PHP_VERSION, '5', '<'))
+{
+  die('Piwigo requires PHP 5 or above.');
+}
+
+define('PHPWG_ROOT_PATH', './');
+
+include_once(PHPWG_ROOT_PATH.'include/functions.inc.php');
+include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+include_once(PHPWG_ROOT_PATH.'admin/include/functions_upgrade.php');
+include(PHPWG_ROOT_PATH.'include/mysql.inc.php');
+include(PHPWG_ROOT_PATH . 'include/config_default.inc.php');
+@include(PHPWG_ROOT_PATH. 'include/config_local.inc.php');
+
+// +-----------------------------------------------------------------------+
+// | Check Access and exit when it is not ok                               |
+// +-----------------------------------------------------------------------+
+
+if (!$conf['check_upgrade_feed'])
+{
+  die("upgrade feed is not active");
+}
+
+prepare_conf_upgrade();
+
+define('PREFIX_TABLE', $prefixeTable);
+define('UPGRADES_PATH', PHPWG_ROOT_PATH.'install/db');
+
+// +-----------------------------------------------------------------------+
+// |                         Database connection                           |
+// +-----------------------------------------------------------------------+
+
+mysql_connect($cfgHote, $cfgUser, $cfgPassword) or die("Could not connect to database server");
+mysql_select_db($cfgBase) or die("Could not connect to database");
+if ( version_compare(mysql_get_server_info(), '4.1.0', '>=')
+    and defined('DB_CHARSET') and DB_CHARSET!='' )
+{
+  pwg_query('SET NAMES "'.DB_CHARSET.'"');
+}
+
+
+// +-----------------------------------------------------------------------+
+// |                              Upgrades                                 |
+// +-----------------------------------------------------------------------+
+
+// retrieve already applied upgrades
+$query = '
+SELECT id
+  FROM '.PREFIX_TABLE.'upgrade
+;';
+$applied = array_from_query($query, 'id');
+
+// retrieve existing upgrades
+$existing = get_available_upgrade_ids();
+
+// which upgrades need to be applied?
+$to_apply = array_diff($existing, $applied);
+
+echo '<pre>';
+echo count($to_apply).' upgrades to apply';
+
+foreach ($to_apply as $upgrade_id)
+{
+  unset($upgrade_description);
+
+  echo "\n\n";
+  echo '=== upgrade '.$upgrade_id."\n";
+
+  // include & execute upgrade script. Each upgrade script must contain
+  // $upgrade_description variable which describe briefly what the upgrade
+  // script does.
+  include(UPGRADES_PATH.'/'.$upgrade_id.'-database.php');
+
+  // notify upgrade
+  $query = '
+INSERT INTO '.PREFIX_TABLE.'upgrade
+  (id, applied, description)
+  VALUES
+  (\''.$upgrade_id.'\', NOW(), \''.$upgrade_description.'\')
+;';
+  pwg_query($query);
+}
+
+echo '</pre>';
+?>
Index: /tags/2.0.2/upload.php
===================================================================
--- /tags/2.0.2/upload.php	(revision 3278)
+++ /tags/2.0.2/upload.php	(revision 3278)
@@ -0,0 +1,431 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+define('PHPWG_ROOT_PATH','./');
+
+// +-----------------------------------------------------------------------+
+// | Includes                                                              |
+// +-----------------------------------------------------------------------+
+include_once(PHPWG_ROOT_PATH.'include/common.inc.php');
+
+// +-----------------------------------------------------------------------+
+// | Check Access and exit when user status is not ok                      |
+// +-----------------------------------------------------------------------+
+check_status($conf['upload_user_access']);
+
+$username = !empty($_POST['username']) ? $_POST['username']:(is_classic_user() ? $user['username'] : '');
+$mail_address = !empty($_POST['mail_address']) ? $_POST['mail_address'] : (is_classic_user() ? $user['email'] : '');
+$name = !empty($_POST['name']) ? $_POST['name'] : '';
+$author = !empty($_POST['author']) ? $_POST['author'] : (is_classic_user() ? $user['username'] : '');
+$date_creation = !empty($_POST['date_creation']) ? $_POST['date_creation'] : '';
+$comment = !empty($_POST['comment']) ? $_POST['comment'] : '';
+
+//------------------------------------------------------------------- functions
+// The validate_upload function checks if the image of the given path is valid.
+// A picture is valid when :
+//     - width, height and filesize are not higher than the maximum
+//       filesize authorized by the administrator
+//     - the type of the picture is among jpg, gif and png
+// The function returns an array containing :
+//     - $result['type'] contains the type of the image ('jpg', 'gif' or 'png')
+//     - $result['error'] contains an array with the different errors
+//       found with the picture
+function validate_upload( $temp_name, $my_max_file_size,
+                          $image_max_width, $image_max_height )
+{
+  global $conf, $lang, $page, $mail_address;
+
+  $result = array();
+  $result['error'] = array();
+  //echo $_FILES['picture']['name']."<br />".$temp_name;
+  $extension = get_extension( $_FILES['picture']['name'] );
+  if (!in_array($extension, $conf['picture_ext']))
+  {
+    array_push( $result['error'], l10n('upload_advise_filetype') );
+    return $result;
+  }
+  if ( !isset( $_FILES['picture'] ) )
+  {
+    // do we even have a file?
+    array_push( $result['error'], "You did not upload anything!" );
+  }
+  else if ( $_FILES['picture']['size'] > $my_max_file_size * 1024 )
+  {
+    array_push( $result['error'],
+                l10n('upload_advise_filesize').$my_max_file_size.' KB' );
+  }
+  else
+  {
+    // check if we are allowed to upload this file_type
+    // upload de la photo sous un nom temporaire
+    if ( !move_uploaded_file( $_FILES['picture']['tmp_name'], $temp_name ) )
+    {
+      array_push( $result['error'], l10n('upload_cannot_upload') );
+    }
+    else
+    {
+      $size = getimagesize( $temp_name );
+      if ( isset( $image_max_width )
+           and $image_max_width != ""
+           and $size[0] > $image_max_width )
+      {
+        array_push( $result['error'],
+                    l10n('upload_advise_width').$image_max_width.' px' );
+      }
+      if ( isset( $image_max_height )
+           and $image_max_height != ""
+           and $size[1] > $image_max_height )
+      {
+        array_push( $result['error'],
+                    l10n('upload_advise_height').$image_max_height.' px' );
+      }
+      // $size[2] == 1 means GIF
+      // $size[2] == 2 means JPG
+      // $size[2] == 3 means PNG
+      switch ( $size[2] )
+      {
+      case 1 : $result['type'] = 'gif'; break;
+      case 2 : $result['type'] = 'jpg'; break;
+      case 3 : $result['type'] = 'png'; break;
+      default :
+        array_push( $result['error'], l10n('upload_advise_filetype') );
+      }
+    }
+  }
+  if ( sizeof( $result['error'] ) > 0 )
+  {
+    // destruction de l'image avec le nom temporaire
+    @unlink( $temp_name );
+  }
+  else
+  {
+    @chmod( $temp_name, 0644);
+  }
+
+  //------------------------------------------------------------ log informations
+  pwg_log();
+
+  return $result;
+}
+
+//-------------------------------------------------- access authorization check
+if (isset($_POST['category']) and is_numeric($_POST['category']))
+{
+  $page['category'] = $_POST['category'];
+}
+else
+if (isset($_GET['cat']) and is_numeric($_GET['cat']))
+{
+  $page['category'] = $_GET['cat'];
+}
+else
+{
+  $page['category'] = null;
+}
+
+if (! empty($page['category']))
+{
+  check_restrictions($page['category']);
+  $category = get_cat_info($page['category']);
+  $category['cat_dir'] = get_complete_dir($page['category']);
+
+  if (url_is_remote($category['cat_dir']) or !$category['uploadable'])
+  {
+    page_forbidden('upload not allowed');
+  }
+}
+else
+{
+  if (isset($_POST['submit']))
+  {
+    // $page['category'] may be set by a futur plugin but without it
+    bad_request('invalid parameters');
+  }
+  else
+  {
+    $category = null;
+  }
+}
+
+$error = array();
+$page['upload_successful'] = false;
+if ( isset( $_GET['waiting_id'] ) )
+{
+  $page['waiting_id'] = $_GET['waiting_id'];
+}
+
+//-------------------------------------------------------------- picture upload
+// verfying fields
+if ( isset( $_POST['submit'] ) and !isset( $_GET['waiting_id'] ) )
+{
+  $path = $category['cat_dir'].$_FILES['picture']['name'];
+  if ( @is_file( $path ) )
+  {
+    array_push( $error, l10n('upload_file_exists') );
+  }
+  // test de la présence des champs obligatoires
+  if ( empty($_FILES['picture']['name']))
+  {
+    array_push( $error, l10n('upload_filenotfound') );
+  }
+  if ( !ereg( "([_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)+)",
+             $_POST['mail_address'] ) )
+  {
+    array_push( $error, l10n('reg_err_mail_address') );
+  }
+  if ( empty($_POST['username']) )
+  {
+    array_push( $error, l10n('upload_err_username') );
+  }
+
+  $date_creation = '';
+  if ( !empty($_POST['date_creation']) )
+  {
+    list( $day,$month,$year ) = explode( '/', $_POST['date_creation'] );
+    // int checkdate ( int month, int day, int year)
+    if (checkdate($month, $day, $year))
+    {
+      $date_creation = $year.'-'.$month.'-'.$day;
+    }
+    else
+    {
+      array_push( $error, l10n('err_date') );
+    }
+  }
+  // creation of the "infos" field :
+  // <infos author="Pierrick LE GALL" comment="my comment"
+  //        date_creation="2004-08-14" name="" />
+  $xml_infos = '<infos ';
+  $xml_infos.= encodeAttribute('author', $_POST['author']);
+  $xml_infos.= encodeAttribute('comment', $_POST['comment']);
+  $xml_infos.= encodeAttribute('date_creation', $date_creation);
+  $xml_infos.= encodeAttribute('name', $_POST['name']);
+  $xml_infos.= ' />';
+
+  if ( !preg_match( '/^[a-zA-Z0-9-_.]+$/', $_FILES['picture']['name'] ) )
+  {
+    array_push( $error, l10n('update_wrong_dirname') );
+  }
+
+  if ( sizeof( $error ) == 0 )
+  {
+    $result = validate_upload( $path, $conf['upload_maxfilesize'],
+                               $conf['upload_maxwidth'],
+                               $conf['upload_maxheight']  );
+    for ( $j = 0; $j < sizeof( $result['error'] ); $j++ )
+    {
+      array_push( $error, $result['error'][$j] );
+    }
+  }
+
+  if ( sizeof( $error ) == 0 )
+  {
+    $query = 'insert into '.WAITING_TABLE;
+    $query.= ' (storage_category_id,file,username,mail_address,date,infos)';
+    $query.= ' values ';
+    $query.= '('.$page['category'].",'".$_FILES['picture']['name']."'";
+    $query.= ",'".htmlspecialchars( $_POST['username'], ENT_QUOTES)."'";
+    $query.= ",'".$_POST['mail_address']."',".time().",'".$xml_infos."')";
+    $query.= ';';
+    pwg_query( $query );
+    $page['waiting_id'] = mysql_insert_id();
+
+    if ($conf['email_admin_on_picture_uploaded'])
+    {
+      include_once(PHPWG_ROOT_PATH.'include/functions_mail.inc.php');
+
+      $waiting_url = get_absolute_root_url().'admin.php?page=upload';
+
+      $keyargs_content = array
+      (
+        get_l10n_args('Category: %s', get_cat_display_name($category['upper_names'], null, false)),
+        get_l10n_args('Picture name: %s', $_FILES['picture']['name']),
+        get_l10n_args('User: %s', $_POST['username']),
+        get_l10n_args('Email: %s', $_POST['mail_address']),
+        get_l10n_args('Picture name: %s', $_POST['name']),
+        get_l10n_args('Author: %s', $_POST['author']),
+        get_l10n_args('Creation date: %s', $_POST['date_creation']),
+        get_l10n_args('Comment: %s', $_POST['comment']),
+        get_l10n_args('', ''),
+        get_l10n_args('Waiting page: %s', $waiting_url)
+      );
+
+      pwg_mail_notification_admins
+      (
+        get_l10n_args('Picture uploaded by %s', $_POST['username']),
+        $keyargs_content
+      );
+    }
+  }
+}
+
+//------------------------------------------------------------ thumbnail upload
+if ( isset( $_POST['submit'] ) and isset( $_GET['waiting_id'] ) )
+{
+  // upload of the thumbnail
+  $query = 'select file';
+  $query.= ' from '.WAITING_TABLE;
+  $query.= ' where id = '.$_GET['waiting_id'];
+  $query.= ';';
+  $result= pwg_query( $query );
+  $row = mysql_fetch_array( $result );
+  $file = substr ( $row['file'], 0, strrpos ( $row['file'], ".") );
+  $extension = get_extension( $_FILES['picture']['name'] );
+
+  if (($path = mkget_thumbnail_dir($category['cat_dir'], $error)) != false)
+  {
+    $path.= '/'.$conf['prefix_thumbnail'].$file.'.'.$extension;
+    $result = validate_upload( $path, $conf['upload_maxfilesize'],
+                               $conf['upload_maxwidth_thumbnail'],
+                               $conf['upload_maxheight_thumbnail']  );
+    for ( $j = 0; $j < sizeof( $result['error'] ); $j++ )
+    {
+      array_push( $error, $result['error'][$j] );
+    }
+  }
+
+  if ( sizeof( $error ) == 0 )
+  {
+    $query = 'update '.WAITING_TABLE;
+    $query.= " set tn_ext = '".$extension."'";
+    $query.= ' where id = '.$_GET['waiting_id'];
+    $query.= ';';
+    pwg_query( $query );
+    $page['upload_successful'] = true;
+  }
+}
+
+//
+// Start output of page
+//
+$title= l10n('upload_title');
+$page['body_id'] = 'theUploadPage';
+include(PHPWG_ROOT_PATH.'include/page_header.php');
+$template->set_filenames(array('upload'=>'upload.tpl'));
+
+// Load category list
+$query = '
+SELECT
+  id, name, uppercats, global_rank
+FROM '.CATEGORIES_TABLE.' INNER JOIN '.USER_CACHE_CATEGORIES_TABLE.'
+  ON id = cat_id and user_id = '.$user['id'].'
+WHERE
+  uploadable = \'true\'
+  '.get_sql_condition_FandF
+    (
+      array
+        (
+          'visible_categories' => 'id',
+        ),
+      'AND'
+    ).'
+;';
+display_select_cat_wrapper($query, array($page['category']), 'categories');
+
+$u_form = PHPWG_ROOT_PATH.'upload.php?cat='.$page['category'];
+if ( isset( $page['waiting_id'] ) )
+{
+$u_form.= '&amp;waiting_id='.$page['waiting_id'];
+}
+
+if ( isset( $page['waiting_id'] ) )
+{
+  $advise_title = l10n('upload_advise_thumbnail').$_FILES['picture']['name'];
+}
+else
+{
+  $advise_title = l10n('Choose an image');
+}
+
+$template->assign(
+  array(
+    'ADVISE_TITLE' => $advise_title,
+    'NAME' => $username,
+    'EMAIL' => $mail_address,
+    'NAME_IMG' => $name,
+    'AUTHOR_IMG' => $author,
+    'DATE_IMG' => $date_creation,
+    'COMMENT_IMG' => $comment,
+
+    'F_ACTION' => $u_form,
+
+    'U_RETURN' => make_index_url(array('category' => $category)),
+    )
+  );
+
+$template->assign('errors', $error);
+$template->assign('UPLOAD_SUCCESSFUL', $page['upload_successful'] );
+
+if ( !$page['upload_successful'] )
+{
+//--------------------------------------------------------------------- advises
+  if ( !empty($conf['upload_maxfilesize']) )
+  {
+    $content = l10n('upload_advise_filesize');
+    $content.= $conf['upload_maxfilesize'].' KB';
+    $template->append('advises', $content);
+  }
+
+  if ( isset( $page['waiting_id'] ) )
+  {
+    if ( $conf['upload_maxwidth_thumbnail'] != '' )
+    {
+      $content = l10n('upload_advise_width');
+      $content.= $conf['upload_maxwidth_thumbnail'].' px';
+      $template->append('advises', $content);
+    }
+    if ( $conf['upload_maxheight_thumbnail'] != '' )
+    {
+      $content = l10n('upload_advise_height');
+      $content.= $conf['upload_maxheight_thumbnail'].' px';
+      $template->append('advises', $content);
+    }
+  }
+  else
+  {
+    if ( $conf['upload_maxwidth'] != '' )
+    {
+      $content = l10n('upload_advise_width');
+      $content.= $conf['upload_maxwidth'].' px';
+      $template->append('advises', $content);
+    }
+    if ( $conf['upload_maxheight'] != '' )
+    {
+      $content = l10n('upload_advise_height');
+      $content.= $conf['upload_maxheight'].' px';
+      $template->append('advises', $content);
+    }
+  }
+  $template->append('advises', l10n('upload_advise_filetype'));
+
+//----------------------------------------- optionnal username and mail address
+  if ( !isset( $page['waiting_id'] ) )
+  {
+    $template->assign('SHOW_FORM_FIELDS', true);
+  }
+}
+
+//----------------------------------------------------------- html code display
+$template->parse('upload');
+include(PHPWG_ROOT_PATH.'include/page_tail.php');
+?>
Index: /tags/2.0.2/ws.php
===================================================================
--- /tags/2.0.2/ws.php	(revision 3278)
+++ /tags/2.0.2/ws.php	(revision 3278)
@@ -0,0 +1,352 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based picture gallery                                  |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2009 Piwigo Team                  http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify  |
+// | it under the terms of the GNU General Public License as published by  |
+// | the Free Software Foundation                                          |
+// |                                                                       |
+// | This program is distributed in the hope that it will be useful, but   |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
+// | General Public License for more details.                              |
+// |                                                                       |
+// | You should have received a copy of the GNU General Public License     |
+// | along with this program; if not, write to the Free Software           |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA.                                                                  |
+// +-----------------------------------------------------------------------+
+
+define ('PHPWG_ROOT_PATH', './');
+
+include_once(PHPWG_ROOT_PATH.'include/common.inc.php');
+check_status(ACCESS_FREE);
+include_once(PHPWG_ROOT_PATH.'include/ws_core.inc.php');
+
+if ( !$conf['allow_web_services'] )
+{
+  page_forbidden('Web services are disabled');
+}
+
+/**
+ * event handler that registers standard methods with the web service
+ */
+function ws_addDefaultMethods( $arr )
+{
+  include_once(PHPWG_ROOT_PATH.'include/ws_functions.inc.php');
+  global $conf, $user;
+  $service = &$arr[0];
+  $service->addMethod('pwg.getVersion', 'ws_getVersion', null,
+      'retrieves the PWG version');
+
+  $service->addMethod('pwg.caddie.add', 'ws_caddie_add',
+      array(
+        'image_id'=> array( 'flags'=>WS_PARAM_FORCE_ARRAY ),
+      ),
+      'adds the elements to the caddie');
+
+  $service->addMethod('pwg.categories.getImages', 'ws_categories_getImages',
+      array(
+        'cat_id'=>array('default'=>0, 'flags'=>WS_PARAM_FORCE_ARRAY),
+        'recursive'=>array('default'=>false),
+        'per_page' => array('default'=>100, 'maxValue'=>$conf['ws_max_images_per_page']),
+        'page' => array('default'=>0),
+        'order' => array('default'=>null),
+        'f_min_rate' => array( 'default'=> null ),
+        'f_max_rate' => array( 'default'=> null ),
+        'f_min_hit' => array( 'default'=> null ),
+        'f_max_hit' => array( 'default'=> null ),
+        'f_min_date_available' => array( 'default'=> null ),
+        'f_max_date_available' => array( 'default'=> null ),
+        'f_min_date_created' => array( 'default'=> null ),
+        'f_max_date_created' => array( 'default'=> null ),
+        'f_min_ratio' => array( 'default'=> null ),
+        'f_max_ratio' => array( 'default'=> null ),
+        'f_with_thumbnail' => array( 'default'=> false ),
+      ),
+      'Returns elements for the corresponding categories.
+<br/><b>cat_id</b> can be empty if <b>recursive</b> is true. Can be sent as an array.
+<br/><b>order</b> comma separated fields for sorting (file,id, average_rate,...)'
+    );
+
+  $service->addMethod('pwg.categories.getList', 'ws_categories_getList',
+      array(
+        'cat_id' => array('default'=>0),
+        'recursive' => array('default'=>false),
+        'public' => array('default'=>false),
+      ),
+      'retrieves a list of categories' );
+
+  $service->addMethod('pwg.images.addComment', 'ws_images_addComment',
+      array(
+        'image_id' => array(),
+        'author' => array( 'default' => is_a_guest()? 'guest':$user['username']),
+        'content' => array(),
+        'key' => array(),
+      ),
+      'add a comment to an image' );
+
+  $service->addMethod('pwg.images.getInfo', 'ws_images_getInfo',
+      array(
+        'image_id' => array(),
+        'comments_page' => array('default'=>0 ),
+        'comments_per_page' => array(
+              'default' => $conf['nb_comment_page'],
+              'maxValue' => 2*$conf['nb_comment_page'],
+            ),
+      ),
+      'retrieves information about the given photo' );
+
+  $service->addMethod('pwg.images.rate', 'ws_images_rate',
+      array(
+        'image_id' => array(),
+        'rate' =>     array(),
+      ),
+      'rate the image' );
+
+  $service->addMethod('pwg.images.search', 'ws_images_search',
+      array(
+        'query'=>array(),
+        'per_page' => array('default'=>100, 'maxValue'=>$conf['ws_max_images_per_page']),
+        'page' => array('default'=>0),
+        'order' => array('default'=>null),
+        'f_min_rate' => array( 'default'=> null ),
+        'f_max_rate' => array( 'default'=> null ),
+        'f_min_hit' => array( 'default'=> null ),
+        'f_max_hit' => array( 'default'=> null ),
+        'f_min_date_available' => array( 'default'=> null ),
+        'f_max_date_available' => array( 'default'=> null ),
+        'f_min_date_created' => array( 'default'=> null ),
+        'f_max_date_created' => array( 'default'=> null ),
+        'f_min_ratio' => array( 'default'=> null ),
+        'f_max_ratio' => array( 'default'=> null ),
+        'f_with_thumbnail' => array( 'default'=> false ),
+      ),
+      'Returns elements for the corresponding query search.'
+    );
+
+  $service->addMethod(
+    'pwg.images.setPrivacyLevel',
+    'ws_images_setPrivacyLevel',
+    array(
+      'image_id' => array('flags'=>WS_PARAM_FORCE_ARRAY),
+      'level' => array('maxValue'=>$conf['available_permission_levels']),
+      ),
+    'sets the privacy levels for the images'
+    );
+
+  $service->addMethod('pwg.session.getStatus', 'ws_session_getStatus', null, '' );
+  $service->addMethod('pwg.session.login', 'ws_session_login',
+    array('username', 'password'),
+    'POST method only' );
+  $service->addMethod('pwg.session.logout', 'ws_session_logout', null, '');
+
+  $service->addMethod('pwg.tags.getList', 'ws_tags_getList',
+    array('sort_by_counter' => array('default' =>false) ),
+    'retrieves a list of available tags');
+  $service->addMethod('pwg.tags.getImages', 'ws_tags_getImages',
+      array(
+        'tag_id'=>array('default'=>null, 'flags'=>WS_PARAM_FORCE_ARRAY ),
+        'tag_url_name'=>array('default'=>null, 'flags'=>WS_PARAM_FORCE_ARRAY ),
+        'tag_name'=>array('default'=>null, 'flags'=>WS_PARAM_FORCE_ARRAY ),
+        'tag_mode_and'=>array('default'=>false),
+        'per_page' => array('default'=>100, 'maxValue'=>$conf['ws_max_images_per_page']),
+        'page' => array('default'=>0),
+        'order' => array('default'=>null),
+        'f_min_rate' => array( 'default'=> null ),
+        'f_max_rate' => array( 'default'=> null ),
+        'f_min_hit' => array( 'default'=> null ),
+        'f_max_hit' => array( 'default'=> null ),
+        'f_min_date_available' => array( 'default'=> null ),
+        'f_max_date_available' => array( 'default'=> null ),
+        'f_min_date_created' => array( 'default'=> null ),
+        'f_max_date_created' => array( 'default'=> null ),
+        'f_min_ratio' => array( 'default'=> null ),
+        'f_max_ratio' => array( 'default'=> null ),
+        'f_with_thumbnail' => array( 'default'=> false ),
+      ),
+      'Returns elements for the corresponding tags. Note that tag_id, tag_url_name, tag_name an be arrays. Fill at least one of them. '
+    );
+
+  $service->addMethod(
+    'pwg.images.addChunk',
+    'ws_images_add_chunk',
+    array(
+      'data' => array(),
+      'original_sum' => array(),
+      'type' => array(),
+      'position' => array(),
+      ),
+    'POST method only. For admin only.'
+    );
+  
+
+  $service->addMethod(
+    'pwg.images.add',
+    'ws_images_add',
+    array(
+      'file_sum' => array(),
+      'thumbnail_sum' => array(),
+      'high_sum' => array('default' => null),
+      'original_sum' => array(),
+      'name' => array('default' => null),
+      'author' => array('default' => null),
+      'date_creation' => array('default' => null),
+      'comment' => array('default' => null),
+      'categories' => array('default' => null),
+      'tag_ids' => array('default' => null),
+      'level' => array(
+        'default' => 0,
+        'maxValue' => $conf['available_permission_levels']
+        ),
+      ),
+    'POST method only.
+<br/><b>categories</b> is a string list "category_id[,rank];category_id[,rank]" The rank is optional and is equivalent to "auto" if not given.'
+    );
+
+  $service->addMethod(
+    'pwg.categories.getAdminList',
+    'ws_categories_getAdminList',
+    array(),
+    'administration method only'
+    );
+
+  $service->addMethod(
+    'pwg.categories.add',
+    'ws_categories_add',
+    array(
+      'name' => array(),
+      'parent' => array('default' => null),
+      ),
+    'administration method only'
+    );
+
+  $service->addMethod(
+    'pwg.tags.getAdminList',
+    'ws_tags_getAdminList',
+    array(),
+    'administration method only'
+    );
+
+  $service->addMethod(
+    'pwg.tags.add',
+    'ws_tags_add',
+    array(
+      'name' => array(),
+      ),
+    'administration method only'
+    );
+
+  $service->addMethod(
+    'pwg.images.exist',
+    'ws_images_exist',
+    array(
+      'md5sum_list'=> array(),
+      ),
+    'check existence of a photo list'
+    );
+
+  $service->addMethod(
+    'pwg.images.setInfo',
+    'ws_images_setInfo',
+    array(
+      'image_id' => array(),
+      
+      'name' => array('default' => null),
+      'author' => array('default' => null),
+      'date_creation' => array('default' => null),
+      'comment' => array('default' => null),
+      'categories' => array('default' => null),
+      'tag_ids' => array('default' => null),
+      'level' => array(
+        'default' => 0,
+        'maxValue' => $conf['available_permission_levels']
+        ),
+      ),
+    'POST method only. Admin only
+<br/><b>categories</b> is a string list "category_id[,rank];category_id[,rank]" The rank is optional and is equivalent to "auto" if not given.'
+    );
+}
+
+add_event_handler('ws_add_methods', 'ws_addDefaultMethods');
+
+
+add_event_handler('ws_invoke_allowed', 'ws_isInvokeAllowed', EVENT_HANDLER_PRIORITY_NEUTRAL, 3);
+
+$requestFormat = null;
+$responseFormat = null;
+
+if ( isset($_GET['format']) )
+{
+  $responseFormat = $_GET['format'];
+}
+
+if ( isset($HTTP_RAW_POST_DATA) )
+{
+  $HTTP_RAW_POST_DATA = trim($HTTP_RAW_POST_DATA);
+  if ( strncmp($HTTP_RAW_POST_DATA, '<?xml', 5) == 0 )
+  {
+  }
+  else
+  {
+    $requestFormat = "json";
+  }
+}
+else
+{
+  $requestFormat = "rest";
+}
+
+if ( !isset($responseFormat) and isset($requestFormat) )
+{
+  $responseFormat = $requestFormat;
+}
+
+$service = new PwgServer();
+
+if (!is_null($requestFormat))
+{
+  $handler = null;
+  switch ($requestFormat)
+  {
+    case 'rest':
+      include_once(PHPWG_ROOT_PATH.'include/ws_protocols/rest_handler.php');
+      $handler = new PwgRestRequestHandler();
+      break;
+  }
+  $service->setHandler($requestFormat, $handler);
+}
+
+if (!is_null($responseFormat))
+{
+  $encoder = null;
+  switch ($responseFormat)
+  {
+    case 'rest':
+      include_once(PHPWG_ROOT_PATH.'include/ws_protocols/rest_encoder.php');
+      $encoder = new PwgRestEncoder();
+      break;
+    case 'php':
+      include_once(PHPWG_ROOT_PATH.'include/ws_protocols/php_encoder.php');
+      $encoder = new PwgSerialPhpEncoder();
+      break;
+    case 'json':
+      include_once(PHPWG_ROOT_PATH.'include/ws_protocols/json_encoder.php');
+      $encoder = new PwgJsonEncoder();
+      break;
+    case 'xmlrpc':
+      include_once(PHPWG_ROOT_PATH.'include/ws_protocols/xmlrpc_encoder.php');
+      $encoder = new PwgXmlRpcEncoder();
+      break;
+  }
+  $service->setEncoder($responseFormat, $encoder);
+}
+
+set_make_full_url();
+$service->run();
+
+?>
