summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS18
-rw-r--r--about.php27
-rw-r--r--ajaxDelete.php40
-rw-r--r--ajaxGetTitle.php66
-rw-r--r--ajaxIsAvailable.php37
-rw-r--r--alltags.php85
-rw-r--r--api/.htaccess10
-rw-r--r--api/httpauth.inc.php22
-rw-r--r--api/posts_add.php83
-rw-r--r--api/posts_all.php50
-rw-r--r--api/posts_dates.php42
-rw-r--r--api/posts_delete.php33
-rw-r--r--api/posts_get.php62
-rw-r--r--api/posts_recent.php63
-rw-r--r--api/posts_update.php26
-rw-r--r--api/tags_get.php25
-rw-r--r--api/tags_rename.php37
-rw-r--r--bg_bar.pngbin0 -> 873 bytes
-rw-r--r--bg_header.pngbin0 -> 684 bytes
-rw-r--r--bg_sidebar.pngbin0 -> 726 bytes
-rw-r--r--bookmarks.php228
-rw-r--r--cache/.cvsignore1
-rw-r--r--cache/.htaccess2
-rw-r--r--config.inc.php120
-rw-r--r--config.inc.php.example120
-rw-r--r--debug.inc.php16
-rw-r--r--edit.php93
-rw-r--r--functions.inc.php160
-rw-r--r--header.inc.php34
-rw-r--r--history.php90
-rw-r--r--icon.pngbin0 -> 771 bytes
-rw-r--r--import.php109
-rw-r--r--importNetscape.php85
-rw-r--r--includes/db/db2.php417
-rw-r--r--includes/db/firebird.php527
-rw-r--r--includes/db/index.htm10
-rw-r--r--includes/db/mssql-odbc.php576
-rw-r--r--includes/db/mssql.php551
-rw-r--r--includes/db/mysql.php552
-rw-r--r--includes/db/mysql4.php552
-rw-r--r--includes/db/mysqli.php566
-rw-r--r--includes/db/oracle.php468
-rw-r--r--includes/db/postgres.php597
-rw-r--r--includes/db/sqlite.php387
-rw-r--r--includes/php-gettext/AUTHORS3
-rw-r--r--includes/php-gettext/COPYING340
-rw-r--r--includes/php-gettext/ChangeLog144
-rw-r--r--includes/php-gettext/Makefile32
-rw-r--r--includes/php-gettext/README189
-rw-r--r--includes/php-gettext/bin/gettexts.bat20
-rw-r--r--includes/php-gettext/examples/index.php27
-rw-r--r--includes/php-gettext/examples/locale/de_CH/LC_MESSAGES/messages.mobin0 -> 585 bytes
-rw-r--r--includes/php-gettext/examples/locale/de_CH/LC_MESSAGES/messages.po30
-rw-r--r--includes/php-gettext/examples/locale/sr_CS/LC_MESSAGES/messages.mobin0 -> 834 bytes
-rw-r--r--includes/php-gettext/examples/locale/sr_CS/LC_MESSAGES/messages.po29
-rw-r--r--includes/php-gettext/examples/pigs_dropin.php87
-rw-r--r--includes/php-gettext/examples/pigs_fallback.php86
-rw-r--r--includes/php-gettext/examples/update14
-rw-r--r--includes/php-gettext/gettext.inc318
-rw-r--r--includes/php-gettext/gettext.php358
-rw-r--r--includes/php-gettext/streams.php166
-rw-r--r--includes/player/error.swfbin0 -> 90 bytes
-rw-r--r--includes/player/license.txt10
-rw-r--r--includes/player/load.swfbin0 -> 311 bytes
-rw-r--r--includes/player/musicplayer_f6.swfbin0 -> 6463 bytes
-rw-r--r--includes/player/play.swfbin0 -> 73 bytes
-rw-r--r--includes/player/stop.swfbin0 -> 77 bytes
-rw-r--r--includes/utf8.php478
-rw-r--r--index.php87
-rw-r--r--jsScuttle.php141
-rw-r--r--licence.txt340
-rw-r--r--loading.gifbin0 -> 1582 bytes
-rw-r--r--locales/de_DE/LC_MESSAGES/messages.mobin0 -> 16513 bytes
-rw-r--r--locales/de_DE/LC_MESSAGES/messages.po808
-rw-r--r--locales/dk_DK/LC_MESSAGES/messages.mobin0 -> 16304 bytes
-rw-r--r--locales/dk_DK/LC_MESSAGES/messages.po808
-rw-r--r--locales/en_GB/LC_MESSAGES/messages.mobin0 -> 493 bytes
-rw-r--r--locales/en_GB/LC_MESSAGES/messages.po808
-rw-r--r--locales/es_ES/LC_MESSAGES/messages.mobin0 -> 14307 bytes
-rw-r--r--locales/es_ES/LC_MESSAGES/messages.po826
-rw-r--r--locales/fr_FR/LC_MESSAGES/messages.mobin0 -> 13738 bytes
-rw-r--r--locales/fr_FR/LC_MESSAGES/messages.po835
-rw-r--r--locales/hi_IN/LC_MESSAGES/messages.mobin0 -> 24889 bytes
-rw-r--r--locales/hi_IN/LC_MESSAGES/messages.po812
-rw-r--r--locales/it_IT/LC_MESSAGES/messages.mobin0 -> 9206 bytes
-rw-r--r--locales/it_IT/LC_MESSAGES/messages.po853
-rw-r--r--locales/ja_JP/LC_MESSAGES/messages.mobin0 -> 18216 bytes
-rw-r--r--locales/ja_JP/LC_MESSAGES/messages.po808
-rw-r--r--locales/lt_LT/LC_MESSAGES/messages.mobin0 -> 16466 bytes
-rw-r--r--locales/lt_LT/LC_MESSAGES/messages.po808
-rw-r--r--locales/messages.po825
-rw-r--r--locales/nl_NL/LC_MESSAGES/messages.mobin0 -> 6030 bytes
-rw-r--r--locales/nl_NL/LC_MESSAGES/messages.po851
-rw-r--r--locales/pt_BR/LC_MESSAGES/messages.mobin0 -> 17153 bytes
-rw-r--r--locales/pt_BR/LC_MESSAGES/messages.po814
-rw-r--r--locales/zh_CN/LC_MESSAGES/messages.mobin0 -> 10939 bytes
-rw-r--r--locales/zh_CN/LC_MESSAGES/messages.po827
-rw-r--r--login.php53
-rw-r--r--logo.pngbin0 -> 2973 bytes
-rw-r--r--logo_24.pngbin0 -> 1729 bytes
-rw-r--r--password.php72
-rw-r--r--populartags.php86
-rw-r--r--profile.php107
-rw-r--r--readme.txt86
-rw-r--r--register.php64
-rw-r--r--rss.gifbin0 -> 401 bytes
-rw-r--r--rss.php115
-rw-r--r--scuttle.css436
-rw-r--r--search.inc.php44
-rw-r--r--search.php113
-rw-r--r--services/bookmarkservice.php416
-rw-r--r--services/cacheservice.php38
-rw-r--r--services/servicefactory.php33
-rw-r--r--services/tagservice.php363
-rw-r--r--services/templateservice.php46
-rw-r--r--services/userservice.php362
-rw-r--r--tables.sql68
-rw-r--r--tagdelete.php48
-rw-r--r--tagrename.php63
-rw-r--r--tags.php88
-rw-r--r--templates/about.tpl.php20
-rw-r--r--templates/bookmarks.tpl.php166
-rw-r--r--templates/bottom.inc.php2
-rw-r--r--templates/dynamictags.inc.php120
-rw-r--r--templates/editbookmark.tpl.php120
-rw-r--r--templates/editprofile.tpl.php56
-rw-r--r--templates/error.404.tpl.php9
-rw-r--r--templates/error.500.tpl.php9
-rw-r--r--templates/importDelicious.tpl.php42
-rw-r--r--templates/importNetscape.tpl.php50
-rw-r--r--templates/login.tpl.php35
-rw-r--r--templates/password.tpl.php26
-rw-r--r--templates/profile.tpl.php67
-rw-r--r--templates/register.tpl.php40
-rw-r--r--templates/rss.tpl.php28
-rw-r--r--templates/sidebar.block.common.php25
-rw-r--r--templates/sidebar.block.popular.php31
-rw-r--r--templates/sidebar.block.profile.php16
-rw-r--r--templates/sidebar.block.recent.php30
-rw-r--r--templates/sidebar.block.related.php29
-rw-r--r--templates/sidebar.block.tagactions.php27
-rw-r--r--templates/sidebar.block.watchlist.php19
-rw-r--r--templates/sidebar.block.watchstatus.php27
-rw-r--r--templates/sidebar.tpl.php13
-rw-r--r--templates/tagdelete.tpl.php20
-rw-r--r--templates/tagrename.tpl.php41
-rw-r--r--templates/tags.tpl.php27
-rw-r--r--templates/toolbar.inc.php27
-rw-r--r--templates/top.inc.php47
-rw-r--r--watch.php56
-rw-r--r--watchlist.php125
151 files changed, 24620 insertions, 0 deletions
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..a45e1e7
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,18 @@
+Scuttle contains code from the following applications:
+
+------------
+GPL Licenced
+------------
+
+phpBB2 (database abstraction layer)
+http://www.phpbb.com/
+
+php-gettext
+Danilo Segan <danilo@kvota.net>
+http://savannah.nongnu.org/projects/php-gettext/
+
+UTF8 Helper Functions
+Andreas Gohr <andi@splitbrain.org>
+
+XSPF Web Music Player (Flash)
+http://musicplayer.sourceforge.net/ \ No newline at end of file
diff --git a/about.php b/about.php
new file mode 100644
index 0000000..020a351
--- /dev/null
+++ b/about.php
@@ -0,0 +1,27 @@
+<?php
+/***************************************************************************
+Copyright (C) 2004, 2005 Scuttle project
+http://sourceforge.net/projects/scuttle/
+
+This program is free software; 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
+***************************************************************************/
+
+require_once('header.inc.php');
+$templateservice =& ServiceFactory::getServiceInstance('TemplateService');
+
+$tplVars = array();
+$tplVars['subtitle'] = T_('About');
+$templateservice->loadTemplate('about.tpl', $tplVars);
+?> \ No newline at end of file
diff --git a/ajaxDelete.php b/ajaxDelete.php
new file mode 100644
index 0000000..ad3efc8
--- /dev/null
+++ b/ajaxDelete.php
@@ -0,0 +1,40 @@
+<?php
+/***************************************************************************
+Copyright (C) 2005 - 2006 Scuttle project
+http://sourceforge.net/projects/scuttle/
+http://scuttle.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; 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
+***************************************************************************/
+
+header('Content-Type: text/xml; charset=UTF-8');
+header('Last-Modified: '. gmdate("D, d M Y H:i:s") .' GMT');
+header('Cache-Control: no-cache, must-revalidate');
+require_once('header.inc.php');
+
+$bookmarkservice = & ServiceFactory :: getServiceInstance('BookmarkService');
+$bookmark = intval($_GET['id']);
+if (!$bookmarkservice->editAllowed($bookmark)) {
+ $result = T_('You are not allowed to delete this bookmark');
+} elseif ($bookmarkservice->deleteBookmark($bookmark)) {
+ $result = 'true';
+} else {
+ $result = T_('Failed to delete bookmark');
+}
+?>
+<response>
+ <method>deleteConfirmed</method>
+ <result><?php echo $result; ?></result>
+</response> \ No newline at end of file
diff --git a/ajaxGetTitle.php b/ajaxGetTitle.php
new file mode 100644
index 0000000..0bc142d
--- /dev/null
+++ b/ajaxGetTitle.php
@@ -0,0 +1,66 @@
+<?php
+/***************************************************************************
+Copyright (C) 2005 - 2006 Scuttle project
+http://sourceforge.net/projects/scuttle/
+http://scuttle.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; 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
+***************************************************************************/
+
+header('Content-Type: text/xml; charset=UTF-8');
+header("Last-Modified: ". gmdate("D, d M Y H:i:s") ." GMT");
+header("Cache-Control: no-cache, must-revalidate");
+
+require_once('header.inc.php');
+
+function getTitle($url) {
+ $fd = @fopen($url, 'r');
+ if ($fd) {
+ $html = fread($fd, 1750);
+ fclose($fd);
+
+ // Get title from title tag
+ preg_match_all('/<title>(.*)<\/title>/si', $html, $matches);
+ $title = $matches[1][0];
+
+ // Get encoding from charset attribute
+ preg_match_all('/<meta.*charset=([^;"]*)">/i', $html, $matches);
+ $encoding = strtoupper($matches[1][0]);
+
+ // Convert to UTF-8 from the original encoding
+ if (function_exists('mb_convert_encoding') {
+ $title = @mb_convert_encoding($title, 'UTF-8', $encoding);
+ }
+
+ if (utf8_strlen($title) > 0) {
+ return $title;
+ } else {
+ // No title, so return filename
+ $uriparts = explode('/', $url);
+ $filename = end($uriparts);
+ unset($uriparts);
+
+ return $filename;
+ }
+ } else {
+ return false;
+ }
+}
+echo '<?xml version="1.0" encoding="utf-8"?>';
+?>
+<response>
+ <method>getTitle</method>
+ <result><?php echo getTitle($_GET['url']); ?></result>
+</response> \ No newline at end of file
diff --git a/ajaxIsAvailable.php b/ajaxIsAvailable.php
new file mode 100644
index 0000000..80883c6
--- /dev/null
+++ b/ajaxIsAvailable.php
@@ -0,0 +1,37 @@
+<?php
+/***************************************************************************
+Copyright (C) 2006 Scuttle project
+http://sourceforge.net/projects/scuttle/
+http://scuttle.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; 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
+***************************************************************************/
+
+header('Content-Type: text/xml; charset=UTF-8');
+header("Last-Modified: ". gmdate("D, d M Y H:i:s") ." GMT");
+header("Cache-Control: no-cache, must-revalidate");
+
+require_once('header.inc.php');
+$userservice = & ServiceFactory :: getServiceInstance('UserService');
+if ($userservice->isReserved($_GET['username'])) {
+ $result = 'false';
+} else {
+ $result = $userservice->getUserByUsername($_GET['username']) ? 'false' : 'true';
+}
+?>
+<response>
+ <method>isAvailable</method>
+ <result><?php echo $result; ?></result>
+</response> \ No newline at end of file
diff --git a/alltags.php b/alltags.php
new file mode 100644
index 0000000..b784414
--- /dev/null
+++ b/alltags.php
@@ -0,0 +1,85 @@
+<?php
+/***************************************************************************
+Copyright (C) 2004 - 2006 Scuttle project
+http://sourceforge.net/projects/scuttle/
+http://scuttle.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; 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
+***************************************************************************/
+
+require_once('header.inc.php');
+$templateservice =& ServiceFactory::getServiceInstance('TemplateService');
+$tagservice =& ServiceFactory::getServiceInstance('TagService');
+$userservice =& ServiceFactory::getServiceInstance('UserService');
+$cacheservice =& ServiceFactory::getServiceInstance('CacheService');
+
+list($url, $user) = explode('/', $_SERVER['PATH_INFO']);
+if (!$user) {
+ header('Location: '. createURL('populartags'));
+ exit;
+}
+
+if ($usecache) {
+ // Generate hash for caching on
+ $hashtext = $_SERVER['REQUEST_URI'];
+ if ($userservice->isLoggedOn()) {
+ $hashtext .= $userservice->getCurrentUserID();
+ }
+ $hash = md5($hashtext);
+
+ // Cache for an hour
+ $cacheservice->Start($hash, 3600);
+}
+
+// Header variables
+$tplvars = array();
+$pagetitle = T_('All Tags');
+
+if (isset($user) && $user != '') {
+ if (is_int($user)) {
+ $userid = intval($user);
+ } else {
+ if ($userinfo = $userservice->getUserByUsername($user)) {
+ $userid =& $userinfo[$userservice->getFieldName('primary')];
+ } else {
+ $tplVars['error'] = sprintf(T_('User with username %s was not found'), $user);
+ $templateservice->loadTemplate('error.404.tpl', $tplVars);
+ //throw a 404 error
+ exit();
+ }
+ }
+ $pagetitle .= ': '. ucfirst($user);
+} else {
+ $userid = NULL;
+}
+
+$tags =& $tagservice->getTags($userid);
+$tplVars['tags'] =& $tagservice->tagCloud($tags, 5, 90, 225, getSortOrder());
+$tplVars['user'] = $user;
+
+if (isset($userid)) {
+ $tplVars['cat_url'] = createURL('bookmarks', '%s/%s');
+} else {
+ $tplVars['cat_url'] = createURL('tags', '%2$s');
+}
+
+$tplVars['subtitle'] = $pagetitle;
+$templateservice->loadTemplate('tags.tpl', $tplVars);
+
+if ($usecache) {
+ // Cache output if existing copy has expired
+ $cacheservice->End($hash);
+}
+?>
diff --git a/api/.htaccess b/api/.htaccess
new file mode 100644
index 0000000..8c48221
--- /dev/null
+++ b/api/.htaccess
@@ -0,0 +1,10 @@
+RewriteEngine On
+RewriteRule ^tags/get tags_get.php
+RewriteRule ^posts/dates posts_dates.php
+RewriteRule ^posts/get posts_get.php
+RewriteRule ^posts/recent posts_recent.php
+RewriteRule ^posts/all posts_all.php
+RewriteRule ^posts/update posts_update.php
+RewriteRule ^posts/add posts_add.php
+RewriteRule ^posts/delete posts_delete.php
+RewriteRule ^tags/rename tags_rename.php \ No newline at end of file
diff --git a/api/httpauth.inc.php b/api/httpauth.inc.php
new file mode 100644
index 0000000..bc26582
--- /dev/null
+++ b/api/httpauth.inc.php
@@ -0,0 +1,22 @@
+<?php
+// Provides HTTP Basic authentication of a user, and sets two variables, sId and username,
+// with the user's info.
+
+function authenticate() {
+ header('WWW-Authenticate: Basic realm="del.icio.us API"');
+ header('HTTP/1.0 401 Unauthorized');
+ die("Use of the API calls requires authentication.");
+}
+
+if (!isset($_SERVER['PHP_AUTH_USER'])) {
+ authenticate();
+} else {
+ require_once('../header.inc.php');
+ $userservice =& ServiceFactory::getServiceInstance('UserService');
+
+ $login = $userservice->login($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']);
+ if (!$login) {
+ authenticate();
+ }
+}
+?> \ No newline at end of file
diff --git a/api/posts_add.php b/api/posts_add.php
new file mode 100644
index 0000000..77c3288
--- /dev/null
+++ b/api/posts_add.php
@@ -0,0 +1,83 @@
+<?php
+// Implements the del.icio.us API request to add a new post.
+
+// del.icio.us behavior:
+// - tags can't have spaces
+// - address and description are mandatory
+
+// Scuttle behavior:
+// - Additional 'status' variable for privacy
+// - No support for 'replace' variable
+
+// Force HTTP authentication
+require_once('httpauth.inc.php');
+require_once('../header.inc.php');
+
+$bookmarkservice =& ServiceFactory::getServiceInstance('BookmarkService');
+$userservice =& ServiceFactory::getServiceInstance('UserService');
+
+// Get all the bookmark's passed-in information
+if (isset($_REQUEST['url']) && (trim($_REQUEST['url']) != ''))
+ $url = trim(urldecode($_REQUEST['url']));
+else
+ $url = NULL;
+
+if (isset($_REQUEST['description']) && (trim($_REQUEST['description']) != ''))
+ $description = trim($_REQUEST['description']);
+else
+ $description = NULL;
+
+if (isset($_REQUEST['extended']) && (trim($_REQUEST['extended']) != ""))
+ $extended = trim($_REQUEST['extended']);
+else
+ $extended = NULL;
+
+if (isset($_REQUEST['tags']) && (trim($_REQUEST['tags']) != '') && (trim($_REQUEST['tags']) != ','))
+ $tags = trim($_REQUEST['tags']);
+else
+ $tags = NULL;
+
+if (isset($_REQUEST['dt']) && (trim($_REQUEST['dt']) != ''))
+ $dt = trim($_REQUEST['dt']);
+else
+ $dt = NULL;
+
+$status = 0;
+if (isset($_REQUEST['status'])) {
+ $status_str = trim($_REQUEST['status']);
+ if (is_numeric($status_str)) {
+ $status = intval($status_str);
+ if($status < 0 || $status > 2) {
+ $status = 0;
+ }
+ } else {
+ switch ($status_str) {
+ case 'private':
+ $status = 2;
+ break;
+ case 'shared':
+ $status = 1;
+ break;
+ default:
+ $status = 0;
+ break;
+ }
+ }
+}
+
+// Error out if there's no address or description
+if (is_null($url) || is_null($description)) {
+ $added = false;
+} else {
+// We're good with info; now insert it!
+ if ($bookmarkservice->bookmarkExists($url, $userservice->getCurrentUserId()))
+ $added = false;
+ else
+ $added = $bookmarkservice->addBookmark($url, $description, $extended, $status, $tags, $dt, true);
+}
+
+// Set up the XML file and output the result.
+header('Content-Type: text/xml');
+echo '<?xml version="1.0" standalone="yes" ?'.">\r\n";
+echo '<result code="'. ($added ? 'done' : 'something went wrong') .'" />';
+?> \ No newline at end of file
diff --git a/api/posts_all.php b/api/posts_all.php
new file mode 100644
index 0000000..03026c4
--- /dev/null
+++ b/api/posts_all.php
@@ -0,0 +1,50 @@
+<?php
+// Implements the del.icio.us API request for all a user's posts, optionally filtered by tag.
+
+// del.icio.us behavior:
+// - doesn't include the filtered tag as an attribute on the root element (we do)
+
+// Force HTTP authentication first!
+require_once('httpauth.inc.php');
+require_once('../header.inc.php');
+
+$bookmarkservice =& ServiceFactory::getServiceInstance('BookmarkService');
+$userservice =& ServiceFactory::getServiceInstance('UserService');
+
+// Check to see if a tag was specified.
+if (isset($_REQUEST['tag']) && (trim($_REQUEST['tag']) != ''))
+ $tag = trim($_REQUEST['tag']);
+else
+ $tag = NULL;
+
+// Get the posts relevant to the passed-in variables.
+$bookmarks =& $bookmarkservice->getBookmarks(0, NULL, $userservice->getCurrentUserId(), $tag);
+
+$currentuser = $userservice->getCurrentUser();
+$currentusername = $currentuser[$userservice->getFieldName('username')];
+
+// Set up the XML file and output all the posts.
+header('Content-Type: text/xml');
+echo '<?xml version="1.0" standalone="yes" ?'.">\r\n";
+echo '<posts update="'. gmdate('Y-m-d\TH:i:s\Z') .'" user="'. htmlspecialchars($currentusername) .'"'. (is_null($tag) ? '' : ' tag="'. htmlspecialchars($tag) .'"') .">\r\n";
+
+foreach($bookmarks['bookmarks'] as $row) {
+ if (is_null($row['bDescription']) || (trim($row['bDescription']) == ''))
+ $description = '';
+ else
+ $description = 'extended="'. filter($row['bDescription'], 'xml') .'" ';
+
+ $taglist = '';
+ if (count($row['tags']) > 0) {
+ foreach($row['tags'] as $tag)
+ $taglist .= convertTag($tag) .' ';
+ $taglist = substr($taglist, 0, -1);
+ } else {
+ $taglist = 'system:unfiled';
+ }
+
+ echo "\t<post href=\"". filter($row['bAddress'], 'xml') .'" description="'. filter($row['bTitle'], 'xml') .'" '. $description .'hash="'. md5($row['bAddress']) .'" tag="'. filter($taglist, 'xml') .'" time="'. gmdate('Y-m-d\TH:i:s\Z', strtotime($row['bDatetime'])) ."\" />\r\n";
+}
+
+echo '</posts>';
+?> \ No newline at end of file
diff --git a/api/posts_dates.php b/api/posts_dates.php
new file mode 100644
index 0000000..7098756
--- /dev/null
+++ b/api/posts_dates.php
@@ -0,0 +1,42 @@
+<?php
+// Implements the del.icio.us API request for a user's post counts by date (and optionally
+// by tag).
+
+// Force HTTP authentication first!
+require_once('httpauth.inc.php');
+require_once('../header.inc.php');
+
+$bookmarkservice =& ServiceFactory::getServiceInstance('BookmarkService');
+$userservice =& ServiceFactory::getServiceInstance('UserService');
+
+// Check to see if a tag was specified.
+if (isset($_REQUEST['tag']) && (trim($_REQUEST['tag']) != ''))
+ $tag = trim($_REQUEST['tag']);
+else
+ $tag = NULL;
+
+// Get the posts relevant to the passed-in variables.
+$bookmarks =& $bookmarkservice->getBookmarks(0, NULL, $userservice->getCurrentUserId(), $tag);
+
+$currentuser = $userservice->getCurrentUser();
+$currentusername = $currentuser[$userservice->getFieldName('username')];
+
+// Set up the XML file and output all the tags.
+header('Content-Type: text/xml');
+echo '<?xml version="1.0" standalone="yes" ?'.">\r\n";
+echo '<dates tag="'. (is_null($tag) ? '' : filter($tag, 'xml')) .'" user="'. filter($currentusername, 'xml') ."\">\r\n";
+
+$lastdate = NULL;
+foreach($bookmarks['bookmarks'] as $row) {
+ $thisdate = gmdate('Y-m-d', strtotime($row['bDatetime']));
+ if ($thisdate != $lastdate && $lastdate != NULL) {
+ echo "\t<date count=\"". $count .'" date="'. $lastdate ."\" />\r\n";
+ $count = 1;
+ } else {
+ $count = $count + 1;
+ }
+ $lastdate = $thisdate;
+}
+
+echo "</dates>";
+?> \ No newline at end of file
diff --git a/api/posts_delete.php b/api/posts_delete.php
new file mode 100644
index 0000000..737a4fb
--- /dev/null
+++ b/api/posts_delete.php
@@ -0,0 +1,33 @@
+<?php
+// Implements the del.icio.us API request to delete a post.
+
+// del.icio.us behavior:
+// - returns "done" even if the bookmark doesn't exist;
+// - does NOT allow the hash for the url parameter;
+// - doesn't set the Content-Type to text/xml (we do).
+
+// Force HTTP authentication first!
+require_once('httpauth.inc.php');
+require_once('../header.inc.php');
+
+$bookmarkservice =& ServiceFactory::getServiceInstance('BookmarkService');
+$userservice =& ServiceFactory::getServiceInstance('UserService');
+
+// Note that del.icio.us only errors out if no URL was passed in; there's no error on attempting
+// to delete a bookmark you don't have.
+
+// Error out if there's no address
+if (is_null($_REQUEST['url'])) {
+ $deleted = false;
+} else {
+ $bookmark = $bookmarkservice->getBookmarkByAddress($_REQUEST['url']);
+ $bid = $bookmark['bId'];
+ $delete = $bookmarkservice->deleteBookmark($bid);
+ $deleted = true;
+}
+
+// Set up the XML file and output the result.
+header('Content-Type: text/xml');
+echo '<?xml version="1.0" standalone="yes" ?'.">\r\n";
+echo '<result code="'. ($deleted ? 'done' : 'something went wrong') .'" />';
+?> \ No newline at end of file
diff --git a/api/posts_get.php b/api/posts_get.php
new file mode 100644
index 0000000..8be067b
--- /dev/null
+++ b/api/posts_get.php
@@ -0,0 +1,62 @@
+<?php
+// Implements the del.icio.us API request for a user's posts, optionally filtered by tag and/or
+// date. Note that when using a date to select the posts returned, del.icio.us uses GMT dates --
+// so we do too.
+
+// del.icio.us behavior:
+// - includes an empty tag attribute on the root element when it hasn't been specified
+
+// Scuttle behavior:
+// - Uses today, instead of the last bookmarked date, if no date is specified
+
+// Force HTTP authentication first!
+require_once('httpauth.inc.php');
+require_once('../header.inc.php');
+
+$bookmarkservice =& ServiceFactory::getServiceInstance('BookmarkService');
+$userservice =& ServiceFactory::getServiceInstance('UserService');
+
+// Check to see if a tag was specified.
+if (isset($_REQUEST['tag']) && (trim($_REQUEST['tag']) != ''))
+ $tag = trim($_REQUEST['tag']);
+else
+ $tag = NULL;
+
+// Check to see if a date was specified; the format should be YYYY-MM-DD
+if (isset($_REQUEST['dt']) && (trim($_REQUEST['dt']) != ""))
+ $dtstart = trim($_REQUEST['dt']);
+else
+ $dtstart = date('Y-m-d H:i:s');
+$dtend = date('Y-m-d H:i:s', strtotime($dtstart .'+1 day'));
+
+// Get the posts relevant to the passed-in variables.
+$bookmarks =& $bookmarkservice->getBookmarks(0, NULL, $userservice->getCurrentUserId(), $tag, NULL, NULL, NULL, $dtstart, $dtend);
+
+$currentuser = $userservice->getCurrentUser();
+$currentusername = $currentuser[$userservice->getFieldName('username')];
+
+// Set up the XML file and output all the tags.
+header('Content-Type: text/xml');
+echo '<?xml version="1.0" standalone="yes" ?'.">\r\n";
+echo '<posts'. (is_null($dtstart) ? '' : ' dt="'. $dtstart .'"') .' tag="'. (is_null($tag) ? '' : filter($tag, 'xml')) .'" user="'. filter($currentusername, 'xml') ."\">\r\n";
+
+foreach($bookmarks['bookmarks'] as $row) {
+ if (is_null($row['bDescription']) || (trim($row['bDescription']) == ''))
+ $description = '';
+ else
+ $description = 'extended="'. filter($row['bDescription'], 'xml') .'" ';
+
+ $taglist = '';
+ if (count($row['tags']) > 0) {
+ foreach($row['tags'] as $tag)
+ $taglist .= convertTag($tag) .' ';
+ $taglist = substr($taglist, 0, -1);
+ } else {
+ $taglist = 'system:unfiled';
+ }
+
+ echo "\t<post href=\"". filter($row['bAddress'], 'xml') .'" description="'. filter($row['bTitle'], 'xml') .'" '. $description .'hash="'. $row['bHash'] .'" others="'. $bookmarkservice->countOthers($row['bAddress']) .'" tag="'. filter($taglist, 'xml') .'" time="'. gmdate('Y-m-d\TH:i:s\Z', strtotime($row['bDatetime'])) ."\" />\r\n";
+}
+
+echo '</posts>';
+?> \ No newline at end of file
diff --git a/api/posts_recent.php b/api/posts_recent.php
new file mode 100644
index 0000000..22fc2bd
--- /dev/null
+++ b/api/posts_recent.php
@@ -0,0 +1,63 @@
+<?php
+// Implements the del.icio.us API request for a user's recent posts, optionally filtered by
+// tag and/or number of posts (default 15, max 100, just like del.icio.us).
+
+// Set default and max number of posts
+$countDefault = 15;
+$countMax = 100;
+
+// Force HTTP authentication first!
+require_once('httpauth.inc.php');
+require_once('../header.inc.php');
+
+$bookmarkservice =& ServiceFactory::getServiceInstance('BookmarkService');
+$userservice =& ServiceFactory::getServiceInstance('UserService');
+
+// Check to see if a tag was specified.
+if (isset($_REQUEST['tag']) && (trim($_REQUEST['tag']) != ''))
+ $tag = trim($_REQUEST['tag']);
+else
+ $tag = NULL;
+
+// Check to see if the number of items was specified.
+if (isset($_REQUEST['count']) && (intval($_REQUEST['count']) != 0)) {
+ $count = intval($_REQUEST['count']);
+ if ($count > $countMax)
+ $count = $countMax;
+ elseif ($count < 0)
+ $count = 0;
+} else {
+ $count = $countDefault;
+}
+
+// Get the posts relevant to the passed-in variables.
+$bookmarks =& $bookmarkservice->getBookmarks(0, $count, $userservice->getCurrentUserId(), $tag);
+
+$currentuser = $userservice->getCurrentUser();
+$currentusername = $currentuser[$userservice->getFieldName('username')];
+
+// Set up the XML file and output all the tags.
+header('Content-Type: text/xml');
+echo '<?xml version="1.0" standalone="yes" ?'.">\r\n";
+echo '<posts tag="'. (is_null($tag) ? '' : filter($tag, 'xml')) .'" user="'. filter($currentusername, 'xml') ."\">\r\n";
+
+foreach($bookmarks['bookmarks'] as $row) {
+ if (is_null($row['bDescription']) || (trim($row['bDescription']) == ''))
+ $description = '';
+ else
+ $description = 'extended="'. filter($row['bDescription'], 'xml') .'" ';
+
+ $taglist = '';
+ if (count($row['tags']) > 0) {
+ foreach($row['tags'] as $tag)
+ $taglist .= convertTag($tag) .' ';
+ $taglist = substr($taglist, 0, -1);
+ } else {
+ $taglist = 'system:unfiled';
+ }
+
+ echo "\t<post href=\"". filter($row['bAddress'], 'xml') .'" description="'. filter($row['bTitle'], 'xml') .'" '. $description .'hash="'. $row['bHash'] .'" tag="'. filter($taglist, 'xml') .'" time="'. gmdate('Y-m-d\TH:i:s\Z', strtotime($row['bDatetime'])) ."\" />\r\n";
+}
+
+echo '</posts>';
+?> \ No newline at end of file
diff --git a/api/posts_update.php b/api/posts_update.php
new file mode 100644
index 0000000..de379d2
--- /dev/null
+++ b/api/posts_update.php
@@ -0,0 +1,26 @@
+<?php
+// Implements the del.icio.us API request for a user's last update time and date.
+
+// del.icio.us behavior:
+// - doesn't set the Content-Type to text/xml (we do).
+
+// Force HTTP authentication first!
+require_once('httpauth.inc.php');
+require_once('../header.inc.php');
+
+$bookmarkservice =& ServiceFactory::getServiceInstance('BookmarkService');
+$userservice =& ServiceFactory::getServiceInstance('UserService');
+
+// Get the posts relevant to the passed-in variables.
+$bookmarks =& $bookmarkservice->getBookmarks(0, 1, $userservice->getCurrentUserId());
+
+$currentuser = $userservice->getCurrentUser();
+$currentusername = $currentuser[$userservice->getFieldName('username')];
+
+// Set up the XML file and output all the tags.
+header('Content-Type: text/xml');
+echo '<?xml version="1.0" standalone="yes" ?'.">\r\n";
+foreach($bookmarks['bookmarks'] as $row) {
+ echo '<update time="'. gmdate('Y-m-d\TH:i:s\Z', strtotime($row['bDatetime'])) .'" />';
+}
+?> \ No newline at end of file
diff --git a/api/tags_get.php b/api/tags_get.php
new file mode 100644
index 0000000..2584566
--- /dev/null
+++ b/api/tags_get.php
@@ -0,0 +1,25 @@
+<?php
+// Implements the del.icio.us API request for all a user's tags.
+
+// del.icio.us behavior:
+// - tags can't have spaces
+
+// Force HTTP authentication first!
+require_once('httpauth.inc.php');
+require_once('../header.inc.php');
+
+$tagservice =& ServiceFactory::getServiceInstance('TagService');
+$userservice =& ServiceFactory::getServiceInstance('UserService');
+
+// Get the tags relevant to the passed-in variables.
+$tags =& $tagservice->getTags($userservice->getCurrentUserId());
+
+// Set up the XML file and output all the tags.
+header('Content-Type: text/xml');
+echo '<?xml version="1.0" standalone="yes" ?'.">\r\n";
+echo "<tags>\r\n";
+foreach($tags as $row) {
+ echo "\t<tag count=\"". $row['bCount'] .'" tag="'. filter(convertTag($row['tag'], 'out'), 'xml') ."\" />\r\n";
+}
+echo "</tags>";
+?> \ No newline at end of file
diff --git a/api/tags_rename.php b/api/tags_rename.php
new file mode 100644
index 0000000..20831e7
--- /dev/null
+++ b/api/tags_rename.php
@@ -0,0 +1,37 @@
+<?php
+// Implements the del.icio.us API request to rename a user's tag.
+
+// del.icio.us behavior:
+// - oddly, returns an entirely different result (<result></result>) than the other API calls.
+
+// Force HTTP authentication first!
+require_once('httpauth.inc.php');
+require_once('../header.inc.php');
+
+$tagservice =& ServiceFactory::getServiceInstance('TagService');
+$userservice =& ServiceFactory::getServiceInstance('UserService');
+
+// Get the tag info.
+if (isset($_REQUEST['old']) && (trim($_REQUEST['old']) != ''))
+ $old = trim($_REQUEST['old']);
+else
+ $old = NULL;
+
+if (isset($_REQUEST['new']) && (trim($_REQUEST['new']) != ''))
+ $new = trim($_REQUEST['new']);
+else
+ $new = NULL;
+
+if (is_null($old) || is_null($new)) {
+ $renamed = false;
+} else {
+ // Rename the tag.
+ $result = $tagservice->renameTag($userservice->getCurrentUserId(), $old, $new, true);
+ $renamed = $result;
+}
+
+// Set up the XML file and output the result.
+header('Content-Type: text/xml');
+echo '<?xml version="1.0" standalone="yes" ?'.">\r\n";
+echo '<result>'. ($renamed ? 'done' : 'something went wrong') .'</result>';
+?>
diff --git a/bg_bar.png b/bg_bar.png
new file mode 100644
index 0000000..7152ba1
--- /dev/null
+++ b/bg_bar.png
Binary files differ
diff --git a/bg_header.png b/bg_header.png
new file mode 100644
index 0000000..6fa4161
--- /dev/null
+++ b/bg_header.png
Binary files differ
diff --git a/bg_sidebar.png b/bg_sidebar.png
new file mode 100644
index 0000000..0edb153
--- /dev/null
+++ b/bg_sidebar.png
Binary files differ
diff --git a/bookmarks.php b/bookmarks.php
new file mode 100644
index 0000000..cc5eba4
--- /dev/null
+++ b/bookmarks.php
@@ -0,0 +1,228 @@
+<?php
+/***************************************************************************
+Copyright (C) 2004 - 2006 Scuttle project
+http://sourceforge.net/projects/scuttle/
+http://scuttle.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; 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
+***************************************************************************/
+
+require_once('header.inc.php');
+
+$bookmarkservice =& ServiceFactory::getServiceInstance('BookmarkService');
+$templateservice =& ServiceFactory::getServiceInstance('TemplateService');
+$userservice =& ServiceFactory::getServiceInstance('UserService');
+$cacheservice =& ServiceFactory::getServiceInstance('CacheService');
+
+$tplVars = array();
+
+if (isset($_GET['action']) && ($_GET['action'] == "add") && !$userservice->isLoggedOn()) {
+ $loginqry = str_replace("'", '%27', stripslashes($_SERVER['QUERY_STRING']));
+ header('Location: '. createURL('login', '?'. $loginqry));
+ exit();
+}
+
+@list($url, $user, $cat) = isset($_SERVER['PATH_INFO']) ? explode('/', $_SERVER['PATH_INFO']) : NULL;
+
+$loggedon = false;
+if ($userservice->isLoggedOn()) {
+ $loggedon = true;
+ $currentUser = $userservice->getCurrentUser();
+ $currentUserID = $userservice->getCurrentUserId();
+ $currentUsername = $currentUser[$userservice->getFieldName('username')];
+}
+
+$endcache = false;
+if ($usecache) {
+ // Generate hash for caching on
+ $hash = md5($_SERVER['REQUEST_URI'] . $user);
+
+ // Don't cache if its users' own bookmarks
+ if ($loggedon) {
+ if ($currentUsername != $user) {
+ // Cache for 5 minutes
+ $cacheservice->Start($hash);
+ $endcache = true;
+ }
+ } else {
+ // Cache for 30 minutes
+ $cacheservice->Start($hash, 1800);
+ $endcache = true;
+ }
+}
+
+$pagetitle = $rssCat = $catTitle = '';
+if ($user) {
+ if (is_int($user)) {
+ $userid = intval($user);
+ } else {
+ if (!($userinfo = $userservice->getUserByUsername($user))) {
+ $tplVars['error'] = sprintf(T_('User with username %s was not found'), $user);
+ $templateservice->loadTemplate('error.404.tpl', $tplVars);
+ exit();
+ } else {
+ $userid =& $userinfo['uId'];
+ }
+ }
+ $pagetitle .= ': '. $user;
+}
+if ($cat) {
+ $catTitle = ': '. str_replace('+', ' + ', $cat);
+ $pagetitle .= $catTitle;
+}
+$pagetitle = substr($pagetitle, 2);
+
+// Header variables
+$tplVars['loadjs'] = true;
+
+// ADD A BOOKMARK
+$saved = false;
+$templatename = 'bookmarks.tpl';
+if ($loggedon && isset($_POST['submitted'])) {
+ if (!$_POST['title'] || !$_POST['address']) {
+ $tplVars['error'] = T_('Your bookmark must have a title and an address');
+ $templatename = 'editbookmark.tpl';
+ } else {
+ $address = trim($_POST['address']);
+ // If the bookmark exists already, edit the original
+ if ($bookmarkservice->bookmarkExists($address, $currentUserID)) {
+ $bookmark =& $bookmarkservice->getBookmarkByAddress($address);
+ header('Location: '. createURL('edit', $bookmark['bId']));
+ exit();
+ // If it's new, save it
+ } else {
+ $title = trim($_POST['title']);
+ $description = trim($_POST['description']);
+ $status = intval($_POST['status']);
+ $categories = trim($_POST['tags']);
+ $saved = true;
+ if ($bookmarkservice->addBookmark($address, $title, $description, $status, $categories)) {
+ if (isset($_POST['popup'])) {
+ $tplVars['msg'] = '<script type="text/javascript">window.close();</script>';
+ } else {
+ $tplVars['msg'] = T_('Bookmark saved');
+ // Redirection option
+ if ($GLOBALS['useredir']) {
+ $address = $GLOBALS['url_redir'] . $address;
+ }
+ header('Location: '. $address);
+ }
+ } else {
+ $tplVars['error'] = T_('There was an error saving your bookmark. Please try again or contact the administrator.');
+ $templatename = 'editbookmark.tpl';
+ $saved = false;
+ }
+ }
+ }
+}
+
+if (isset($_GET['action']) && ($_GET['action'] == "add")) {
+ // If the bookmark exists already, edit the original
+ if ($bookmarkservice->bookmarkExists(stripslashes($_GET['address']), $currentUserID)) {
+ $bookmark =& $bookmarkservice->getBookmarkByAddress(stripslashes($_GET['address']));
+ $popup = (isset($_GET['popup'])) ? '?popup=1' : '';
+ header('Location: '. createURL('edit', $bookmark['bId'] . $popup));
+ exit();
+ }
+ $templatename = 'editbookmark.tpl';
+}
+
+if ($templatename == 'editbookmark.tpl') {
+ if ($loggedon) {
+ $tplVars['formaction'] = createURL('bookmarks', $currentUsername);
+ if (isset($_POST['submitted'])) {
+ $tplVars['row'] = array(
+ 'bTitle' => stripslashes($_POST['title']),
+ 'bAddress' => stripslashes($_POST['address']),
+ 'bDescription' => stripslashes($_POST['description']),
+ 'tags' => ($_POST['tags'] ? explode(',', stripslashes($_POST['tags'])) : array())
+ );
+ $tplVars['tags'] = $_POST['tags'];
+ } else {
+ $tplVars['row'] = array(
+ 'bTitle' => stripslashes($_GET['title']),
+ 'bAddress' => stripslashes($_GET['address']),
+ 'bDescription' => stripslashes($_GET['description']),
+ 'tags' => ($_GET['tags'] ? explode(',', stripslashes($_GET['tags'])) : array())
+ );
+ }
+ $title = T_('Add a Bookmark');
+ $tplVars['pagetitle'] = $title;
+ $tplVars['subtitle'] = $title;
+ $tplVars['btnsubmit'] = T_('Add Bookmark');
+ $tplVars['popup'] = (isset($_GET['popup'])) ? $_GET['popup'] : null;
+ } else {
+ $tplVars['error'] = T_('You must be logged in before you can add bookmarks.');
+ }
+} else if ($user && !isset($_GET['popup'])) {
+
+ $tplVars['sidebar_blocks'] = array('profile', 'watchstatus');
+
+ if (!$cat) {
+ $cat = NULL;
+ $tplVars['currenttag'] = NULL;
+ } else {
+ $rssCat = '/'. filter($cat, 'url');
+ $tplVars['currenttag'] = $cat;
+ $tplVars['sidebar_blocks'][] = 'related';
+ $tplVars['sidebar_blocks'][] = 'tagactions';
+ }
+ $tplVars['popCount'] = 30;
+ $tplVars['sidebar_blocks'][] = 'popular';
+
+ $tplVars['userid'] = $userid;
+ $tplVars['userinfo'] =& $userinfo;
+ $tplVars['user'] = $user;
+ $tplVars['range'] = 'user';
+
+ // Pagination
+ $perpage = getPerPageCount();
+ if (isset($_GET['page']) && intval($_GET['page']) > 1) {
+ $page = $_GET['page'];
+ $start = ($page - 1) * $perpage;
+ } else {
+ $page = 0;
+ $start = 0;
+ }
+
+ // Set template vars
+ $tplVars['rsschannels'] = array(
+ array(filter($sitename .': '. $pagetitle), createURL('rss', filter($user, 'url') . $rssCat))
+ );
+
+ $tplVars['page'] = $page;
+ $tplVars['start'] = $start;
+ $tplVars['bookmarkCount'] = $start + 1;
+
+ $bookmarks =& $bookmarkservice->getBookmarks($start, $perpage, $userid, $cat, $terms, getSortOrder());
+ $tplVars['total'] = $bookmarks['total'];
+ $tplVars['bookmarks'] =& $bookmarks['bookmarks'];
+ $tplVars['cat_url'] = createURL('bookmarks', '%s/%s');
+ $tplVars['nav_url'] = createURL('bookmarks', '%s/%s%s');
+ if ($user == $currentUsername) {
+ $title = T_('My Bookmarks') . filter($catTitle);
+ } else {
+ $title = filter($pagetitle);
+ }
+ $tplVars['pagetitle'] = $title;
+ $tplVars['subtitle'] = $title;
+}
+$templateservice->loadTemplate($templatename, $tplVars);
+
+if ($usecache && $endcache) {
+ // Cache output if existing copy has expired
+ $cacheservice->End($hash);
+}
+?>
diff --git a/cache/.cvsignore b/cache/.cvsignore
new file mode 100644
index 0000000..f05fcdc
--- /dev/null
+++ b/cache/.cvsignore
@@ -0,0 +1 @@
+*.cache \ No newline at end of file
diff --git a/cache/.htaccess b/cache/.htaccess
new file mode 100644
index 0000000..baa56e5
--- /dev/null
+++ b/cache/.htaccess
@@ -0,0 +1,2 @@
+order allow,deny
+deny from all \ No newline at end of file
diff --git a/config.inc.php b/config.inc.php
new file mode 100644
index 0000000..6c0117a
--- /dev/null
+++ b/config.inc.php
@@ -0,0 +1,120 @@
+<?php
+######################################################################
+# SCUTTLE: Online social bookmarks manager
+######################################################################
+# Copyright (C) 2005 - 2006 Scuttle project
+# http://sourceforge.net/projects/scuttle/
+# http://scuttle.org/
+#
+# This module is to configure the main options for your site
+#
+# This program is free software. 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.
+######################################################################
+
+######################################################################
+# Database Configuration
+#
+# dbtype: Database driver - mysql, mysqli, mysql4, oracle, postgres,
+# sqlite, db2, firebird, mssql, mssq-odbc
+# dbhost: Database hostname
+# dbport: Database port
+# dbuser: Database username
+# dbpass: Database password
+# dbname: Database name
+######################################################################
+
+$dbtype = 'mysql4';
+$dbhost = '127.0.0.1';
+$dbport = '3306';
+$dbuser = 'root';
+$dbpass = '';
+$dbname = 'scuttle';
+
+######################################################################
+# You have finished configuring the database!
+# ONLY EDIT THE INFORMATION BELOW IF YOU KNOW WHAT YOU ARE DOING.
+######################################################################
+# System Configuration
+#
+# sitename: The name of this site.
+# locale: The locale used.
+# top_include: The header file.
+# bottom_include: The footer file.
+# shortdate: The format of short dates.
+# longdate: The format of long dates.
+# nofollow: true - Include rel="nofollow" attribute on
+# bookmark links.
+# false - Don't include rel="nofollow".
+# defaultPerPage: The default number of bookmarks per page.
+# -1 means no limit!
+# defaultRecentDays: The number of days that bookmarks or tags should
+# be considered recent.
+# defaultOrderBy: The default order in which bookmarks will appear.
+# Possible values are:
+# date_desc - By date of entry descending.
+# Latest entry first. (Default)
+# date_asc - By date of entry ascending.
+# Earliest entry first.
+# title_desc - By title, descending alphabetically.
+# title_asc - By title, ascending alphabetically.
+# url_desc - By URL, descending alphabetically.
+# url_asc - By URL, ascending alphabetically.
+# TEMPLATES_DIR: The directory where the template files should be
+# loaded from (the *.tpl.php files)
+# root : Set to NULL to autodetect the root url of the website
+# cookieprefix : The prefix to use for the cookies on the site
+# tableprefix : The table prefix used for this installation
+# adminemail : Contact address for the site administrator. Used
+# as the FROM address in password retrieval e-mails.
+# cleanurls : true - Use mod_rewrite to hide PHP extensions
+# : false - Don't hide extensions [Default]
+#
+# usecache : true - Cache pages when possible
+# false - Don't cache at all [Default]
+# dir_cache : The directory where cache files will be stored
+#
+# useredir : true - Improve privacy by redirecting all bookmarks
+# through the address specified in url_redir
+# false - Don't redirect bookmarks
+# url_redir : URL prefix for bookmarks to redirect through
+#
+# filetypes : An array of bookmark extensions that Scuttle should
+# add system tags for.
+# reservedusers : An array of usernames that cannot be registered
+######################################################################
+
+$sitename = 'Scuttle';
+$locale = 'en_GB';
+$top_include = 'top.inc.php';
+$bottom_include = 'bottom.inc.php';
+$shortdate = 'd-m-Y';
+$longdate = 'j F Y';
+$nofollow = true;
+$defaultPerPage = 10;
+$defaultRecentDays = 14;
+$defaultOrderBy = 'date_desc';
+$TEMPLATES_DIR = dirname(__FILE__) .'/templates/';
+$root = NULL;
+$cookieprefix = 'SCUTTLE';
+$tableprefix = 'sc_';
+$adminemail = 'admin@example.org';
+$cleanurls = false;
+
+$usecache = false;
+$dir_cache = dirname(__FILE__) .'/cache/';
+
+$useredir = false;
+$url_redir = 'http://www.google.com/url?sa=D&q=';
+
+$filetypes = array(
+ 'audio' => array('mp3', 'ogg', 'wav'),
+ 'document' => array('doc', 'odt', 'pdf'),
+ 'image' => array('gif', 'jpeg', 'jpg', 'png'),
+ 'video' => array('avi', 'mov', 'mp4', 'mpeg', 'mpg', 'wmv')
+ );
+$reservedusers = array('all', 'watchlist');
+
+include_once('debug.inc.php');
+?>
diff --git a/config.inc.php.example b/config.inc.php.example
new file mode 100644
index 0000000..c78f361
--- /dev/null
+++ b/config.inc.php.example
@@ -0,0 +1,120 @@
+<?php
+######################################################################
+# SCUTTLE: Online social bookmarks manager
+######################################################################
+# Copyright (C) 2005 - 2006 Scuttle project
+# http://sourceforge.net/projects/scuttle/
+# http://scuttle.org/
+#
+# This module is to configure the main options for your site
+#
+# This program is free software. 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.
+######################################################################
+
+######################################################################
+# Database Configuration
+#
+# dbtype: Database driver - mysql, mysqli, mysql4, oracle, postgres,
+# sqlite, db2, firebird, mssql, mssq-odbc
+# dbhost: Database hostname
+# dbport: Database port
+# dbuser: Database username
+# dbpass: Database password
+# dbname: Database name
+######################################################################
+
+$dbtype = 'mysql4';
+$dbhost = '127.0.0.1';
+$dbport = '3306';
+$dbuser = 'username';
+$dbpass = 'password';
+$dbname = 'scuttle';
+
+######################################################################
+# You have finished configuring the database!
+# ONLY EDIT THE INFORMATION BELOW IF YOU KNOW WHAT YOU ARE DOING.
+######################################################################
+# System Configuration
+#
+# sitename: The name of this site.
+# locale: The locale used.
+# top_include: The header file.
+# bottom_include: The footer file.
+# shortdate: The format of short dates.
+# longdate: The format of long dates.
+# nofollow: true - Include rel="nofollow" attribute on
+# bookmark links.
+# false - Don't include rel="nofollow".
+# defaultPerPage: The default number of bookmarks per page.
+# -1 means no limit!
+# defaultRecentDays: The number of days that bookmarks or tags should
+# be considered recent.
+# defaultOrderBy: The default order in which bookmarks will appear.
+# Possible values are:
+# date_desc - By date of entry descending.
+# Latest entry first. (Default)
+# date_asc - By date of entry ascending.
+# Earliest entry first.
+# title_desc - By title, descending alphabetically.
+# title_asc - By title, ascending alphabetically.
+# url_desc - By URL, descending alphabetically.
+# url_asc - By URL, ascending alphabetically.
+# TEMPLATES_DIR: The directory where the template files should be
+# loaded from (the *.tpl.php files)
+# root : Set to NULL to autodetect the root url of the website
+# cookieprefix : The prefix to use for the cookies on the site
+# tableprefix : The table prefix used for this installation
+# adminemail : Contact address for the site administrator. Used
+# as the FROM address in password retrieval e-mails.
+# cleanurls : true - Use mod_rewrite to hide PHP extensions
+# : false - Don't hide extensions [Default]
+#
+# usecache : true - Cache pages when possible
+# false - Don't cache at all [Default]
+# dir_cache : The directory where cache files will be stored
+#
+# useredir : true - Improve privacy by redirecting all bookmarks
+# through the address specified in url_redir
+# false - Don't redirect bookmarks
+# url_redir : URL prefix for bookmarks to redirect through
+#
+# filetypes : An array of bookmark extensions that Scuttle should
+# add system tags for.
+# reservedusers : An array of usernames that cannot be registered
+######################################################################
+
+$sitename = 'Scuttle';
+$locale = 'en_GB';
+$top_include = 'top.inc.php';
+$bottom_include = 'bottom.inc.php';
+$shortdate = 'd-m-Y';
+$longdate = 'j F Y';
+$nofollow = true;
+$defaultPerPage = 10;
+$defaultRecentDays = 14;
+$defaultOrderBy = 'date_desc';
+$TEMPLATES_DIR = dirname(__FILE__) .'/templates/';
+$root = NULL;
+$cookieprefix = 'SCUTTLE';
+$tableprefix = 'sc_';
+$adminemail = 'admin@example.org';
+$cleanurls = false;
+
+$usecache = false;
+$dir_cache = dirname(__FILE__) .'/cache/';
+
+$useredir = false;
+$url_redir = 'http://www.google.com/url?sa=D&q=';
+
+$filetypes = array(
+ 'audio' => array('mp3', 'ogg', 'wav'),
+ 'document' => array('doc', 'odt', 'pdf'),
+ 'image' => array('gif', 'jpeg', 'jpg', 'png'),
+ 'video' => array('avi', 'mov', 'mp4', 'mpeg', 'mpg', 'wmv')
+ );
+$reservedusers = array('all', 'watchlist');
+
+include_once('debug.inc.php');
+?>
diff --git a/debug.inc.php b/debug.inc.php
new file mode 100644
index 0000000..8bd7f33
--- /dev/null
+++ b/debug.inc.php
@@ -0,0 +1,16 @@
+<?php
+// Turn debugging on
+define('SCUTTLE_DEBUG',true);
+
+// generic debugging function
+// Sample:
+// pc_debug(__FILE__, __LINE__, "This is a debug message.");
+
+function pc_debug($file, $line, $message) {
+ if (defined('SCUTTLE_DEBUG') && SCUTTLE_DEBUG) {
+ error_log("---DEBUG-". $sitename .": [$file][$line]: $message");
+ } else {
+ error_log("SCUTTLE_DEBUG disabled");
+ }
+}
+?> \ No newline at end of file
diff --git a/edit.php b/edit.php
new file mode 100644
index 0000000..028e8ba
--- /dev/null
+++ b/edit.php
@@ -0,0 +1,93 @@
+<?php
+/***************************************************************************
+Copyright (C) 2004 - 2006 Scuttle project
+http://sourceforge.net/projects/scuttle/
+http://scuttle.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; 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
+***************************************************************************/
+
+require_once('header.inc.php');
+
+$bookmarkservice = & ServiceFactory :: getServiceInstance('BookmarkService');
+$templateservice = & ServiceFactory :: getServiceInstance('TemplateService');
+$userservice = & ServiceFactory :: getServiceInstance('UserService');
+
+// Header variables
+$tplVars['subtitle'] = T_('Edit Bookmark');
+$tplVars['loadjs'] = true;
+
+list ($url, $bookmark) = explode('/', $_SERVER['PATH_INFO']);
+if (!($row = $bookmarkservice->getBookmark(intval($bookmark), true))) {
+ $tplVars['error'] = sprintf(T_('Bookmark with id %s not was not found'), $bookmark);
+ $templateservice->loadTemplate('error.404.tpl', $tplVars);
+ exit();
+} else {
+ if (!$bookmarkservice->editAllowed($row)) {
+ $tplVars['error'] = T_('You are not allowed to edit this bookmark');
+ $templateservice->loadTemplate('error.500.tpl', $tplVars);
+ exit();
+ } else if ($_POST['submitted']) {
+ if (!$_POST['title'] || !$_POST['address']) {
+ $tplVars['error'] = T_('Your bookmark must have a title and an address');
+ } else {
+ // Update bookmark
+ $bId = intval($bookmark);
+ $address = trim($_POST['address']);
+ $title = trim($_POST['title']);
+ $description = trim($_POST['description']);
+ $status = intval($_POST['status']);
+ $tags = trim($_POST['tags']);
+ $logged_on_user = $userservice->getCurrentUser();
+ if (!$bookmarkservice->updateBookmark($bId, $address, $title, $description, $status, $tags)) {
+ $tplvars['error'] = T_('Error while saving your bookmark');
+ } else {
+ if (isset($_POST['popup'])) {
+ $tplVars['msg'] = (isset($_POST['popup'])) ? '<script type="text/javascript">window.close();</script>' : T_('Bookmark saved');
+ } elseif (isset($_POST['referrer'])) {
+ header('Location: '. $_POST['referrer']);
+ } else {
+ header('Location: '. createURL('bookmarks', $logged_on_user[$userservice->getFieldName('username')]));
+ }
+ }
+ }
+ } else {
+ if ($_POST['delete']) {
+ // Delete bookmark
+ if ($bookmarkservice->deleteBookmark($bookmark)) {
+ $logged_on_user = $userservice->getCurrentUser();
+ if (isset($_POST['referrer'])) {
+ header('Location: '. $_POST['referrer']);
+ } else {
+ header('Location: '. createURL('bookmarks', $logged_on_user[$userservice->getFieldName('username')]));
+ }
+ exit();
+ } else {
+ $tplVars['error'] = T_('Failed to delete the bookmark');
+ $templateservice->loadTemplate('error.500.tpl', $tplVars);
+ exit();
+ }
+ }
+ }
+
+ $tplVars['popup'] = (isset($_GET['popup'])) ? $_GET['popup'] : null;
+ $tplVars['row'] =& $row;
+ $tplVars['formaction'] = createURL('edit', $bookmark);
+ $tplVars['btnsubmit'] = T_('Save Changes');
+ $tplVars['showdelete'] = true;
+ $tplVars['referrer'] = $_SERVER['HTTP_REFERER'];
+ $templateservice->loadTemplate('editbookmark.tpl', $tplVars);
+}
+?>
diff --git a/functions.inc.php b/functions.inc.php
new file mode 100644
index 0000000..63b789a
--- /dev/null
+++ b/functions.inc.php
@@ -0,0 +1,160 @@
+<?php
+// UTF-8 functions
+require_once(dirname(__FILE__) .'/includes/utf8.php');
+
+// Translation
+require_once(dirname(__FILE__) .'/includes/php-gettext/gettext.inc');
+$domain = 'messages';
+T_setlocale(LC_MESSAGES, $locale);
+T_bindtextdomain($domain, dirname(__FILE__) .'/locales');
+T_bind_textdomain_codeset($domain, 'UTF-8');
+T_textdomain($domain);
+
+// Converts tags:
+// - direction = out: convert spaces to underscores;
+// - direction = in: convert underscores to spaces.
+function convertTag($tag, $direction = 'out') {
+ if ($direction == 'out') {
+ $tag = str_replace(' ', '_', $tag);
+ } else {
+ $tag = str_replace('_', ' ', $tag);
+ }
+ return $tag;
+}
+
+function filter($data, $type = NULL) {
+ if (is_string($data)) {
+ $data = trim($data);
+ $data = stripslashes($data);
+ switch ($type) {
+ case 'url':
+ $data = rawurlencode($data);
+ break;
+ default:
+ $data = htmlspecialchars($data);
+ break;
+ }
+ } else if (is_array($data)) {
+ foreach(array_keys($data) as $key) {
+ $row =& $data[$key];
+ $row = filter($row, $type);
+ }
+ }
+ return $data;
+}
+
+function getPerPageCount() {
+ global $defaultPerPage;
+ return $defaultPerPage;
+}
+
+function getSortOrder($override = NULL) {
+ global $defaultOrderBy;
+
+ if (isset($_GET['sort'])) {
+ return $_GET['sort'];
+ } else if (isset($override)) {
+ return $override;
+ } else {
+ return $defaultOrderBy;
+ }
+}
+
+function multi_array_search($needle, $haystack) {
+ if (is_array($haystack)) {
+ foreach(array_keys($haystack) as $key) {
+ $value =& $haystack[$key];
+ $result = multi_array_search($needle, $value);
+ if (is_array($result)) {
+ $return = $result;
+ array_unshift($return, $key);
+ return $return;
+ } elseif ($result == true) {
+ $return[] = $key;
+ return $return;
+ }
+ }
+ return false;
+ } else {
+ if ($needle === $haystack) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+}
+
+function createURL($page = '', $ending = '') {
+ global $cleanurls, $root;
+ if (!$cleanurls && $page != '') {
+ $page .= '.php';
+ }
+ return $root . $page .'/'. $ending;
+}
+
+function message_die($msg_code, $msg_text = '', $msg_title = '', $err_line = '', $err_file = '', $sql = '', $db = NULL) {
+ if(defined('HAS_DIED'))
+ die(T_('message_die() was called multiple times.'));
+ define('HAS_DIED', 1);
+
+ $sql_store = $sql;
+
+ // Get SQL error if we are debugging. Do this as soon as possible to prevent
+ // subsequent queries from overwriting the status of sql_error()
+ if (DEBUG && ($msg_code == GENERAL_ERROR || $msg_code == CRITICAL_ERROR)) {
+ $sql_error = is_null($db) ? '' : $db->sql_error();
+ $debug_text = '';
+
+ if ($sql_error['message'] != '')
+ $debug_text .= '<br /><br />'. T_('SQL Error') .' : '. $sql_error['code'] .' '. $sql_error['message'];
+
+ if ($sql_store != '')
+ $debug_text .= '<br /><br />'. $sql_store;
+
+ if ($err_line != '' && $err_file != '')
+ $debug_text .= '</br /><br />'. T_('Line') .' : '. $err_line .'<br />'. T_('File') .' :'. $err_file;
+ }
+
+ switch($msg_code) {
+ case GENERAL_MESSAGE:
+ if ($msg_title == '')
+ $msg_title = T_('Information');
+ break;
+
+ case CRITICAL_MESSAGE:
+ if ($msg_title == '')
+ $msg_title = T_('Critical Information');
+ break;
+
+ case GENERAL_ERROR:
+ if ($msg_text == '')
+ $msg_text = T_('An error occured');
+
+ if ($msg_title == '')
+ $msg_title = T_('General Error');
+ break;
+
+ case CRITICAL_ERROR:
+ // Critical errors mean we cannot rely on _ANY_ DB information being
+ // available so we're going to dump out a simple echo'd statement
+
+ if ($msg_text == '')
+ $msg_text = T_('An critical error occured');
+
+ if ($msg_title == '')
+ $msg_title = T_('Critical Error');
+ break;
+ }
+
+ // Add on DEBUG info if we've enabled debug mode and this is an error. This
+ // prevents debug info being output for general messages should DEBUG be
+ // set TRUE by accident (preventing confusion for the end user!)
+ if (DEBUG && ($msg_code == GENERAL_ERROR || $msg_code == CRITICAL_ERROR)) {
+ if ($debug_text != '')
+ $msg_text = $msg_text . '<br /><br /><strong>'. T_('DEBUG MODE') .'</strong>'. $debug_text;
+ }
+
+ echo "<html>\n<body>\n". $msg_title ."\n<br /><br />\n". $msg_text ."</body>\n</html>";
+ exit;
+}
+?>
diff --git a/header.inc.php b/header.inc.php
new file mode 100644
index 0000000..751e4e8
--- /dev/null
+++ b/header.inc.php
@@ -0,0 +1,34 @@
+<?php
+ini_set('display_errors', '1');
+ini_set('mysql.trace_mode', '0');
+
+error_reporting(E_ALL ^ E_NOTICE);
+
+define('DEBUG', true);
+session_start();
+
+require_once(dirname(__FILE__) .'/services/servicefactory.php');
+require_once(dirname(__FILE__) .'/config.inc.php');
+require_once(dirname(__FILE__) .'/functions.inc.php');
+
+// Determine the base URL
+if (!isset($root)) {
+ $pieces = explode('/', $_SERVER['SCRIPT_NAME']);
+ $root = '/';
+ foreach($pieces as $piece) {
+ if ($piece != '' && !strstr($piece, '.php')) {
+ $root .= $piece .'/';
+ }
+ }
+ if (($root != '/') && (substr($root, -1, 1) != '/')) {
+ $root .= '/';
+ }
+ $root = 'http://'. $_SERVER['HTTP_HOST'] . $root;
+}
+
+// Error codes
+define('GENERAL_MESSAGE', 200);
+define('GENERAL_ERROR', 202);
+define('CRITICAL_MESSAGE', 203);
+define('CRITICAL_ERROR', 204);
+?> \ No newline at end of file
diff --git a/history.php b/history.php
new file mode 100644
index 0000000..568a8b6
--- /dev/null
+++ b/history.php
@@ -0,0 +1,90 @@
+<?php
+/***************************************************************************
+Copyright (C) 2006 Scuttle project
+http://sourceforge.net/projects/scuttle/
+http://scuttle.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; 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
+***************************************************************************/
+
+require_once('header.inc.php');
+
+$bookmarkservice =& ServiceFactory::getServiceInstance('BookmarkService');
+$templateservice =& ServiceFactory::getServiceInstance('TemplateService');
+$userservice =& ServiceFactory::getServiceInstance('UserService');
+$cacheservice =& ServiceFactory::getServiceInstance('CacheService');
+
+$tplVars = array();
+
+@list($url, $hash) = isset($_SERVER['PATH_INFO']) ? explode('/', $_SERVER['PATH_INFO']) : NULL;
+
+$loggedon = false;
+if ($userservice->isLoggedOn()) {
+ $loggedon = true;
+ $currentUser = $userservice->getCurrentUser();
+ $currentUsername = $currentUser[$userservice->getFieldName('username')];
+}
+
+if ($usecache) {
+ // Generate hash for caching on
+ $hashtext = $_SERVER['REQUEST_URI'];
+ if ($userservice->isLoggedOn()) {
+ $hashtext .= $currentUsername;
+ }
+ $cachehash = md5($hashtext);
+
+ // Cache for 30 minutes
+ $cacheservice->Start($cachehash, 1800);
+}
+
+// Pagination
+$perpage = getPerPageCount();
+if (isset($_GET['page']) && intval($_GET['page']) > 1) {
+ $page = $_GET['page'];
+ $start = ($page - 1) * $perpage;
+} else {
+ $page = 0;
+ $start = 0;
+}
+
+if ($bookmark =& $bookmarkservice->getBookmarkByHash($hash)) {
+ // Template variables
+ $bookmarks =& $bookmarkservice->getBookmarks($start, $perpage, NULL, NULL, NULL, getSortOrder(), NULL, NULL, NULL, $hash);
+ $tplVars['pagetitle'] = T_('History') .': '. $bookmark['bAddress'];
+ $tplVars['subtitle'] = sprintf(T_('History for %s'), $bookmark['bAddress']);
+ $tplVars['loadjs'] = true;
+ $tplVars['page'] = $page;
+ $tplVars['start'] = $start;
+ $tplVars['bookmarkCount'] = $start + 1;
+ $tplVars['total'] = $bookmarks['total'];
+ $tplVars['bookmarks'] =& $bookmarks['bookmarks'];
+ $tplVars['hash'] = $hash;
+ $tplVars['popCount'] = 50;
+ $tplVars['sidebar_blocks'] = array('common');
+ $tplVars['cat_url'] = createURL('tags', '%2$s');
+ $tplVars['nav_url'] = createURL('history', $hash .'/%3$s');
+ $templateservice->loadTemplate('bookmarks.tpl', $tplVars);
+} else {
+ // Throw a 404 error
+ $tplVars['error'] = T_('Address was not found');
+ $templateservice->loadTemplate('error.404.tpl', $tplVars);
+ exit();
+}
+
+if ($usecache) {
+ // Cache output if existing copy has expired
+ $cacheservice->End($cachehash);
+}
+?> \ No newline at end of file
diff --git a/icon.png b/icon.png
new file mode 100644
index 0000000..be864a7
--- /dev/null
+++ b/icon.png
Binary files differ
diff --git a/import.php b/import.php
new file mode 100644
index 0000000..f25b439
--- /dev/null
+++ b/import.php
@@ -0,0 +1,109 @@
+<?
+/***************************************************************************
+Copyright (C) 2004 - 2006 Scuttle project
+http://sourceforge.net/projects/scuttle/
+http://scuttle.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; 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
+***************************************************************************/
+
+require_once('header.inc.php');
+$userservice =& ServiceFactory::getServiceInstance('UserService');
+$templateservice =& ServiceFactory::getServiceInstance('TemplateService');
+$tplVars = array();
+
+if ($userservice->isLoggedOn() && sizeof($_FILES) > 0 && $_FILES['userfile']['size'] > 0) {
+ $userinfo = $userservice->getCurrentUser();
+
+ if (isset($_POST['status']) && is_numeric($_POST['status'])) {
+ $status = intval($_POST['status']);
+ } else {
+ $status = 2;
+ }
+
+ $depth = array();
+ $xml_parser = xml_parser_create();
+ xml_set_element_handler($xml_parser, "startElement", "endElement");
+
+ if (!($fp = fopen($_FILES['userfile']['tmp_name'], "r")))
+ die(T_("Could not open XML input"));
+
+ while ($data = fread($fp, 4096)) {
+ if (!xml_parse($xml_parser, $data, feof($fp))) {
+ die(sprintf(T_("XML error: %s at line %d"),
+ xml_error_string(xml_get_error_code($xml_parser)),
+ xml_get_current_line_number($xml_parser)));
+ }
+ }
+ xml_parser_free($xml_parser);
+ header('Location: '. createURL('bookmarks', $userinfo[$userservice->getFieldName('username')]));
+} else {
+ $templatename = 'importDelicious.tpl';
+ $tplVars['subtitle'] = T_('Import Bookmarks from del.icio.us');
+ $tplVars['formaction'] = createURL('import');
+ $templateservice->loadTemplate($templatename, $tplVars);
+}
+
+function startElement($parser, $name, $attrs) {
+ global $depth, $status, $tplVars, $userservice;
+
+ $bookmarkservice =& ServiceFactory::getServiceInstance('BookmarkService');
+ $userservice =& ServiceFactory::getServiceInstance('UserService');
+
+ if ($name == 'POST') {
+ while(list($attrTitle, $attrVal) = each($attrs)) {
+ switch ($attrTitle) {
+ case 'HREF':
+ $bAddress = $attrVal;
+ break;
+ case 'DESCRIPTION':
+ $bTitle = $attrVal;
+ break;
+ case 'EXTENDED':
+ $bDescription = $attrVal;
+ break;
+ case 'TIME':
+ $bDatetime = $attrVal;
+ break;
+ case 'TAG':
+ $tags = strtolower($attrVal);
+ break;
+ }
+ }
+ if ($bookmarkservice->bookmarkExists($bAddress, $userservice->getCurrentUserId())) {
+ $tplVars['error'] = T_('You have already submitted this bookmark.');
+ } else {
+ // Strangely, PHP can't work out full ISO 8601 dates, so we have to chop off the Z.
+ $bDatetime = substr($bDatetime, 0, -1);
+
+ // If bookmark claims to be from the future, set it to be now instead
+ if (strtotime($bDatetime) > time()) {
+ $bDatetime = gmdate('Y-m-d H:i:s');
+ }
+
+ if ($bookmarkservice->addBookmark($bAddress, $bTitle, $bDescription, $status, $tags, $bDatetime, true, true))
+ $tplVars['msg'] = T_('Bookmark imported.');
+ else
+ $tplVars['error'] = T_('There was an error saving your bookmark. Please try again or contact the administrator.');
+ }
+ }
+ $depth[$parser]++;
+}
+
+function endElement($parser, $name) {
+ global $depth;
+ $depth[$parser]--;
+}
+?>
diff --git a/importNetscape.php b/importNetscape.php
new file mode 100644
index 0000000..6682ec0
--- /dev/null
+++ b/importNetscape.php
@@ -0,0 +1,85 @@
+<?
+/***************************************************************************
+Copyright (C) 2004 - 2006 Scuttle project
+http://sourceforge.net/projects/scuttle/
+http://scuttle.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; 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
+***************************************************************************/
+
+require_once('header.inc.php');
+$bookmarkservice =& ServiceFactory::getServiceInstance('BookmarkService');
+$userservice =& ServiceFactory::getServiceInstance('UserService');
+$templateservice =& ServiceFactory::getServiceInstance('TemplateService');
+$tplVars = array();
+
+if ($userservice->isLoggedOn() && sizeof($_FILES) > 0 && $_FILES['userfile']['size'] > 0) {
+ $userinfo = $userservice->getCurrentUser();
+
+ if (isset($_POST['status']) && is_numeric($_POST['status'])) {
+ $status = intval($_POST['status']);
+ } else {
+ $status = 2;
+ }
+
+ // File handle
+ $html = file_get_contents($_FILES['userfile']['tmp_name']);
+
+ // Create link array
+ preg_match_all('/<a\s+(.*?)\s*\/*>([^<]*)/si', $html, $matches);
+ $links = $matches[1];
+ $titles = $matches[2];
+
+ $size = count($links);
+ for ($i = 0; $i < $size; $i++) {
+ $attributes = preg_split('/\s+/s', $links[$i]);
+ foreach ($attributes as $attribute) {
+ $att = preg_split('/\s*=\s*/s', $attribute, 2);
+ $attrTitle = $att[0];
+ $attrVal = eregi_replace('"', '&quot;', preg_replace('/([\'"]?)(.*)\1/', '$2', $att[1]));
+ switch ($attrTitle) {
+ case "HREF":
+ $bAddress = $attrVal;
+ break;
+ case "ADD_DATE":
+ $bDatetime = gmdate('Y-m-d H:i:s', $attrVal);
+ break;
+ }
+ }
+ $bTitle = eregi_replace('"', '&quot;', trim($titles[$i]));
+
+ if ($bookmarkservice->bookmarkExists($bAddress, $userservice->getCurrentUserId())) {
+ $tplVars['error'] = T_('You have already submitted this bookmark.');
+ } else {
+ // If bookmark claims to be from the future, set it to be now instead
+ if (strtotime($bDatetime) > time()) {
+ $bDatetime = gmdate('Y-m-d H:i:s');
+ }
+
+ if ($bookmarkservice->addBookmark($bAddress, $bTitle, NULL, $status, NULL, $bDatetime, false, true)) {
+ $tplVars['msg'] = T_('Bookmark imported.');
+ } else {
+ $tplVars['error'] = T_('There was an error saving your bookmark. Please try again or contact the administrator.');
+ }
+ }
+ }
+ header('Location: '. createURL('bookmarks', $userinfo[$userservice->getFieldName('username')]));
+} else {
+ $templatename = 'importNetscape.tpl';
+ $tplVars['subtitle'] = T_('Import Bookmarks from Browser File');
+ $tplVars['formaction'] = createURL('importNetscape');
+ $templateservice->loadTemplate($templatename, $tplVars);
+}
+?>
diff --git a/includes/db/db2.php b/includes/db/db2.php
new file mode 100644
index 0000000..b1abf1a
--- /dev/null
+++ b/includes/db/db2.php
@@ -0,0 +1,417 @@
+<?php
+/**
+*
+* @package dbal_db2
+* @version $Id: db2.php,v 1.2 2005/06/10 08:52:03 devalley Exp $
+* @copyright (c) 2005 phpBB Group
+* @license http://opensource.org/licenses/gpl-license.php GNU Public License
+*
+*/
+
+/**
+* @ignore
+*/
+if(!defined("SQL_LAYER"))
+{
+
+define("SQL_LAYER","db2");
+
+/**
+* @package dbal_db2
+* DB2 Database Abstraction Layer
+*/
+class sql_db
+{
+
+ var $db_connect_id;
+ var $query_result;
+ var $query_resultset;
+ var $query_numrows;
+ var $next_id;
+ var $row = array();
+ var $rowset = array();
+ var $row_index;
+ var $num_queries = 0;
+
+ //
+ // Constructor
+ //
+ function sql_db($sqlserver, $sqluser, $sqlpassword, $database, $persistency = true)
+ {
+ $this->persistency = $persistency;
+ $this->user = $sqluser;
+ $this->password = $sqlpassword;
+ $this->dbname = $database;
+
+ $this->server = $sqlserver;
+
+ if($this->persistency)
+ {
+ $this->db_connect_id = odbc_pconnect($this->server, "", "");
+ }
+ else
+ {
+ $this->db_connect_id = odbc_connect($this->server, "", "");
+ }
+
+ if($this->db_connect_id)
+ {
+ @odbc_autocommit($this->db_connect_id, off);
+
+ return $this->db_connect_id;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ //
+ // Other base methods
+ //
+ function sql_close()
+ {
+ if($this->db_connect_id)
+ {
+ if($this->query_result)
+ {
+ @odbc_free_result($this->query_result);
+ }
+ $result = @odbc_close($this->db_connect_id);
+ return $result;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+
+ //
+ // Query method
+ //
+ function sql_query($query = "", $transaction = FALSE)
+ {
+ //
+ // Remove any pre-existing queries
+ //
+ unset($this->query_result);
+ unset($this->row);
+ if($query != "")
+ {
+ $this->num_queries++;
+
+ if(!eregi("^INSERT ",$query))
+ {
+ if(eregi("LIMIT", $query))
+ {
+ preg_match("/^(.*)LIMIT ([0-9]+)[, ]*([0-9]+)*/s", $query, $limits);
+
+ $query = $limits[1];
+ if($limits[3])
+ {
+ $row_offset = $limits[2];
+ $num_rows = $limits[3];
+ }
+ else
+ {
+ $row_offset = 0;
+ $num_rows = $limits[2];
+ }
+
+ $query .= " FETCH FIRST ".($row_offset+$num_rows)." ROWS ONLY OPTIMIZE FOR ".($row_offset+$num_rows)." ROWS";
+
+ $this->query_result = odbc_exec($this->db_connect_id, $query);
+
+ $query_limit_offset = $row_offset;
+ $this->result_numrows[$this->query_result] = $num_rows;
+ }
+ else
+ {
+ $this->query_result = odbc_exec($this->db_connect_id, $query);
+
+ $row_offset = 0;
+ $this->result_numrows[$this->query_result] = 5E6;
+ }
+
+ $result_id = $this->query_result;
+ if($this->query_result && eregi("^SELECT", $query))
+ {
+
+ for($i = 1; $i < odbc_num_fields($result_id)+1; $i++)
+ {
+ $this->result_field_names[$result_id][] = odbc_field_name($result_id, $i);
+ }
+
+ $i = $row_offset + 1;
+ $k = 0;
+ while(odbc_fetch_row($result_id, $i) && $k < $this->result_numrows[$result_id])
+ {
+
+ for($j = 1; $j < count($this->result_field_names[$result_id])+1; $j++)
+ {
+ $this->result_rowset[$result_id][$k][$this->result_field_names[$result_id][$j-1]] = odbc_result($result_id, $j);
+ }
+ $i++;
+ $k++;
+ }
+
+ $this->result_numrows[$result_id] = $k;
+ $this->row_index[$result_id] = 0;
+ }
+ else
+ {
+ $this->result_numrows[$result_id] = @odbc_num_rows($result_id);
+ $this->row_index[$result_id] = 0;
+ }
+ }
+ else
+ {
+ if(eregi("^(INSERT|UPDATE) ", $query))
+ {
+ $query = preg_replace("/\\\'/s", "''", $query);
+ }
+
+ $this->query_result = odbc_exec($this->db_connect_id, $query);
+
+ if($this->query_result)
+ {
+ $sql_id = "VALUES(IDENTITY_VAL_LOCAL())";
+
+ $id_result = odbc_exec($this->db_connect_id, $sql_id);
+ if($id_result)
+ {
+ $row_result = odbc_fetch_row($id_result);
+ if($row_result)
+ {
+ $this->next_id[$this->query_result] = odbc_result($id_result, 1);
+ }
+ }
+ }
+
+ odbc_commit($this->db_connect_id);
+
+ $this->query_limit_offset[$this->query_result] = 0;
+ $this->result_numrows[$this->query_result] = 0;
+ }
+
+ return $this->query_result;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ //
+ // Other query methods
+ //
+ function sql_numrows($query_id = 0)
+ {
+ if(!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+ if($query_id)
+ {
+ return $this->result_numrows[$query_id];
+ }
+ else
+ {
+ return false;
+ }
+ }
+ function sql_affectedrows($query_id = 0)
+ {
+ if(!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+ if($query_id)
+ {
+ return $this->result_numrows[$query_id];
+ }
+ else
+ {
+ return false;
+ }
+ }
+ function sql_numfields($query_id = 0)
+ {
+ if(!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+ if($query_id)
+ {
+ $result = count($this->result_field_names[$query_id]);
+ return $result;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ function sql_fieldname($offset, $query_id = 0)
+ {
+ if(!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+ if($query_id)
+ {
+ $result = $this->result_field_names[$query_id][$offset];
+ return $result;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ function sql_fieldtype($offset, $query_id = 0)
+ {
+ if(!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+ if($query_id)
+ {
+ $result = @odbc_field_type($query_id, $offset);
+ return $result;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ function sql_fetchrow($query_id = 0)
+ {
+ if(!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+ if($query_id)
+ {
+ if($this->row_index[$query_id] < $this->result_numrows[$query_id])
+ {
+ $result = $this->result_rowset[$query_id][$this->row_index[$query_id]];
+ $this->row_index[$query_id]++;
+ return $result;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+ function sql_fetchrowset($query_id = 0)
+ {
+ if(!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+ if($query_id)
+ {
+ $this->row_index[$query_id] = $this->result_numrows[$query_id];
+ return $this->result_rowset[$query_id];
+ }
+ else
+ {
+ return false;
+ }
+ }
+ function sql_fetchfield($field, $row = -1, $query_id = 0)
+ {
+ if(!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+ if($query_id)
+ {
+ if($row < $this->result_numrows[$query_id])
+ {
+ if($row == -1)
+ {
+ $getrow = $this->row_index[$query_id]-1;
+ }
+ else
+ {
+ $getrow = $row;
+ }
+
+ return $this->result_rowset[$query_id][$getrow][$this->result_field_names[$query_id][$field]];
+
+ }
+ else
+ {
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+ function sql_rowseek($offset, $query_id = 0)
+ {
+ if(!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+ if($query_id)
+ {
+ $this->row_index[$query_id] = 0;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ function sql_nextid($query_id = 0)
+ {
+ if(!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+ if($query_id)
+ {
+ return $this->next_id[$query_id];
+ }
+ else
+ {
+ return false;
+ }
+ }
+ function sql_freeresult($query_id = 0)
+ {
+ if(!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+ if($query_id)
+ {
+ $result = @odbc_free_result($query_id);
+ return $result;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ function sql_error($query_id = 0)
+ {
+// $result['code'] = @odbc_error($this->db_connect_id);
+// $result['message'] = @odbc_errormsg($this->db_connect_id);
+
+ return "";
+ }
+
+} // class sql_db
+
+} // if ... define
+
+?> \ No newline at end of file
diff --git a/includes/db/firebird.php b/includes/db/firebird.php
new file mode 100644
index 0000000..58a7d07
--- /dev/null
+++ b/includes/db/firebird.php
@@ -0,0 +1,527 @@
+<?php
+/**
+*
+* @package dbal_firebird
+* @version $Id: firebird.php,v 1.2 2005/06/10 08:52:03 devalley Exp $
+* @copyright (c) 2005 phpBB Group
+* @license http://opensource.org/licenses/gpl-license.php GNU Public License
+*
+*/
+
+/**
+* @ignore
+*/
+if (!defined('SQL_LAYER'))
+{
+
+define('SQL_LAYER', 'firebird');
+
+/**
+* @package dbal_firebird
+* Firebird/Interbase Database Abstraction Layer
+* Minimum Requirement is Firebird 1.5+/Interbase 7.1+
+*/
+class sql_db
+{
+ var $db_connect_id;
+ var $query_result;
+ var $return_on_error = false;
+ var $transaction = false;
+ var $sql_time = 0;
+ var $num_queries = 0;
+ var $open_queries = array();
+
+ var $last_query_text = '';
+
+ function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false)
+ {
+ $this->persistency = $persistency;
+ $this->user = $sqluser;
+ $this->server = $sqlserver . (($port) ? ':' . $port : '');
+ $this->dbname = $database;
+
+ $this->db_connect_id = ($this->persistency) ? @ibase_pconnect($this->server . ':' . $this->dbname, $this->user, $sqlpassword, false, false, 3) : @ibase_connect($this->server . ':' . $this->dbname, $this->user, $sqlpassword, false, false, 3);
+
+ return ($this->db_connect_id) ? $this->db_connect_id : $this->sql_error('');
+ }
+
+ //
+ // Other base methods
+ //
+ function sql_close()
+ {
+ if (!$this->db_connect_id)
+ {
+ return false;
+ }
+
+ if ($this->transaction)
+ {
+ @ibase_commit($this->db_connect_id);
+ }
+
+ if (sizeof($this->open_queries))
+ {
+ foreach ($this->open_queries as $i_query_id => $query_id)
+ {
+ @ibase_free_query($query_id);
+ }
+ }
+
+ return @ibase_close($this->db_connect_id);
+ }
+
+ function sql_return_on_error($fail = false)
+ {
+ $this->return_on_error = $fail;
+ }
+
+ function sql_num_queries()
+ {
+ return $this->num_queries;
+ }
+
+ function sql_transaction($status = 'begin')
+ {
+ switch ($status)
+ {
+ case 'begin':
+ $this->transaction = true;
+ break;
+
+ case 'commit':
+ $result = @ibase_commit();
+ $this->transaction = false;
+
+ if (!$result)
+ {
+ @ibase_rollback();
+ }
+ break;
+
+ case 'rollback':
+ $result = @ibase_rollback();
+ $this->transaction = false;
+ break;
+
+ default:
+ $result = true;
+ }
+
+ return $result;
+ }
+
+ // Base query method
+ function sql_query($query = '', $cache_ttl = 0)
+ {
+ if ($query != '')
+ {
+ global $cache;
+
+ $this->last_query_text = $query;
+ $this->query_result = ($cache_ttl && method_exists($cache, 'sql_load')) ? $cache->sql_load($query) : false;
+
+ if (!$this->query_result)
+ {
+ $this->num_queries++;
+
+ if (($this->query_result = @ibase_query($this->db_connect_id, $query)) === false)
+ {
+ $this->sql_error($query);
+ }
+
+ // TODO: have to debug the commit states in firebird
+ if (!$this->transaction)
+ {
+ @ibase_commit_ret();
+ }
+
+ if ($cache_ttl && method_exists($cache, 'sql_save'))
+ {
+ $cache->sql_save($query, $this->query_result, $cache_ttl);
+ }
+ }
+ }
+ else
+ {
+ return false;
+ }
+
+ return ($this->query_result) ? $this->query_result : false;
+ }
+
+ function sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0)
+ {
+ if ($query != '')
+ {
+ $this->query_result = false;
+
+ $query = 'SELECT FIRST ' . $total . ((!empty($offset)) ? ' SKIP ' . $offset : '') . substr($query, 6);
+
+ return $this->sql_query($query, $cache_ttl);
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ // Idea for this from Ikonboard
+ function sql_build_array($query, $assoc_ary = false)
+ {
+ if (!is_array($assoc_ary))
+ {
+ return false;
+ }
+
+ $fields = array();
+ $values = array();
+ if ($query == 'INSERT')
+ {
+ foreach ($assoc_ary as $key => $var)
+ {
+ $fields[] = $key;
+
+ if (is_null($var))
+ {
+ $values[] = 'NULL';
+ }
+ elseif (is_string($var))
+ {
+ $values[] = "'" . $this->sql_escape($var) . "'";
+ }
+ else
+ {
+ $values[] = (is_bool($var)) ? intval($var) : $var;
+ }
+ }
+
+ $query = ' (' . implode(', ', $fields) . ') VALUES (' . implode(', ', $values) . ')';
+ }
+ else if ($query == 'UPDATE' || $query == 'SELECT')
+ {
+ $values = array();
+ foreach ($assoc_ary as $key => $var)
+ {
+ if (is_null($var))
+ {
+ $values[] = "$key = NULL";
+ }
+ elseif (is_string($var))
+ {
+ $values[] = "$key = '" . $this->sql_escape($var) . "'";
+ }
+ else
+ {
+ $values[] = (is_bool($var)) ? "$key = " . intval($var) : "$key = $var";
+ }
+ }
+ $query = implode(($query == 'UPDATE') ? ', ' : ' AND ', $values);
+ }
+
+ return $query;
+ }
+
+ // Other query methods
+ //
+ // NOTE :: Want to remove _ALL_ reliance on sql_numrows from core code ...
+ // don't want this here by a middle Milestone
+ function sql_numrows($query_id = false)
+ {
+ return FALSE;
+ }
+
+ function sql_affectedrows()
+ {
+ // TODO: hmm, maybe doing something similar as in mssql-odbc.php?
+ return ($this->query_result) ? true : false;
+ }
+
+ function sql_fetchrow($query_id = false)
+ {
+ global $cache;
+
+ if (!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+
+ if (isset($cache->sql_rowset[$query_id]))
+ {
+ return $cache->sql_fetchrow($query_id);
+ }
+
+ $row = array();
+ $cur_row = @ibase_fetch_object($query_id, IBASE_TEXT);
+
+ if (!$cur_row)
+ {
+ return false;
+ }
+
+ foreach (get_object_vars($cur_row) as $key => $value)
+ {
+ $row[strtolower($key)] = trim(str_replace("\\0", "\0", str_replace("\\n", "\n", $value)));
+ }
+ return ($query_id) ? $row : false;
+ }
+
+ function sql_fetchrowset($query_id = false)
+ {
+ if (!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+
+ if ($query_id)
+ {
+ unset($this->rowset[$query_id]);
+ unset($this->row[$query_id]);
+
+ $result = array();
+ while ($this->rowset[$query_id] = get_object_vars(@ibase_fetch_object($query_id, IBASE_TEXT)))
+ {
+ $result[] = $this->rowset[$query_id];
+ }
+
+ return $result;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ function sql_fetchfield($field, $rownum = -1, $query_id = 0)
+ {
+ if (!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+
+ if ($query_id)
+ {
+ if ($rownum > -1)
+ {
+ // erm... ok, my bad, we always use zero. :/
+ for ($i = 0; $i <= $rownum; $i++)
+ {
+ $row = $this->sql_fetchrow($query_id);
+ }
+
+ return $row[$field];
+ }
+ else
+ {
+ if (empty($this->row[$query_id]) && empty($this->rowset[$query_id]))
+ {
+ if ($this->sql_fetchrow($query_id))
+ {
+ $result = $this->row[$query_id][$field];
+ }
+ }
+ else
+ {
+ if ($this->rowset[$query_id])
+ {
+ $result = $this->rowset[$query_id][$field];
+ }
+ else if ($this->row[$query_id])
+ {
+ $result = $this->row[$query_id][$field];
+ }
+ }
+ }
+ return $result;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ function sql_rowseek($rownum, $query_id = 0)
+ {
+ if (!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+
+ for($i = 1; $i < $rownum; $i++)
+ {
+ if (!$this->sql_fetchrow($query_id))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ function sql_nextid()
+ {
+ if ($this->query_result && preg_match('#^INSERT[\t\n ]+INTO[\t\n ]+([a-z0-9\_\-]+)#is', $this->last_query_text, $tablename))
+ {
+ $query = "SELECT GEN_ID('" . $tablename[1] . "_gen', 0) AS new_id
+ FROM RDB\$DATABASE";
+ if (!($temp_q_id = @ibase_query($this->db_connect_id, $query)))
+ {
+ return false;
+ }
+
+ $temp_result = @ibase_fetch_object($temp_q_id);
+ $this->sql_freeresult($temp_q_id);
+
+ return ($temp_result) ? $temp_result->last_value : false;
+ }
+ }
+
+ function sql_freeresult($query_id = false)
+ {
+ if (!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+
+ if (!$this->transaction && $query_id)
+ {
+ @ibase_commit();
+ }
+
+ return ($query_id) ? @ibase_free_result($query_id) : false;
+ }
+
+ function sql_escape($msg)
+ {
+ return (@ini_get('magic_quotes_sybase') || strtolower(@ini_get('magic_quotes_sybase')) == 'on') ? str_replace('\\\'', '\'', addslashes($msg)) : str_replace('\'', '\'\'', stripslashes($msg));
+ }
+
+ function sql_error($sql = '')
+ {
+ if (!$this->return_on_error)
+ {
+ $this_page =(!empty($_SERVER['PHP_SELF'])) ? $_SERVER['PHP_SELF'] : $_ENV['PHP_SELF'];
+ $this_page .= '&' .((!empty($_SERVER['QUERY_STRING'])) ? $_SERVER['QUERY_STRING'] : $_ENV['QUERY_STRING']);
+
+ $message = '<u>SQL ERROR</u> [ ' . SQL_LAYER . ' ]<br /><br />' . @ibase_errmsg() . '<br /><br /><u>CALLING PAGE</u><br /><br />' . $this_page .(($sql != '') ? '<br /><br /><u>SQL</u><br /><br />' . $sql : '') . '<br />';
+
+ if ($this->transaction)
+ {
+ $this->sql_transaction('rollback');
+ }
+
+ trigger_error($message, E_USER_ERROR);
+ }
+
+ $result['message'] = @ibase_errmsg();
+ $result['code'] = '';
+
+ return $result;
+ }
+
+ function sql_report($mode, $query = '')
+ {
+ if (empty($_GET['explain']))
+ {
+ return;
+ }
+
+ global $cache, $starttime, $phpbb_root_path;
+ static $curtime, $query_hold, $html_hold;
+ static $sql_report = '';
+ static $cache_num_queries = 0;
+
+ if (!$query && !empty($query_hold))
+ {
+ $query = $query_hold;
+ }
+
+ switch ($mode)
+ {
+ case 'display':
+ if (!empty($cache))
+ {
+ $cache->unload();
+ }
+ $this->sql_close();
+
+ $mtime = explode(' ', microtime());
+ $totaltime = $mtime[0] + $mtime[1] - $starttime;
+
+ echo '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><meta http-equiv="Content-Type" content="text/html; charset=iso-8869-1"><meta http-equiv="Content-Style-Type" content="text/css"><link rel="stylesheet" href="' . $phpbb_root_path . 'adm/subSilver.css" type="text/css"><style type="text/css">' . "\n";
+ echo 'th { background-image: url(\'' . $phpbb_root_path . 'adm/images/cellpic3.gif\') }' . "\n";
+ echo 'td.cat { background-image: url(\'' . $phpbb_root_path . 'adm/images/cellpic1.gif\') }' . "\n";
+ echo '</style><title>' . $msg_title . '</title></head><body>';
+ echo '<table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td><a href="' . htmlspecialchars(preg_replace('/&explain=([^&]*)/', '', $_SERVER['REQUEST_URI'])) . '"><img src="' . $phpbb_root_path . 'adm/images/header_left.jpg" width="200" height="60" alt="phpBB Logo" title="phpBB Logo" border="0"/></a></td><td width="100%" background="' . $phpbb_root_path . 'adm/images/header_bg.jpg" height="60" align="right" nowrap="nowrap"><span class="maintitle">SQL Report</span> &nbsp; &nbsp; &nbsp;</td></tr></table><br clear="all"/><table width="95%" cellspacing="1" cellpadding="4" border="0" align="center"><tr><td height="40" align="center" valign="middle"><b>Page generated in ' . round($totaltime, 4) . " seconds with {$this->num_queries} queries" . (($cache_num_queries) ? " + $cache_num_queries " . (($cache_num_queries == 1) ? 'query' : 'queries') . ' returning data from cache' : '') . '</b></td></tr><tr><td align="center" nowrap="nowrap">Time spent on MySQL queries: <b>' . round($this->sql_time, 5) . 's</b> | Time spent on PHP: <b>' . round($totaltime - $this->sql_time, 5) . 's</b></td></tr></table><table width="95%" cellspacing="1" cellpadding="4" border="0" align="center"><tr><td>';
+ echo $sql_report;
+ echo '</td></tr></table><br /></body></html>';
+ exit;
+ break;
+
+ case 'start':
+ $query_hold = $query;
+ $html_hold = '';
+
+ $curtime = explode(' ', microtime());
+ $curtime = $curtime[0] + $curtime[1];
+ break;
+
+ case 'fromcache':
+ $endtime = explode(' ', microtime());
+ $endtime = $endtime[0] + $endtime[1];
+
+ $result = @ibase_query($this->db_connect_id, $query);
+ while ($void = @ibase_fetch_object($result, IBASE_TEXT))
+ {
+ // Take the time spent on parsing rows into account
+ }
+ $splittime = explode(' ', microtime());
+ $splittime = $splittime[0] + $splittime[1];
+
+ $time_cache = $endtime - $curtime;
+ $time_db = $splittime - $endtime;
+ $color = ($time_db > $time_cache) ? 'green' : 'red';
+
+ $sql_report .= '<hr width="100%"/><br /><table class="bg" width="100%" cellspacing="1" cellpadding="4" border="0"><tr><th>Query results obtained from the cache</th></tr><tr><td class="row1"><textarea style="font-family:\'Courier New\',monospace;width:100%" rows="5">' . preg_replace('/\t(AND|OR)(\W)/', "\$1\$2", htmlspecialchars(preg_replace('/[\s]*[\n\r\t]+[\n\r\s\t]*/', "\n", $query))) . '</textarea></td></tr></table><p align="center">';
+
+ $sql_report .= 'Before: ' . sprintf('%.5f', $curtime - $starttime) . 's | After: ' . sprintf('%.5f', $endtime - $starttime) . 's | Elapsed [cache]: <b style="color: ' . $color . '">' . sprintf('%.5f', ($time_cache)) . 's</b> | Elapsed [db]: <b>' . sprintf('%.5f', $time_db) . 's</b></p>';
+
+ // Pad the start time to not interfere with page timing
+ $starttime += $time_db;
+
+ @ibase_freeresult($result);
+ $cache_num_queries++;
+ break;
+
+ case 'stop':
+ $endtime = explode(' ', microtime());
+ $endtime = $endtime[0] + $endtime[1];
+
+ $sql_report .= '<hr width="100%"/><br /><table class="bg" width="100%" cellspacing="1" cellpadding="4" border="0"><tr><th>Query #' . $this->num_queries . '</th></tr><tr><td class="row1"><textarea style="font-family:\'Courier New\',monospace;width:100%" rows="5">' . preg_replace('/\t(AND|OR)(\W)/', "\$1\$2", htmlspecialchars(preg_replace('/[\s]*[\n\r\t]+[\n\r\s\t]*/', "\n", $query))) . '</textarea></td></tr></table> ' . $html_hold . '<p align="center">';
+
+ if ($this->query_result)
+ {
+ if (preg_match('/^(UPDATE|DELETE|REPLACE)/', $query))
+ {
+ $sql_report .= "Affected rows: <b>" . $this->sql_affectedrows($this->query_result) . '</b> | ';
+ }
+ $sql_report .= 'Before: ' . sprintf('%.5f', $curtime - $starttime) . 's | After: ' . sprintf('%.5f', $endtime - $starttime) . 's | Elapsed: <b>' . sprintf('%.5f', $endtime - $curtime) . 's</b>';
+ }
+ else
+ {
+ $error = $this->sql_error();
+ $sql_report .= '<b style="color: red">FAILED</b> - ' . SQL_LAYER . ' Error ' . $error['code'] . ': ' . htmlspecialchars($error['message']);
+ }
+
+ $sql_report .= '</p>';
+
+ $this->sql_time += $endtime - $curtime;
+ break;
+ }
+ }
+
+} // class sql_db
+
+} // if ... define
+
+?> \ No newline at end of file
diff --git a/includes/db/index.htm b/includes/db/index.htm
new file mode 100644
index 0000000..ee1f723
--- /dev/null
+++ b/includes/db/index.htm
@@ -0,0 +1,10 @@
+<html>
+<head>
+<title></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+</head>
+
+<body bgcolor="#FFFFFF" text="#000000">
+
+</body>
+</html>
diff --git a/includes/db/mssql-odbc.php b/includes/db/mssql-odbc.php
new file mode 100644
index 0000000..a2d3d02
--- /dev/null
+++ b/includes/db/mssql-odbc.php
@@ -0,0 +1,576 @@
+<?php
+/**
+*
+* @package dbal_odbc_mssql
+* @version $Id: mssql-odbc.php,v 1.2 2005/06/10 08:52:03 devalley Exp $
+* @copyright (c) 2005 phpBB Group
+* @license http://opensource.org/licenses/gpl-license.php GNU Public License
+*
+*/
+
+/**
+* @ignore
+*/
+if (!defined('SQL_LAYER'))
+{
+
+define('SQL_LAYER', 'mssql-odbc');
+
+/**
+* @package dbal_odbc_mssql
+* MSSQL ODBC Database Abstraction Layer for MSSQL
+* Minimum Requirement is Version 2000+
+*/
+class sql_db
+{
+ var $db_connect_id;
+ var $query_result;
+ var $return_on_error = false;
+ var $transaction = false;
+ var $sql_time = 0;
+ var $num_queries = 0;
+ var $open_queries = array();
+
+ var $result_rowset = array();
+ var $field_names = array();
+ var $field_types = array();
+ var $num_rows = array();
+ var $current_row = array();
+
+ function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false)
+ {
+ $this->persistency = $persistency;
+ $this->user = $sqluser;
+ $this->server = $sqlserver . (($port) ? ':' . $port : '');
+ $this->dbname = $database;
+
+ $this->db_connect_id = ($this->persistency) ? @odbc_pconnect($this->server, $this->user, $sqlpassword) : @odbc_connect($this->server, $this->user, $sqlpassword);
+
+ return ($this->db_connect_id) ? $this->db_connect_id : $this->sql_error('');
+ }
+
+ //
+ // Other base methods
+ //
+ function sql_close()
+ {
+ if (!$this->db_connect_id)
+ {
+ return false;
+ }
+
+ if ($this->transaction)
+ {
+ @odbc_commit($this->db_connect_id);
+ }
+
+ if (sizeof($this->result_rowset))
+ {
+ unset($this->result_rowset);
+ unset($this->field_names);
+ unset($this->field_types);
+ unset($this->num_rows);
+ unset($this->current_row);
+ }
+
+ if (sizeof($this->open_queries))
+ {
+ foreach ($this->open_queries as $i_query_id => $query_id)
+ {
+ @odbc_free_result($query_id);
+ }
+ }
+
+ return @odbc_close($this->db_connect_id);
+ }
+
+ function sql_return_on_error($fail = false)
+ {
+ $this->return_on_error = $fail;
+ }
+
+ function sql_num_queries()
+ {
+ return $this->num_queries;
+ }
+
+ function sql_transaction($status = 'begin')
+ {
+ switch ($status)
+ {
+ case 'begin':
+ $result = @odbc_autocommit($this->db_connect_id, false);
+ $this->transaction = true;
+ break;
+
+ case 'commit':
+ $result = @odbc_commit($this->db_connect_id);
+ @odbc_autocommit($this->db_connect_id, true);
+ $this->transaction = false;
+
+ if (!$result)
+ {
+ @odbc_rollback($this->db_connect_id);
+ @odbc_autocommit($this->db_connect_id, true);
+ }
+ break;
+
+ case 'rollback':
+ $result = @odbc_rollback($this->db_connect_id);
+ @odbc_autocommit($this->db_connect_id, true);
+ $this->transaction = false;
+ break;
+
+ default:
+ $result = true;
+ }
+
+ return $result;
+ }
+
+ // Base query method
+ function sql_query($query = '', $cache_ttl = 0)
+ {
+ if ($query != '')
+ {
+ global $cache;
+
+ // EXPLAIN only in extra debug mode
+ if (defined('DEBUG_EXTRA'))
+ {
+ $this->sql_report('start', $query);
+ }
+
+ $this->query_result = ($cache_ttl && method_exists($cache, 'sql_load')) ? $cache->sql_load($query) : false;
+
+ if (!$this->query_result)
+ {
+ $this->num_queries++;
+
+ if (($this->query_result = $this->_odbc_execute_query($query)) === false)
+ {
+ $this->sql_error($query);
+ }
+
+ if (defined('DEBUG_EXTRA'))
+ {
+ $this->sql_report('stop', $query);
+ }
+
+ if ($cache_ttl && method_exists($cache, 'sql_save'))
+ {
+ $this->open_queries[(int) $this->query_result] = $this->query_result;
+ $cache->sql_save($query, $this->query_result, $cache_ttl);
+ // odbc_free_result called within sql_save()
+ }
+ else if (strpos($query, 'SELECT') !== false && $this->query_result)
+ {
+ $this->open_queries[(int) $this->query_result] = $this->query_result;
+ }
+ }
+ else if (defined('DEBUG_EXTRA'))
+ {
+ $this->sql_report('fromcache', $query);
+ }
+ }
+ else
+ {
+ return false;
+ }
+
+ return ($this->query_result) ? $this->query_result : false;
+ }
+
+ function _odbc_execute_query($query)
+ {
+ $result = false;
+
+ if (eregi("^SELECT ", $query))
+ {
+ $result = @odbc_exec($this->db_connect_id, $query);
+
+ if ($result)
+ {
+ if (empty($this->field_names[$result]))
+ {
+ for ($i = 1, $j = @odbc_num_fields($result) + 1; $i < $j; $i++)
+ {
+ $this->field_names[$result][] = @odbc_field_name($result, $i);
+ $this->field_types[$result][] = @odbc_field_type($result, $i);
+ }
+ }
+
+ $this->current_row[$result] = 0;
+ $this->result_rowset[$result] = array();
+
+ $row_outer = (isset($row_offset)) ? $row_offset + 1 : 1;
+ $row_outer_max = (isset($num_rows)) ? $row_offset + $num_rows + 1 : 1E9;
+ $row_inner = 0;
+
+ while (@odbc_fetch_row($result, $row_outer) && $row_outer < $row_outer_max)
+ {
+ for ($i = 0, $j = sizeof($this->field_names[$result]); $i < $j; $i++)
+ {
+ $this->result_rowset[$result][$row_inner][$this->field_names[$result][$i]] = stripslashes(@odbc_result($result, $i + 1));
+ }
+
+ $row_outer++;
+ $row_inner++;
+ }
+
+ $this->num_rows[$result] = sizeof($this->result_rowset[$result]);
+ }
+ }
+ else if (eregi("^INSERT ", $query))
+ {
+ $result = @odbc_exec($this->db_connect_id, $query);
+
+ if ($result)
+ {
+ $result_id = @odbc_exec($this->db_connect_id, 'SELECT @@IDENTITY');
+ if ($result_id)
+ {
+ if (@odbc_fetch_row($result_id))
+ {
+ $this->next_id[$this->db_connect_id] = @odbc_result($result_id, 1);
+ $this->affected_rows[$this->db_connect_id] = @odbc_num_rows($result);
+ }
+ }
+ }
+ }
+ else
+ {
+ $result = @odbc_exec($this->db_connect_id, $query);
+
+ if ($result)
+ {
+ $this->affected_rows[$this->db_connect_id] = @odbc_num_rows($result);
+ }
+ }
+
+ return $result;
+ }
+
+ function sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0)
+ {
+ if ($query != '')
+ {
+ $this->query_result = false;
+
+ // if $total is set to 0 we do not want to limit the number of rows
+ if ($total == 0)
+ {
+ $total = -1;
+ }
+
+ $row_offset = ($total) ? $offset : '';
+ $num_rows = ($total) ? $total : $offset;
+
+ $query = 'SELECT TOP ' . ($row_offset + $num_rows) . ' ' . substr($query, 6);
+
+ return $this->sql_query($query, $cache_ttl);
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ // Idea for this from Ikonboard
+ function sql_build_array($query, $assoc_ary = false)
+ {
+ if (!is_array($assoc_ary))
+ {
+ return false;
+ }
+
+ $fields = array();
+ $values = array();
+ if ($query == 'INSERT')
+ {
+ foreach ($assoc_ary as $key => $var)
+ {
+ $fields[] = $key;
+
+ if (is_null($var))
+ {
+ $values[] = 'NULL';
+ }
+ elseif (is_string($var))
+ {
+ $values[] = "'" . $this->sql_escape($var) . "'";
+ }
+ else
+ {
+ $values[] = (is_bool($var)) ? intval($var) : $var;
+ }
+ }
+
+ $query = ' (' . implode(', ', $fields) . ') VALUES (' . implode(', ', $values) . ')';
+ }
+ else if ($query == 'UPDATE' || $query == 'SELECT')
+ {
+ $values = array();
+ foreach ($assoc_ary as $key => $var)
+ {
+ if (is_null($var))
+ {
+ $values[] = "$key = NULL";
+ }
+ elseif (is_string($var))
+ {
+ $values[] = "$key = '" . $this->sql_escape($var) . "'";
+ }
+ else
+ {
+ $values[] = (is_bool($var)) ? "$key = " . intval($var) : "$key = $var";
+ }
+ }
+ $query = implode(($query == 'UPDATE') ? ', ' : ' AND ', $values);
+ }
+
+ return $query;
+ }
+
+ // Other query methods
+ //
+ // NOTE :: Want to remove _ALL_ reliance on sql_numrows from core code ...
+ // don't want this here by a middle Milestone
+ function sql_numrows($query_id = false)
+ {
+ if (!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+
+ return ($query_id) ? @$this->num_rows($query_id) : false;
+ }
+
+ function sql_affectedrows()
+ {
+ return ($this->affected_rows[$this->db_connect_id]) ? $this->affected_rows[$this->db_connect_id] : false;
+ }
+
+ function sql_fetchrow($query_id = false)
+ {
+ global $cache;
+
+ if (!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+
+ if (isset($cache->sql_rowset[$query_id]))
+ {
+ return $cache->sql_fetchrow($query_id);
+ }
+
+ return ($this->num_rows[$query_id] && $this->current_row[$query_id] < $this->num_rows[$query_id]) ? $this->result_rowset[$query_id][$this->current_row[$query_id]++] : false;
+ }
+
+ function sql_fetchrowset($query_id = false)
+ {
+ if (!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+
+ return ($this->num_rows[$query_id]) ? $this->result_rowset[$query_id] : false;
+ }
+
+ function sql_fetchfield($field, $rownum = -1, $query_id = false)
+ {
+ if (!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+
+ if ($query_id)
+ {
+ if ($rownum < $this->num_rows[$query_id])
+ {
+ $getrow = ($rownum == -1) ? $this->current_row[$query_id] - 1 : $rownum;
+
+ return $this->result_rowset[$query_id][$getrow][$this->field_names[$query_id][$field]];
+ }
+ }
+
+ return false;
+ }
+
+ function sql_rowseek($rownum, $query_id = false)
+ {
+ if (!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+
+ if (isset($this->current_row[$query_id]))
+ {
+ $this->current_row[$query_id] = $rownum;
+ return true;
+ }
+
+ return false;
+ }
+
+ function sql_nextid()
+ {
+ return ($this->next_id[$this->db_connect_id]) ? $this->next_id[$this->db_connect_id] : false;
+ }
+
+ function sql_freeresult($query_id = false)
+ {
+ if (!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+
+ if (isset($this->open_queries[(int) $query_id]))
+ {
+ unset($this->open_queries[(int) $query_id]);
+ unset($this->num_rows[$query_id]);
+ unset($this->current_row[$query_id]);
+ unset($this->result_rowset[$query_id]);
+ unset($this->field_names[$query_id]);
+ unset($this->field_types[$query_id]);
+
+ return @odbc_free_result($query_id);
+ }
+
+ return false;
+ }
+
+ function sql_escape($msg)
+ {
+ return str_replace("'", "''", str_replace('\\', '\\\\', $msg));
+ }
+
+ function sql_error($sql = '')
+ {
+ if (!$this->return_on_error)
+ {
+ $this_page = (isset($_SERVER['PHP_SELF']) && !empty($_SERVER['PHP_SELF'])) ? $_SERVER['PHP_SELF'] : $_ENV['PHP_SELF'];
+ $this_page .= '&' . ((isset($_SERVER['QUERY_STRING']) && !empty($_SERVER['QUERY_STRING'])) ? $_SERVER['QUERY_STRING'] : (isset($_ENV['QUERY_STRING']) ? $_ENV['QUERY_STRING'] : ''));
+
+ $message = '<u>SQL ERROR</u> [ ' . SQL_LAYER . ' ]<br /><br />' . @odbc_errormsg() . '<br /><br /><u>CALLING PAGE</u><br /><br />' . htmlspecialchars($this_page) . (($sql != '') ? '<br /><br /><u>SQL</u><br /><br />' . $sql : '') . '<br />';
+
+ if ($this->transaction)
+ {
+ $this->sql_transaction('rollback');
+ }
+
+ trigger_error($message, E_USER_ERROR);
+ }
+
+ $result = array(
+ 'message' => @odbc_errormsg(),
+ 'code' => @odbc_error()
+ );
+
+ return $result;
+ }
+
+ function sql_report($mode, $query = '')
+ {
+ if (empty($_GET['explain']))
+ {
+ return;
+ }
+
+ global $cache, $starttime, $phpbb_root_path;
+ static $curtime, $query_hold, $html_hold;
+ static $sql_report = '';
+ static $cache_num_queries = 0;
+
+ if (!$query && !empty($query_hold))
+ {
+ $query = $query_hold;
+ }
+
+ switch ($mode)
+ {
+ case 'display':
+ if (!empty($cache))
+ {
+ $cache->unload();
+ }
+ $this->sql_close();
+
+ $mtime = explode(' ', microtime());
+ $totaltime = $mtime[0] + $mtime[1] - $starttime;
+
+ echo '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><meta http-equiv="Content-Type" content="text/html; charset=iso-8869-1"><meta http-equiv="Content-Style-Type" content="text/css"><link rel="stylesheet" href="' . $phpbb_root_path . 'adm/subSilver.css" type="text/css"><style type="text/css">' . "\n";
+ echo 'th { background-image: url(\'' . $phpbb_root_path . 'adm/images/cellpic3.gif\') }' . "\n";
+ echo 'td.cat { background-image: url(\'' . $phpbb_root_path . 'adm/images/cellpic1.gif\') }' . "\n";
+ echo '</style><title>' . $msg_title . '</title></head><body>';
+ echo '<table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td><a href="' . htmlspecialchars(preg_replace('/&explain=([^&]*)/', '', $_SERVER['REQUEST_URI'])) . '"><img src="' . $phpbb_root_path . 'adm/images/header_left.jpg" width="200" height="60" alt="phpBB Logo" title="phpBB Logo" border="0"/></a></td><td width="100%" background="' . $phpbb_root_path . 'adm/images/header_bg.jpg" height="60" align="right" nowrap="nowrap"><span class="maintitle">SQL Report</span> &nbsp; &nbsp; &nbsp;</td></tr></table><br clear="all"/><table width="95%" cellspacing="1" cellpadding="4" border="0" align="center"><tr><td height="40" align="center" valign="middle"><b>Page generated in ' . round($totaltime, 4) . " seconds with {$this->num_queries} queries" . (($cache_num_queries) ? " + $cache_num_queries " . (($cache_num_queries == 1) ? 'query' : 'queries') . ' returning data from cache' : '') . '</b></td></tr><tr><td align="center" nowrap="nowrap">Time spent on MySQL queries: <b>' . round($this->sql_time, 5) . 's</b> | Time spent on PHP: <b>' . round($totaltime - $this->sql_time, 5) . 's</b></td></tr></table><table width="95%" cellspacing="1" cellpadding="4" border="0" align="center"><tr><td>';
+ echo $sql_report;
+ echo '</td></tr></table><br /></body></html>';
+ exit;
+ break;
+
+ case 'start':
+ $query_hold = $query;
+ $html_hold = '';
+
+ $curtime = explode(' ', microtime());
+ $curtime = $curtime[0] + $curtime[1];
+ break;
+
+ case 'fromcache':
+ $endtime = explode(' ', microtime());
+ $endtime = $endtime[0] + $endtime[1];
+
+ $result = $this->_odbc_execute_query($query);
+
+ $splittime = explode(' ', microtime());
+ $splittime = $splittime[0] + $splittime[1];
+
+ $time_cache = $endtime - $curtime;
+ $time_db = $splittime - $endtime;
+ $color = ($time_db > $time_cache) ? 'green' : 'red';
+
+ $sql_report .= '<hr width="100%"/><br /><table class="bg" width="100%" cellspacing="1" cellpadding="4" border="0"><tr><th>Query results obtained from the cache</th></tr><tr><td class="row1"><textarea style="font-family:\'Courier New\',monospace;width:100%" rows="5">' . preg_replace('/\t(AND|OR)(\W)/', "\$1\$2", htmlspecialchars(preg_replace('/[\s]*[\n\r\t]+[\n\r\s\t]*/', "\n", $query))) . '</textarea></td></tr></table><p align="center">';
+
+ $sql_report .= 'Before: ' . sprintf('%.5f', $curtime - $starttime) . 's | After: ' . sprintf('%.5f', $endtime - $starttime) . 's | Elapsed [cache]: <b style="color: ' . $color . '">' . sprintf('%.5f', ($time_cache)) . 's</b> | Elapsed [db]: <b>' . sprintf('%.5f', $time_db) . 's</b></p>';
+
+ // Pad the start time to not interfere with page timing
+ $starttime += $time_db;
+
+ @odbc_free_result($result);
+ $cache_num_queries++;
+ break;
+
+ case 'stop':
+ $endtime = explode(' ', microtime());
+ $endtime = $endtime[0] + $endtime[1];
+
+ $sql_report .= '<hr width="100%"/><br /><table class="bg" width="100%" cellspacing="1" cellpadding="4" border="0"><tr><th>Query #' . $this->num_queries . '</th></tr><tr><td class="row1"><textarea style="font-family:\'Courier New\',monospace;width:100%" rows="5">' . preg_replace('/\t(AND|OR)(\W)/', "\$1\$2", htmlspecialchars(preg_replace('/[\s]*[\n\r\t]+[\n\r\s\t]*/', "\n", $query))) . '</textarea></td></tr></table> ' . $html_hold . '<p align="center">';
+
+ if ($this->query_result)
+ {
+ if (preg_match('/^(UPDATE|DELETE|REPLACE)/', $query))
+ {
+ $sql_report .= "Affected rows: <b>" . $this->sql_affectedrows($this->query_result) . '</b> | ';
+ }
+ $sql_report .= 'Before: ' . sprintf('%.5f', $curtime - $starttime) . 's | After: ' . sprintf('%.5f', $endtime - $starttime) . 's | Elapsed: <b>' . sprintf('%.5f', $endtime - $curtime) . 's</b>';
+ }
+ else
+ {
+ $error = $this->sql_error();
+ $sql_report .= '<b style="color: red">FAILED</b> - ' . SQL_LAYER . ' Error ' . $error['code'] . ': ' . htmlspecialchars($error['message']);
+ }
+
+ $sql_report .= '</p>';
+
+ $this->sql_time += $endtime - $curtime;
+ break;
+ }
+ }
+
+} // class sql_db
+
+} // if ... define
+
+?> \ No newline at end of file
diff --git a/includes/db/mssql.php b/includes/db/mssql.php
new file mode 100644
index 0000000..2b17b9e
--- /dev/null
+++ b/includes/db/mssql.php
@@ -0,0 +1,551 @@
+<?php
+/**
+*
+* @package dbal_mssql
+* @version $Id: mssql.php,v 1.2 2005/06/10 08:52:03 devalley Exp $
+* @copyright (c) 2005 phpBB Group
+* @license http://opensource.org/licenses/gpl-license.php GNU Public License
+*
+*/
+
+/**
+* @ignore
+*/
+if (!defined('SQL_LAYER'))
+{
+
+define('SQL_LAYER', 'mssql');
+
+/**
+* @package dbal_mssql
+* MSSQL Database Abstraction Layer
+* Minimum Requirement is MSSQL 2000+
+*/
+class sql_db
+{
+ var $db_connect_id;
+ var $query_result;
+ var $return_on_error = false;
+ var $transaction = false;
+ var $sql_time = 0;
+ var $num_queries = 0;
+ var $open_queries = array();
+
+ function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false)
+ {
+ $this->persistency = $persistency;
+ $this->user = $sqluser;
+ $this->server = $sqlserver . (($port) ? ':' . $port : '');
+ $this->dbname = $database;
+
+ $this->db_connect_id = ($this->persistency) ? @mssql_pconnect($this->server, $this->user, $sqlpassword) : @mssql_connect($this->server, $this->user, $sqlpassword);
+
+ if ($this->db_connect_id && $this->dbname != '')
+ {
+ if (!@mssql_select_db($this->dbname, $this->db_connect_id))
+ {
+ @mssql_close($this->db_connect_id);
+ return false;
+ }
+ }
+
+ return ($this->db_connect_id) ? $this->db_connect_id : $this->sql_error('');
+ }
+
+ function sql_close()
+ {
+ if (!$this->db_connect_id)
+ {
+ return false;
+ }
+
+ if ($this->transaction)
+ {
+ @mssql_query('COMMIT', $this->db_connect_id);
+ }
+
+ if (sizeof($this->open_queries))
+ {
+ foreach ($this->open_queries as $i_query_id => $query_id)
+ {
+ @mssql_free_result($query_id);
+ }
+ }
+
+ return @mssql_close($this->db_connect_id);
+ }
+
+ function sql_return_on_error($fail = false)
+ {
+ $this->return_on_error = $fail;
+ }
+
+ function sql_num_queries()
+ {
+ return $this->num_queries;
+ }
+
+ function sql_transaction($status = 'begin')
+ {
+ switch ($status)
+ {
+ case 'begin':
+ $result = @mssql_query('BEGIN TRANSACTION', $this->db_connect_id);
+ $this->transaction = true;
+ break;
+
+ case 'commit':
+ $result = @mssql_query('commit', $this->db_connect_id);
+ $this->transaction = false;
+
+ if (!$result)
+ {
+ @mssql_query('ROLLBACK', $this->db_connect_id);
+ }
+ break;
+
+ case 'rollback':
+ $result = @mssql_query('ROLLBACK', $this->db_connect_id);
+ $this->transaction = false;
+ break;
+
+ default:
+ $result = true;
+ }
+
+ return $result;
+ }
+
+ // Base query method
+ function sql_query($query = '', $cache_ttl = 0)
+ {
+ if ($query != '')
+ {
+ global $cache;
+
+ // EXPLAIN only in extra debug mode
+ if (defined('DEBUG_EXTRA'))
+ {
+ $this->sql_report('start', $query);
+ }
+
+ $this->query_result = ($cache_ttl && method_exists($cache, 'sql_load')) ? $cache->sql_load($query) : false;
+
+ if (!$this->query_result)
+ {
+ $this->num_queries++;
+
+ if (($this->query_result = @mssql_query($query, $this->db_connect_id)) === false)
+ {
+ $this->sql_error($query);
+ }
+
+ if (defined('DEBUG_EXTRA'))
+ {
+ $this->sql_report('stop', $query);
+ }
+
+ if ($cache_ttl && method_exists($cache, 'sql_save'))
+ {
+ $this->open_queries[(int) $this->query_result] = $this->query_result;
+ $cache->sql_save($query, $this->query_result, $cache_ttl);
+ // sql_freeresult called within sql_save()
+ }
+ else if (strpos($query, 'SELECT') !== false && $this->query_result)
+ {
+ $this->open_queries[(int) $this->query_result] = $this->query_result;
+ }
+ }
+ else if (defined('DEBUG_EXTRA'))
+ {
+ $this->sql_report('fromcache', $query);
+ }
+ }
+ else
+ {
+ return false;
+ }
+
+ return ($this->query_result) ? $this->query_result : false;
+ }
+
+ function sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0)
+ {
+ if ($query != '')
+ {
+ $this->query_result = false;
+
+ // if $total is set to 0 we do not want to limit the number of rows
+ if ($total == 0)
+ {
+ $total = -1;
+ }
+
+ $row_offset = ($total) ? $offset : '';
+ $num_rows = ($total) ? $total : $offset;
+
+ $query = 'SELECT TOP ' . ($row_offset + $num_rows) . ' ' . substr($query, 6);
+
+ return $this->sql_query($query, $cache_ttl);
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ // Idea for this from Ikonboard
+ function sql_build_array($query, $assoc_ary = false)
+ {
+ if (!is_array($assoc_ary))
+ {
+ return false;
+ }
+
+ $fields = array();
+ $values = array();
+ if ($query == 'INSERT')
+ {
+ foreach ($assoc_ary as $key => $var)
+ {
+ $fields[] = $key;
+
+ if (is_null($var))
+ {
+ $values[] = 'NULL';
+ }
+ elseif (is_string($var))
+ {
+ $values[] = "'" . $this->sql_escape($var) . "'";
+ }
+ else
+ {
+ $values[] = (is_bool($var)) ? intval($var) : $var;
+ }
+ }
+
+ $query = ' (' . implode(', ', $fields) . ') VALUES (' . implode(', ', $values) . ')';
+ }
+ else if ($query == 'UPDATE' || $query == 'SELECT')
+ {
+ $values = array();
+ foreach ($assoc_ary as $key => $var)
+ {
+ if (is_null($var))
+ {
+ $values[] = "$key = NULL";
+ }
+ elseif (is_string($var))
+ {
+ $values[] = "$key = '" . $this->sql_escape($var) . "'";
+ }
+ else
+ {
+ $values[] = (is_bool($var)) ? "$key = " . intval($var) : "$key = $var";
+ }
+ }
+ $query = implode(($query == 'UPDATE') ? ', ' : ' AND ', $values);
+ }
+
+ return $query;
+ }
+
+ // Other query methods
+ //
+ // NOTE :: Want to remove _ALL_ reliance on sql_numrows from core code ...
+ // don't want this here by a middle Milestone
+ function sql_numrows($query_id = false)
+ {
+ if (!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+
+// return (isset($this->limit_offset[$query_id])) ? @mssql_num_rows($query_id) - $this->limit_offset[$query_id] : @mssql_num_rows($query_id);
+ return ($query_id) ? @mssql_num_rows($query_id) : false;
+ }
+
+ function sql_affectedrows()
+ {
+ return ($this->db_connect_id) ? @mssql_rows_affected($this->db_connect_id) : false;
+ }
+
+ function sql_fetchrow($query_id = false)
+ {
+ global $cache;
+
+ if (!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+
+ if (isset($cache->sql_rowset[$query_id]))
+ {
+ return $cache->sql_fetchrow($query_id);
+ }
+
+ $row = @mssql_fetch_array($query_id, MSSQL_ASSOC);
+
+ if ($row)
+ {
+ foreach ($row as $key => $value)
+ {
+ $row[$key] = ($value === ' ') ? trim($value) : $value;
+ }
+ }
+
+ return $row;
+ }
+
+ function sql_fetchrowset($query_id = false)
+ {
+ if (!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+
+ if ($query_id)
+ {
+ unset($this->rowset[$query_id]);
+ unset($this->row[$query_id]);
+
+ $result = array();
+ while ($this->rowset[$query_id] = $this->sql_fetchrow($query_id))
+ {
+ $result[] = $this->rowset[$query_id];
+ }
+ return $result;
+ }
+
+ return false;
+ }
+
+ function sql_fetchfield($field, $rownum = -1, $query_id = false)
+ {
+ if (!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+
+ if ($query_id)
+ {
+ if ($rownum > -1)
+ {
+// (!empty($this->limit_offset[$query_id])) ? @mssql_data_seek($query_id, ($this->limit_offset[$query_id] + $rownum)) : @mssql_data_seek($query_id, $rownum);
+ @mssql_data_seek($query_id, $rownum);
+ $row = @mssql_fetch_array($query_id, MSSQL_ASSOC);
+ $result = isset($row[$field]) ? $row[$field] : false;
+ }
+ else
+ {
+ if (empty($this->row[$query_id]) && empty($this->rowset[$query_id]))
+ {
+ if ($this->sql_fetchrow($query_id))
+ {
+ $result = $this->row[$query_id][$field];
+ }
+ }
+ else
+ {
+ if ($this->rowset[$query_id])
+ {
+ $result = $this->rowset[$query_id][$field];
+ }
+ elseif ($this->row[$query_id])
+ {
+ $result = $this->row[$query_id][$field];
+ }
+ }
+ }
+
+ return $result;
+ }
+
+ return false;
+ }
+
+ function sql_rowseek($rownum, $query_id = false)
+ {
+ if (!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+
+ if (isset($this->current_row[$query_id]))
+ {
+// (!empty($this->limit_offset[$query_id])) ? @mssql_data_seek($query_id, ($this->limit_offset[$query_id] + $rownum)) : @mssql_data_seek($query_id, $rownum);
+ @mssql_data_seek($query_id, $rownum);
+ return true;
+ }
+
+ return false;
+ }
+
+ function sql_nextid()
+ {
+ $result_id = @mssql_query('SELECT @@IDENTITY', $this->db_connect_id);
+ if ($result_id)
+ {
+ if (@mssql_fetch_array($result_id, MSSQL_ASSOC))
+ {
+ return @mssql_result($result_id, 1);
+ }
+ }
+
+ return false;
+ }
+
+ function sql_freeresult($query_id = false)
+ {
+ if (!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+
+ if (isset($this->open_queries[$query_id]))
+ {
+ unset($this->open_queries[$query_id]);
+ unset($this->result_rowset[$query_id]);
+
+ return @mssql_free_result($query_id);
+ }
+
+ return false;
+ }
+
+ function sql_escape($msg)
+ {
+ return str_replace("'", "''", str_replace('\\', '\\\\', $msg));
+ }
+
+ function sql_error($sql = '')
+ {
+ if (!$this->return_on_error)
+ {
+ $this_page = (isset($_SERVER['PHP_SELF']) && !empty($_SERVER['PHP_SELF'])) ? $_SERVER['PHP_SELF'] : $_ENV['PHP_SELF'];
+ $this_page .= '&' . ((isset($_SERVER['QUERY_STRING']) && !empty($_SERVER['QUERY_STRING'])) ? $_SERVER['QUERY_STRING'] : (isset($_ENV['QUERY_STRING']) ? $_ENV['QUERY_STRING'] : ''));
+
+ $message = '<u>SQL ERROR</u> [ ' . SQL_LAYER . ' ]<br /><br />' . @mssql_get_last_message() . '<br /><br /><u>CALLING PAGE</u><br /><br />' . htmlspecialchars($this_page) . (($sql != '') ? '<br /><br /><u>SQL</u><br /><br />' . $sql : '') . '<br />';
+
+ if ($this->transaction)
+ {
+ $this->sql_transaction('rollback');
+ }
+
+ trigger_error($message, E_USER_ERROR);
+ }
+
+ $result = array(
+ 'message' => @mssql_get_last_message($this->db_connect_id),
+ 'code' => ''
+ );
+
+ return $result;
+ }
+
+ function sql_report($mode, $query = '')
+ {
+ if (empty($_GET['explain']))
+ {
+ return;
+ }
+
+ global $cache, $starttime, $phpbb_root_path;
+ static $curtime, $query_hold, $html_hold;
+ static $sql_report = '';
+ static $cache_num_queries = 0;
+
+ if (!$query && !empty($query_hold))
+ {
+ $query = $query_hold;
+ }
+
+ switch ($mode)
+ {
+ case 'display':
+ if (!empty($cache))
+ {
+ $cache->unload();
+ }
+ $this->sql_close();
+
+ $mtime = explode(' ', microtime());
+ $totaltime = $mtime[0] + $mtime[1] - $starttime;
+
+ echo '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><meta http-equiv="Content-Type" content="text/html; charset=iso-8869-1"><meta http-equiv="Content-Style-Type" content="text/css"><link rel="stylesheet" href="' . $phpbb_root_path . 'adm/subSilver.css" type="text/css"><style type="text/css">' . "\n";
+ echo 'th { background-image: url(\'' . $phpbb_root_path . 'adm/images/cellpic3.gif\') }' . "\n";
+ echo 'td.cat { background-image: url(\'' . $phpbb_root_path . 'adm/images/cellpic1.gif\') }' . "\n";
+ echo '</style><title>' . $msg_title . '</title></head><body>';
+ echo '<table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td><a href="' . htmlspecialchars(preg_replace('/&explain=([^&]*)/', '', $_SERVER['REQUEST_URI'])) . '"><img src="' . $phpbb_root_path . 'adm/images/header_left.jpg" width="200" height="60" alt="phpBB Logo" title="phpBB Logo" border="0"/></a></td><td width="100%" background="' . $phpbb_root_path . 'adm/images/header_bg.jpg" height="60" align="right" nowrap="nowrap"><span class="maintitle">SQL Report</span> &nbsp; &nbsp; &nbsp;</td></tr></table><br clear="all"/><table width="95%" cellspacing="1" cellpadding="4" border="0" align="center"><tr><td height="40" align="center" valign="middle"><b>Page generated in ' . round($totaltime, 4) . " seconds with {$this->num_queries} queries" . (($cache_num_queries) ? " + $cache_num_queries " . (($cache_num_queries == 1) ? 'query' : 'queries') . ' returning data from cache' : '') . '</b></td></tr><tr><td align="center" nowrap="nowrap">Time spent on MySQL queries: <b>' . round($this->sql_time, 5) . 's</b> | Time spent on PHP: <b>' . round($totaltime - $this->sql_time, 5) . 's</b></td></tr></table><table width="95%" cellspacing="1" cellpadding="4" border="0" align="center"><tr><td>';
+ echo $sql_report;
+ echo '</td></tr></table><br /></body></html>';
+ exit;
+ break;
+
+ case 'start':
+ $query_hold = $query;
+ $html_hold = '';
+
+ $curtime = explode(' ', microtime());
+ $curtime = $curtime[0] + $curtime[1];
+ break;
+
+ case 'fromcache':
+ $endtime = explode(' ', microtime());
+ $endtime = $endtime[0] + $endtime[1];
+
+ $result = @mssql_query($query, $this->db_connect_id);
+ while ($void = @mssql_fetch_array($result, MSSQL_ASSOC))
+ {
+ // Take the time spent on parsing rows into account
+ }
+ $splittime = explode(' ', microtime());
+ $splittime = $splittime[0] + $splittime[1];
+
+ $time_cache = $endtime - $curtime;
+ $time_db = $splittime - $endtime;
+ $color = ($time_db > $time_cache) ? 'green' : 'red';
+
+ $sql_report .= '<hr width="100%"/><br /><table class="bg" width="100%" cellspacing="1" cellpadding="4" border="0"><tr><th>Query results obtained from the cache</th></tr><tr><td class="row1"><textarea style="font-family:\'Courier New\',monospace;width:100%" rows="5">' . preg_replace('/\t(AND|OR)(\W)/', "\$1\$2", htmlspecialchars(preg_replace('/[\s]*[\n\r\t]+[\n\r\s\t]*/', "\n", $query))) . '</textarea></td></tr></table><p align="center">';
+
+ $sql_report .= 'Before: ' . sprintf('%.5f', $curtime - $starttime) . 's | After: ' . sprintf('%.5f', $endtime - $starttime) . 's | Elapsed [cache]: <b style="color: ' . $color . '">' . sprintf('%.5f', ($time_cache)) . 's</b> | Elapsed [db]: <b>' . sprintf('%.5f', $time_db) . 's</b></p>';
+
+ // Pad the start time to not interfere with page timing
+ $starttime += $time_db;
+
+ @mssql_free_result($result);
+ $cache_num_queries++;
+ break;
+
+ case 'stop':
+ $endtime = explode(' ', microtime());
+ $endtime = $endtime[0] + $endtime[1];
+
+ $sql_report .= '<hr width="100%"/><br /><table class="bg" width="100%" cellspacing="1" cellpadding="4" border="0"><tr><th>Query #' . $this->num_queries . '</th></tr><tr><td class="row1"><textarea style="font-family:\'Courier New\',monospace;width:100%" rows="5">' . preg_replace('/\t(AND|OR)(\W)/', "\$1\$2", htmlspecialchars(preg_replace('/[\s]*[\n\r\t]+[\n\r\s\t]*/', "\n", $query))) . '</textarea></td></tr></table> ' . $html_hold . '<p align="center">';
+
+ if ($this->query_result)
+ {
+ if (preg_match('/^(UPDATE|DELETE|REPLACE)/', $query))
+ {
+ $sql_report .= "Affected rows: <b>" . $this->sql_affectedrows($this->query_result) . '</b> | ';
+ }
+ $sql_report .= 'Before: ' . sprintf('%.5f', $curtime - $starttime) . 's | After: ' . sprintf('%.5f', $endtime - $starttime) . 's | Elapsed: <b>' . sprintf('%.5f', $endtime - $curtime) . 's</b>';
+ }
+ else
+ {
+ $error = $this->sql_error();
+ $sql_report .= '<b style="color: red">FAILED</b> - ' . SQL_LAYER . ' Error ' . $error['code'] . ': ' . htmlspecialchars($error['message']);
+ }
+
+ $sql_report .= '</p>';
+
+ $this->sql_time += $endtime - $curtime;
+ break;
+ }
+ }
+
+} // class sql_db
+
+} // if ... define
+
+?> \ No newline at end of file
diff --git a/includes/db/mysql.php b/includes/db/mysql.php
new file mode 100644
index 0000000..a646e0d
--- /dev/null
+++ b/includes/db/mysql.php
@@ -0,0 +1,552 @@
+<?php
+/**
+*
+* @package dbal_mysql
+* @version $Id: mysql.php,v 1.5 2006/02/10 01:30:19 scronide Exp $
+* @copyright (c) 2005 phpBB Group
+* @license http://opensource.org/licenses/gpl-license.php GNU Public License
+*
+*/
+
+/**
+* @ignore
+*/
+if (!defined('SQL_LAYER'))
+{
+
+define('SQL_LAYER', 'mysql');
+
+/**
+* @package dbal_mysql
+* MySQL Database Abstraction Layer
+* Minimum Requirement is 3.23+/4.0+/4.1+
+*/
+class sql_db
+{
+ var $db_connect_id;
+ var $query_result;
+ var $return_on_error = false;
+ var $transaction = false;
+ var $sql_time = 0;
+ var $num_queries = 0;
+ var $open_queries = array();
+
+ function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false)
+ {
+ $this->persistency = $persistency;
+ $this->user = $sqluser;
+ $this->server = $sqlserver . (($port) ? ':' . $port : '');
+ $this->dbname = $database;
+
+ $this->db_connect_id = ($this->persistency) ? @mysql_pconnect($this->server, $this->user, $sqlpassword) : @mysql_connect($this->server, $this->user, $sqlpassword);
+
+ if ($this->db_connect_id && $this->dbname != '')
+ {
+ if (@mysql_select_db($this->dbname))
+ {
+ return $this->db_connect_id;
+ }
+ }
+
+ return $this->sql_error('');
+ }
+
+ //
+ // Other base methods
+ //
+ function sql_close()
+ {
+ if (!$this->db_connect_id)
+ {
+ return false;
+ }
+
+ if (sizeof($this->open_queries))
+ {
+ foreach ($this->open_queries as $i_query_id => $query_id)
+ {
+ @mysql_free_result($query_id);
+ }
+ }
+
+ return @mysql_close($this->db_connect_id);
+ }
+
+ function sql_return_on_error($fail = false)
+ {
+ $this->return_on_error = $fail;
+ }
+
+ function sql_num_queries()
+ {
+ return $this->num_queries;
+ }
+
+ function sql_transaction($status = 'begin')
+ {
+ switch ($status)
+ {
+ case 'begin':
+ $result = @mysql_query('BEGIN', $this->db_connect_id);
+ $this->transaction = true;
+ break;
+
+ case 'commit':
+ $result = @mysql_query('COMMIT', $this->db_connect_id);
+ $this->transaction = false;
+
+ if (!$result)
+ {
+ @mysql_query('ROLLBACK', $this->db_connect_id);
+ }
+ break;
+
+ case 'rollback':
+ $result = @mysql_query('ROLLBACK', $this->db_connect_id);
+ $this->transaction = false;
+ break;
+
+ default:
+ $result = true;
+ }
+
+ return $result;
+ }
+
+ // Base query method
+ function sql_query($query = '', $cache_ttl = 0)
+ {
+ if ($query != '')
+ {
+ global $cache;
+
+ // EXPLAIN only in extra debug mode
+ if (defined('DEBUG_EXTRA'))
+ {
+ $this->sql_report('start', $query);
+ }
+
+ $this->query_result = ($cache_ttl && method_exists($cache, 'sql_load')) ? $cache->sql_load($query) : false;
+
+ if (!$this->query_result)
+ {
+ $this->num_queries++;
+
+ if (($this->query_result = @mysql_query($query, $this->db_connect_id)) === false)
+ {
+ $this->sql_error($query);
+ }
+
+ if (defined('DEBUG_EXTRA'))
+ {
+ $this->sql_report('stop', $query);
+ }
+
+ if ($cache_ttl && method_exists($cache, 'sql_save'))
+ {
+ $this->open_queries[(int) $this->query_result] = $this->query_result;
+ $cache->sql_save($query, $this->query_result, $cache_ttl);
+ // mysql_free_result called within sql_save()
+ }
+ else if (strpos($query, 'SELECT') !== false && $this->query_result)
+ {
+ $this->open_queries[(int) $this->query_result] = $this->query_result;
+ }
+ }
+ else if (defined('DEBUG_EXTRA'))
+ {
+ $this->sql_report('fromcache', $query);
+ }
+ }
+ else
+ {
+ return false;
+ }
+
+ return ($this->query_result) ? $this->query_result : false;
+ }
+
+ function sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0) {
+ if ($query != '') {
+ $this->query_result = false;
+
+ // only limit the number of rows if $total is greater than 0
+ if ($total > 0)
+ $query .= "\n LIMIT " . ((!empty($offset)) ? $offset . ', ' . $total : $total);
+
+ return $this->sql_query($query, $cache_ttl);
+ } else {
+ return false;
+ }
+ }
+
+ // Idea for this from Ikonboard
+ function sql_build_array($query, $assoc_ary = false)
+ {
+ if (!is_array($assoc_ary))
+ {
+ return false;
+ }
+
+ $fields = array();
+ $values = array();
+ if ($query == 'INSERT')
+ {
+ foreach ($assoc_ary as $key => $var)
+ {
+ $fields[] = $key;
+
+ if (is_null($var))
+ {
+ $values[] = 'NULL';
+ }
+ elseif (is_string($var))
+ {
+ $values[] = "'" . $this->sql_escape($var) . "'";
+ }
+ else
+ {
+ $values[] = (is_bool($var)) ? intval($var) : $var;
+ }
+ }
+
+ $query = ' (' . implode(', ', $fields) . ') VALUES (' . implode(', ', $values) . ')';
+ }
+ else if ($query == 'UPDATE' || $query == 'SELECT')
+ {
+ $values = array();
+ foreach ($assoc_ary as $key => $var)
+ {
+ if (is_null($var))
+ {
+ $values[] = "$key = NULL";
+ }
+ elseif (is_string($var))
+ {
+ $values[] = "$key = '" . $this->sql_escape($var) . "'";
+ }
+ else
+ {
+ $values[] = (is_bool($var)) ? "$key = " . intval($var) : "$key = $var";
+ }
+ }
+ $query = implode(($query == 'UPDATE') ? ', ' : ' AND ', $values);
+ }
+
+ return $query;
+ }
+
+ // Other query methods
+ //
+ // NOTE :: Want to remove _ALL_ reliance on sql_numrows from core code ...
+ // don't want this here by a middle Milestone
+ function sql_numrows($query_id = false)
+ {
+ if (!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+
+ return ($query_id) ? @mysql_num_rows($query_id) : false;
+ }
+
+ function sql_affectedrows()
+ {
+ return ($this->db_connect_id) ? @mysql_affected_rows($this->db_connect_id) : false;
+ }
+
+ function sql_fetchrow($query_id = false)
+ {
+ global $cache;
+
+ if (!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+
+ if (isset($cache->sql_rowset[$query_id]))
+ {
+ return $cache->sql_fetchrow($query_id);
+ }
+
+ return ($query_id) ? @mysql_fetch_assoc($query_id) : false;
+ }
+
+ function sql_fetchrowset($query_id = false)
+ {
+ if (!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+
+ if ($query_id)
+ {
+ unset($this->rowset[$query_id]);
+ unset($this->row[$query_id]);
+
+ $result = array();
+ while ($this->rowset[$query_id] = $this->sql_fetchrow($query_id))
+ {
+ $result[] = $this->rowset[$query_id];
+ }
+ return $result;
+ }
+
+ return false;
+ }
+
+ function sql_fetchfield($field, $rownum = -1, $query_id = false)
+ {
+ if (!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+
+ if ($query_id)
+ {
+ if ($rownum > -1)
+ {
+ $result = @mysql_result($query_id, $rownum, $field);
+ }
+ else
+ {
+ if (empty($this->row[$query_id]) && empty($this->rowset[$query_id]))
+ {
+ if ($this->sql_fetchrow($query_id))
+ {
+ $result = $this->row[$query_id][$field];
+ }
+ }
+ else
+ {
+ if ($this->rowset[$query_id])
+ {
+ $result = $this->rowset[$query_id][$field];
+ }
+ elseif ($this->row[$query_id])
+ {
+ $result = $this->row[$query_id][$field];
+ }
+ }
+ }
+ return $result;
+ }
+ return false;
+ }
+
+ function sql_rowseek($rownum, $query_id = false)
+ {
+ if (!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+
+ return ($query_id) ? @mysql_data_seek($query_id, $rownum) : false;
+ }
+
+ function sql_nextid()
+ {
+ return ($this->db_connect_id) ? @mysql_insert_id($this->db_connect_id) : false;
+ }
+
+ function sql_freeresult($query_id = false)
+ {
+ if (!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+
+ if (isset($this->open_queries[(int) $query_id]))
+ {
+ unset($this->open_queries[(int) $query_id]);
+ return @mysql_free_result($query_id);
+ }
+
+ return false;
+ }
+
+ function sql_escape($msg) {
+ if (function_exists('mysql_real_escape_string')) {
+ return @mysql_real_escape_string($msg, $this->db_connect_id);
+ } else {
+ return mysql_escape_string($msg);
+ }
+ }
+
+ function sql_error($sql = '')
+ {
+ if (!$this->return_on_error)
+ {
+ $this_page = (isset($_SERVER['PHP_SELF']) && !empty($_SERVER['PHP_SELF'])) ? $_SERVER['PHP_SELF'] : $_ENV['PHP_SELF'];
+ $this_page .= '&' . ((isset($_SERVER['QUERY_STRING']) && !empty($_SERVER['QUERY_STRING'])) ? $_SERVER['QUERY_STRING'] : (isset($_ENV['QUERY_STRING']) ? $_ENV['QUERY_STRING'] : ''));
+
+ $message = '<u>SQL ERROR</u> [ ' . SQL_LAYER . ' ]<br /><br />' . @mysql_error() . '<br /><br /><u>CALLING PAGE</u><br /><br />' . htmlspecialchars($this_page) . (($sql != '') ? '<br /><br /><u>SQL</u><br /><br />' . $sql : '') . '<br />';
+
+ if ($this->transaction)
+ {
+ $this->sql_transaction('rollback');
+ }
+
+ trigger_error($message, E_USER_ERROR);
+ }
+
+ $result = array(
+ 'message' => @mysql_error(),
+ 'code' => @mysql_errno()
+ );
+
+ return $result;
+ }
+
+ function sql_report($mode, $query = '')
+ {
+ if (empty($_GET['explain']))
+ {
+ return;
+ }
+
+ global $db, $cache, $starttime, $phpbb_root_path;
+ static $curtime, $query_hold, $html_hold;
+ static $sql_report = '';
+ static $cache_num_queries = 0;
+
+ if (!$query && !empty($query_hold))
+ {
+ $query = $query_hold;
+ }
+
+ switch ($mode)
+ {
+ case 'display':
+ if (!empty($cache))
+ {
+ $cache->unload();
+ }
+ $db->sql_close();
+
+ $mtime = explode(' ', microtime());
+ $totaltime = $mtime[0] + $mtime[1] - $starttime;
+
+ echo '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><meta http-equiv="Content-Type" content="text/html; charset=iso-8869-1"><meta http-equiv="Content-Style-Type" content="text/css"><link rel="stylesheet" href="' . $phpbb_root_path . 'adm/subSilver.css" type="text/css"><style type="text/css">' . "\n";
+ echo 'th { background-image: url(\'' . $phpbb_root_path . 'adm/images/cellpic3.gif\') }' . "\n";
+ echo 'td.cat { background-image: url(\'' . $phpbb_root_path . 'adm/images/cellpic1.gif\') }' . "\n";
+ echo '</style><title>' . $msg_title . '</title></head><body>';
+ echo '<table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td><a href="' . htmlspecialchars(preg_replace('/&explain=([^&]*)/', '', $_SERVER['REQUEST_URI'])) . '"><img src="' . $phpbb_root_path . 'adm/images/header_left.jpg" width="200" height="60" alt="phpBB Logo" title="phpBB Logo" border="0"/></a></td><td width="100%" background="' . $phpbb_root_path . 'adm/images/header_bg.jpg" height="60" align="right" nowrap="nowrap"><span class="maintitle">SQL Report</span> &nbsp; &nbsp; &nbsp;</td></tr></table><br clear="all"/><table width="95%" cellspacing="1" cellpadding="4" border="0" align="center"><tr><td height="40" align="center" valign="middle"><b>Page generated in ' . round($totaltime, 4) . " seconds with {$this->num_queries} queries" . (($cache_num_queries) ? " + $cache_num_queries " . (($cache_num_queries == 1) ? 'query' : 'queries') . ' returning data from cache' : '') . '</b></td></tr><tr><td align="center" nowrap="nowrap">Time spent on MySQL queries: <b>' . round($this->sql_time, 5) . 's</b> | Time spent on PHP: <b>' . round($totaltime - $this->sql_time, 5) . 's</b></td></tr></table><table width="95%" cellspacing="1" cellpadding="4" border="0" align="center"><tr><td>';
+ echo $sql_report;
+ echo '</td></tr></table><br /></body></html>';
+ exit;
+ break;
+
+ case 'start':
+ $query_hold = $query;
+ $html_hold = '';
+
+ $explain_query = $query;
+ if (preg_match('/UPDATE ([a-z0-9_]+).*?WHERE(.*)/s', $query, $m))
+ {
+ $explain_query = 'SELECT * FROM ' . $m[1] . ' WHERE ' . $m[2];
+ }
+ elseif (preg_match('/DELETE FROM ([a-z0-9_]+).*?WHERE(.*)/s', $query, $m))
+ {
+ $explain_query = 'SELECT * FROM ' . $m[1] . ' WHERE ' . $m[2];
+ }
+
+ if (preg_match('/^SELECT/', $explain_query))
+ {
+ $html_table = FALSE;
+
+ if ($result = mysql_query("EXPLAIN $explain_query", $this->db_connect_id))
+ {
+ while ($row = mysql_fetch_assoc($result))
+ {
+ if (!$html_table && sizeof($row))
+ {
+ $html_table = TRUE;
+ $html_hold .= '<table class="bg" width="100%" cellspacing="1" cellpadding="4" border="0" align="center"><tr>';
+
+ foreach (array_keys($row) as $val)
+ {
+ $html_hold .= '<th nowrap="nowrap">' . (($val) ? ucwords(str_replace('_', ' ', $val)) : '&nbsp;') . '</th>';
+ }
+ $html_hold .= '</tr>';
+ }
+ $html_hold .= '<tr>';
+
+ $class = 'row1';
+ foreach (array_values($row) as $val)
+ {
+ $class = ($class == 'row1') ? 'row2' : 'row1';
+ $html_hold .= '<td class="' . $class . '">' . (($val) ? $val : '&nbsp;') . '</td>';
+ }
+ $html_hold .= '</tr>';
+ }
+ }
+
+ if ($html_table)
+ {
+ $html_hold .= '</table>';
+ }
+ }
+
+ $curtime = explode(' ', microtime());
+ $curtime = $curtime[0] + $curtime[1];
+ break;
+
+ case 'fromcache':
+ $endtime = explode(' ', microtime());
+ $endtime = $endtime[0] + $endtime[1];
+
+ $result = mysql_query($query, $this->db_connect_id);
+ while ($void = mysql_fetch_assoc($result))
+ {
+ // Take the time spent on parsing rows into account
+ }
+ $splittime = explode(' ', microtime());
+ $splittime = $splittime[0] + $splittime[1];
+
+ $time_cache = $endtime - $curtime;
+ $time_db = $splittime - $endtime;
+ $color = ($time_db > $time_cache) ? 'green' : 'red';
+
+ $sql_report .= '<hr width="100%"/><br /><table class="bg" width="100%" cellspacing="1" cellpadding="4" border="0"><tr><th>Query results obtained from the cache</th></tr><tr><td class="row1"><textarea style="font-family:\'Courier New\',monospace;width:100%" rows="5">' . preg_replace('/\t(AND|OR)(\W)/', "\$1\$2", htmlspecialchars(preg_replace('/[\s]*[\n\r\t]+[\n\r\s\t]*/', "\n", $query))) . '</textarea></td></tr></table><p align="center">';
+
+ $sql_report .= 'Before: ' . sprintf('%.5f', $curtime - $starttime) . 's | After: ' . sprintf('%.5f', $endtime - $starttime) . 's | Elapsed [cache]: <b style="color: ' . $color . '">' . sprintf('%.5f', ($time_cache)) . 's</b> | Elapsed [db]: <b>' . sprintf('%.5f', $time_db) . 's</b></p>';
+
+ // Pad the start time to not interfere with page timing
+ $starttime += $time_db;
+
+ mysql_free_result($result);
+ $cache_num_queries++;
+ break;
+
+ case 'stop':
+ $endtime = explode(' ', microtime());
+ $endtime = $endtime[0] + $endtime[1];
+
+ $sql_report .= '<hr width="100%"/><br /><table class="bg" width="100%" cellspacing="1" cellpadding="4" border="0"><tr><th>Query #' . $this->num_queries . '</th></tr><tr><td class="row1"><textarea style="font-family:\'Courier New\',monospace;width:100%" rows="5">' . preg_replace('/\t(AND|OR)(\W)/', "\$1\$2", htmlspecialchars(preg_replace('/[\s]*[\n\r\t]+[\n\r\s\t]*/', "\n", $query))) . '</textarea></td></tr></table> ' . $html_hold . '<p align="center">';
+
+ if ($this->query_result)
+ {
+ if (preg_match('/^(UPDATE|DELETE|REPLACE)/', $query))
+ {
+ $sql_report .= "Affected rows: <b>" . $this->sql_affectedrows($this->query_result) . '</b> | ';
+ }
+ $sql_report .= 'Before: ' . sprintf('%.5f', $curtime - $starttime) . 's | After: ' . sprintf('%.5f', $endtime - $starttime) . 's | Elapsed: <b>' . sprintf('%.5f', $endtime - $curtime) . 's</b>';
+ }
+ else
+ {
+ $error = $this->sql_error();
+ $sql_report .= '<b style="color: red">FAILED</b> - MySQL Error ' . $error['code'] . ': ' . htmlspecialchars($error['message']);
+ }
+
+ $sql_report .= '</p>';
+
+ $this->sql_time += $endtime - $curtime;
+ break;
+ }
+ }
+} // class sql_db
+
+} // if ... define
+
+?> \ No newline at end of file
diff --git a/includes/db/mysql4.php b/includes/db/mysql4.php
new file mode 100644
index 0000000..0639518
--- /dev/null
+++ b/includes/db/mysql4.php
@@ -0,0 +1,552 @@
+<?php
+/**
+*
+* @package dbal_mysql4
+* @version $Id: mysql4.php,v 1.4 2006/02/10 01:30:19 scronide Exp $
+* @copyright (c) 2005 phpBB Group
+* @license http://opensource.org/licenses/gpl-license.php GNU Public License
+*
+*/
+
+/**
+* @ignore
+*/
+if (!defined('SQL_LAYER'))
+{
+
+define('SQL_LAYER', 'mysql4');
+
+/**
+* @package dbal_mysql4
+* MySQL4 Database Abstraction Layer
+* Minimum Requirement is 4.0+/4.1+
+*/
+class sql_db
+{
+ var $db_connect_id;
+ var $query_result;
+ var $return_on_error = false;
+ var $transaction = false;
+ var $sql_time = 0;
+ var $num_queries = 0;
+ var $open_queries = array();
+
+ function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false)
+ {
+ $this->persistency = $persistency;
+ $this->user = $sqluser;
+ $this->server = $sqlserver . (($port) ? ':' . $port : '');
+ $this->dbname = $database;
+
+ $this->db_connect_id = ($this->persistency) ? @mysql_pconnect($this->server, $this->user, $sqlpassword) : @mysql_connect($this->server, $this->user, $sqlpassword);
+
+ if ($this->db_connect_id && $this->dbname != '')
+ {
+ if (@mysql_select_db($this->dbname))
+ {
+ return $this->db_connect_id;
+ }
+ }
+
+ return $this->sql_error('');
+ }
+
+ //
+ // Other base methods
+ //
+ function sql_close()
+ {
+ if (!$this->db_connect_id)
+ {
+ return false;
+ }
+
+ if (sizeof($this->open_queries))
+ {
+ foreach ($this->open_queries as $i_query_id => $query_id)
+ {
+ @mysql_free_result($query_id);
+ }
+ }
+
+ return @mysql_close($this->db_connect_id);
+ }
+
+ function sql_return_on_error($fail = false)
+ {
+ $this->return_on_error = $fail;
+ }
+
+ function sql_num_queries()
+ {
+ return $this->num_queries;
+ }
+
+ function sql_transaction($status = 'begin')
+ {
+ switch ($status)
+ {
+ case 'begin':
+ $result = @mysql_query('BEGIN', $this->db_connect_id);
+ $this->transaction = true;
+ break;
+
+ case 'commit':
+ $result = @mysql_query('COMMIT', $this->db_connect_id);
+ $this->transaction = false;
+
+ if (!$result)
+ {
+ @mysql_query('ROLLBACK', $this->db_connect_id);
+ }
+ break;
+
+ case 'rollback':
+ $result = @mysql_query('ROLLBACK', $this->db_connect_id);
+ $this->transaction = false;
+ break;
+
+ default:
+ $result = true;
+ }
+
+ return $result;
+ }
+
+ // Base query method
+ function sql_query($query = '', $cache_ttl = 0)
+ {
+ if ($query != '')
+ {
+ global $cache;
+
+ // EXPLAIN only in extra debug mode
+ if (defined('DEBUG_EXTRA'))
+ {
+ $this->sql_report('start', $query);
+ }
+
+ $this->query_result = ($cache_ttl && method_exists($cache, 'sql_load')) ? $cache->sql_load($query) : false;
+
+ if (!$this->query_result)
+ {
+ $this->num_queries++;
+
+ if (($this->query_result = @mysql_query($query, $this->db_connect_id)) === false)
+ {
+ $this->sql_error($query);
+ }
+
+ if (defined('DEBUG_EXTRA'))
+ {
+ $this->sql_report('stop', $query);
+ }
+
+ if ($cache_ttl && method_exists($cache, 'sql_save'))
+ {
+ $this->open_queries[(int) $this->query_result] = $this->query_result;
+ $cache->sql_save($query, $this->query_result, $cache_ttl);
+ // mysql_free_result called within sql_save()
+ }
+ else if (strpos($query, 'SELECT') !== false && $this->query_result)
+ {
+ $this->open_queries[(int) $this->query_result] = $this->query_result;
+ }
+ }
+ else if (defined('DEBUG_EXTRA'))
+ {
+ $this->sql_report('fromcache', $query);
+ }
+ }
+ else
+ {
+ return false;
+ }
+
+ return ($this->query_result) ? $this->query_result : false;
+ }
+
+ function sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0) {
+ if ($query != '') {
+ $this->query_result = false;
+
+ // only limit the number of rows if $total is greater than 0
+ if ($total > 0)
+ $query .= "\n LIMIT " . ((!empty($offset)) ? $offset . ', ' . $total : $total);
+
+ return $this->sql_query($query, $cache_ttl);
+ } else {
+ return false;
+ }
+ }
+
+ // Idea for this from Ikonboard
+ function sql_build_array($query, $assoc_ary = false)
+ {
+ if (!is_array($assoc_ary))
+ {
+ return false;
+ }
+
+ $fields = array();
+ $values = array();
+ if ($query == 'INSERT')
+ {
+ foreach ($assoc_ary as $key => $var)
+ {
+ $fields[] = $key;
+
+ if (is_null($var))
+ {
+ $values[] = 'NULL';
+ }
+ elseif (is_string($var))
+ {
+ $values[] = "'" . $this->sql_escape($var) . "'";
+ }
+ else
+ {
+ $values[] = (is_bool($var)) ? intval($var) : $var;
+ }
+ }
+
+ $query = ' (' . implode(', ', $fields) . ') VALUES (' . implode(', ', $values) . ')';
+ }
+ else if ($query == 'UPDATE' || $query == 'SELECT')
+ {
+ $values = array();
+ foreach ($assoc_ary as $key => $var)
+ {
+ if (is_null($var))
+ {
+ $values[] = "$key = NULL";
+ }
+ elseif (is_string($var))
+ {
+ $values[] = "$key = '" . $this->sql_escape($var) . "'";
+ }
+ else
+ {
+ $values[] = (is_bool($var)) ? "$key = " . intval($var) : "$key = $var";
+ }
+ }
+ $query = implode(($query == 'UPDATE') ? ', ' : ' AND ', $values);
+ }
+
+ return $query;
+ }
+
+ // Other query methods
+ //
+ // NOTE :: Want to remove _ALL_ reliance on sql_numrows from core code ...
+ // don't want this here by a middle Milestone
+ function sql_numrows($query_id = false)
+ {
+ if (!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+
+ return ($query_id) ? @mysql_num_rows($query_id) : false;
+ }
+
+ function sql_affectedrows()
+ {
+ return ($this->db_connect_id) ? @mysql_affected_rows($this->db_connect_id) : false;
+ }
+
+ function sql_fetchrow($query_id = false)
+ {
+ global $cache;
+
+ if (!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+
+ if (isset($cache->sql_rowset[$query_id]))
+ {
+ return $cache->sql_fetchrow($query_id);
+ }
+
+ return ($query_id) ? @mysql_fetch_assoc($query_id) : false;
+ }
+
+ function sql_fetchrowset($query_id = false)
+ {
+ if (!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+
+ if ($query_id)
+ {
+ unset($this->rowset[$query_id]);
+ unset($this->row[$query_id]);
+
+ $result = array();
+ while ($this->rowset[$query_id] = $this->sql_fetchrow($query_id))
+ {
+ $result[] = $this->rowset[$query_id];
+ }
+ return $result;
+ }
+
+ return false;
+ }
+
+ function sql_fetchfield($field, $rownum = -1, $query_id = false)
+ {
+ if (!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+
+ if ($query_id)
+ {
+ if ($rownum > -1)
+ {
+ $result = @mysql_result($query_id, $rownum, $field);
+ }
+ else
+ {
+ if (empty($this->row[$query_id]) && empty($this->rowset[$query_id]))
+ {
+ if ($this->sql_fetchrow($query_id))
+ {
+ $result = $this->row[$query_id][$field];
+ }
+ }
+ else
+ {
+ if ($this->rowset[$query_id])
+ {
+ $result = $this->rowset[$query_id][$field];
+ }
+ elseif ($this->row[$query_id])
+ {
+ $result = $this->row[$query_id][$field];
+ }
+ }
+ }
+ return $result;
+ }
+ return false;
+ }
+
+ function sql_rowseek($rownum, $query_id = false)
+ {
+ if (!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+
+ return ($query_id) ? @mysql_data_seek($query_id, $rownum) : false;
+ }
+
+ function sql_nextid()
+ {
+ return ($this->db_connect_id) ? @mysql_insert_id($this->db_connect_id) : false;
+ }
+
+ function sql_freeresult($query_id = false)
+ {
+ if (!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+
+ if (isset($this->open_queries[(int) $query_id]))
+ {
+ unset($this->open_queries[(int) $query_id]);
+ return @mysql_free_result($query_id);
+ }
+
+ return false;
+ }
+
+ function sql_escape($msg) {
+ if (function_exists('mysql_real_escape_string')) {
+ return @mysql_real_escape_string($msg, $this->db_connect_id);
+ } else {
+ return mysql_escape_string($msg);
+ }
+ }
+
+ function sql_error($sql = '')
+ {
+ if (!$this->return_on_error)
+ {
+ $this_page = (isset($_SERVER['PHP_SELF']) && !empty($_SERVER['PHP_SELF'])) ? $_SERVER['PHP_SELF'] : $_ENV['PHP_SELF'];
+ $this_page .= '&' . ((isset($_SERVER['QUERY_STRING']) && !empty($_SERVER['QUERY_STRING'])) ? $_SERVER['QUERY_STRING'] : (isset($_ENV['QUERY_STRING']) ? $_ENV['QUERY_STRING'] : ''));
+
+ $message = '<u>SQL ERROR</u> [ ' . SQL_LAYER . ' ]<br /><br />' . @mysql_error() . '<br /><br /><u>CALLING PAGE</u><br /><br />' . htmlspecialchars($this_page) . (($sql != '') ? '<br /><br /><u>SQL</u><br /><br />' . $sql : '') . '<br />';
+
+ if ($this->transaction)
+ {
+ $this->sql_transaction('rollback');
+ }
+
+ trigger_error($message, E_USER_ERROR);
+ }
+
+ $result = array(
+ 'message' => @mysql_error(),
+ 'code' => @mysql_errno()
+ );
+
+ return $result;
+ }
+
+ function sql_report($mode, $query = '')
+ {
+ if (empty($_GET['explain']))
+ {
+ return;
+ }
+
+ global $db, $cache, $starttime, $phpbb_root_path;
+ static $curtime, $query_hold, $html_hold;
+ static $sql_report = '';
+ static $cache_num_queries = 0;
+
+ if (!$query && !empty($query_hold))
+ {
+ $query = $query_hold;
+ }
+
+ switch ($mode)
+ {
+ case 'display':
+ if (!empty($cache))
+ {
+ $cache->unload();
+ }
+ $db->sql_close();
+
+ $mtime = explode(' ', microtime());
+ $totaltime = $mtime[0] + $mtime[1] - $starttime;
+
+ echo '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><meta http-equiv="Content-Type" content="text/html; charset=iso-8869-1"><meta http-equiv="Content-Style-Type" content="text/css"><link rel="stylesheet" href="' . $phpbb_root_path . 'adm/subSilver.css" type="text/css"><style type="text/css">' . "\n";
+ echo 'th { background-image: url(\'' . $phpbb_root_path . 'adm/images/cellpic3.gif\') }' . "\n";
+ echo 'td.cat { background-image: url(\'' . $phpbb_root_path . 'adm/images/cellpic1.gif\') }' . "\n";
+ echo '</style><title>' . $msg_title . '</title></head><body>';
+ echo '<table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td><a href="' . htmlspecialchars(preg_replace('/&explain=([^&]*)/', '', $_SERVER['REQUEST_URI'])) . '"><img src="' . $phpbb_root_path . 'adm/images/header_left.jpg" width="200" height="60" alt="phpBB Logo" title="phpBB Logo" border="0"/></a></td><td width="100%" background="' . $phpbb_root_path . 'adm/images/header_bg.jpg" height="60" align="right" nowrap="nowrap"><span class="maintitle">SQL Report</span> &nbsp; &nbsp; &nbsp;</td></tr></table><br clear="all"/><table width="95%" cellspacing="1" cellpadding="4" border="0" align="center"><tr><td height="40" align="center" valign="middle"><b>Page generated in ' . round($totaltime, 4) . " seconds with {$this->num_queries} queries" . (($cache_num_queries) ? " + $cache_num_queries " . (($cache_num_queries == 1) ? 'query' : 'queries') . ' returning data from cache' : '') . '</b></td></tr><tr><td align="center" nowrap="nowrap">Time spent on MySQL queries: <b>' . round($this->sql_time, 5) . 's</b> | Time spent on PHP: <b>' . round($totaltime - $this->sql_time, 5) . 's</b></td></tr></table><table width="95%" cellspacing="1" cellpadding="4" border="0" align="center"><tr><td>';
+ echo $sql_report;
+ echo '</td></tr></table><br /></body></html>';
+ exit;
+ break;
+
+ case 'start':
+ $query_hold = $query;
+ $html_hold = '';
+
+ $explain_query = $query;
+ if (preg_match('/UPDATE ([a-z0-9_]+).*?WHERE(.*)/s', $query, $m))
+ {
+ $explain_query = 'SELECT * FROM ' . $m[1] . ' WHERE ' . $m[2];
+ }
+ elseif (preg_match('/DELETE FROM ([a-z0-9_]+).*?WHERE(.*)/s', $query, $m))
+ {
+ $explain_query = 'SELECT * FROM ' . $m[1] . ' WHERE ' . $m[2];
+ }
+
+ if (preg_match('/^SELECT/', $explain_query))
+ {
+ $html_table = FALSE;
+
+ if ($result = mysql_query("EXPLAIN $explain_query", $this->db_connect_id))
+ {
+ while ($row = mysql_fetch_assoc($result))
+ {
+ if (!$html_table && sizeof($row))
+ {
+ $html_table = TRUE;
+ $html_hold .= '<table class="bg" width="100%" cellspacing="1" cellpadding="4" border="0" align="center"><tr>';
+
+ foreach (array_keys($row) as $val)
+ {
+ $html_hold .= '<th nowrap="nowrap">' . (($val) ? ucwords(str_replace('_', ' ', $val)) : '&nbsp;') . '</th>';
+ }
+ $html_hold .= '</tr>';
+ }
+ $html_hold .= '<tr>';
+
+ $class = 'row1';
+ foreach (array_values($row) as $val)
+ {
+ $class = ($class == 'row1') ? 'row2' : 'row1';
+ $html_hold .= '<td class="' . $class . '">' . (($val) ? $val : '&nbsp;') . '</td>';
+ }
+ $html_hold .= '</tr>';
+ }
+ }
+
+ if ($html_table)
+ {
+ $html_hold .= '</table>';
+ }
+ }
+
+ $curtime = explode(' ', microtime());
+ $curtime = $curtime[0] + $curtime[1];
+ break;
+
+ case 'fromcache':
+ $endtime = explode(' ', microtime());
+ $endtime = $endtime[0] + $endtime[1];
+
+ $result = mysql_query($query, $this->db_connect_id);
+ while ($void = mysql_fetch_assoc($result))
+ {
+ // Take the time spent on parsing rows into account
+ }
+ $splittime = explode(' ', microtime());
+ $splittime = $splittime[0] + $splittime[1];
+
+ $time_cache = $endtime - $curtime;
+ $time_db = $splittime - $endtime;
+ $color = ($time_db > $time_cache) ? 'green' : 'red';
+
+ $sql_report .= '<hr width="100%"/><br /><table class="bg" width="100%" cellspacing="1" cellpadding="4" border="0"><tr><th>Query results obtained from the cache</th></tr><tr><td class="row1"><textarea style="font-family:\'Courier New\',monospace;width:100%" rows="5">' . preg_replace('/\t(AND|OR)(\W)/', "\$1\$2", htmlspecialchars(preg_replace('/[\s]*[\n\r\t]+[\n\r\s\t]*/', "\n", $query))) . '</textarea></td></tr></table><p align="center">';
+
+ $sql_report .= 'Before: ' . sprintf('%.5f', $curtime - $starttime) . 's | After: ' . sprintf('%.5f', $endtime - $starttime) . 's | Elapsed [cache]: <b style="color: ' . $color . '">' . sprintf('%.5f', ($time_cache)) . 's</b> | Elapsed [db]: <b>' . sprintf('%.5f', $time_db) . 's</b></p>';
+
+ // Pad the start time to not interfere with page timing
+ $starttime += $time_db;
+
+ mysql_free_result($result);
+ $cache_num_queries++;
+ break;
+
+ case 'stop':
+ $endtime = explode(' ', microtime());
+ $endtime = $endtime[0] + $endtime[1];
+
+ $sql_report .= '<hr width="100%"/><br /><table class="bg" width="100%" cellspacing="1" cellpadding="4" border="0"><tr><th>Query #' . $this->num_queries . '</th></tr><tr><td class="row1"><textarea style="font-family:\'Courier New\',monospace;width:100%" rows="5">' . preg_replace('/\t(AND|OR)(\W)/', "\$1\$2", htmlspecialchars(preg_replace('/[\s]*[\n\r\t]+[\n\r\s\t]*/', "\n", $query))) . '</textarea></td></tr></table> ' . $html_hold . '<p align="center">';
+
+ if ($this->query_result)
+ {
+ if (preg_match('/^(UPDATE|DELETE|REPLACE)/', $query))
+ {
+ $sql_report .= "Affected rows: <b>" . $this->sql_affectedrows($this->query_result) . '</b> | ';
+ }
+ $sql_report .= 'Before: ' . sprintf('%.5f', $curtime - $starttime) . 's | After: ' . sprintf('%.5f', $endtime - $starttime) . 's | Elapsed: <b>' . sprintf('%.5f', $endtime - $curtime) . 's</b>';
+ }
+ else
+ {
+ $error = $this->sql_error();
+ $sql_report .= '<b style="color: red">FAILED</b> - MySQL Error ' . $error['code'] . ': ' . htmlspecialchars($error['message']);
+ }
+
+ $sql_report .= '</p>';
+
+ $this->sql_time += $endtime - $curtime;
+ break;
+ }
+ }
+} // class sql_db
+
+} // if ... define
+
+?> \ No newline at end of file
diff --git a/includes/db/mysqli.php b/includes/db/mysqli.php
new file mode 100644
index 0000000..fa643c2
--- /dev/null
+++ b/includes/db/mysqli.php
@@ -0,0 +1,566 @@
+<?php
+/**
+*
+* @package dbal_mysqli
+* @version $Id: mysqli.php,v 1.4 2006/02/10 01:30:19 scronide Exp $
+* @copyright (c) 2005 phpBB Group
+* @license http://opensource.org/licenses/gpl-license.php GNU Public License
+*
+*/
+
+/**
+* @ignore
+*/
+if (!defined('SQL_LAYER'))
+{
+
+define('SQL_LAYER', 'mysqli');
+
+/**
+* @package dbal_mysqli
+* MySQLi Database Abstraction Layer
+* Minimum Requirement is MySQL 4.1+ and the mysqli-extension
+*/
+class sql_db
+{
+ var $db_connect_id;
+ var $query_result;
+ var $return_on_error = false;
+ var $transaction = false;
+ var $sql_time = 0;
+ var $num_queries = 0;
+ var $open_queries = array();
+
+ var $indexed = 0;
+
+ function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false)
+ {
+ $this->persistency = $persistency;
+ $this->user = $sqluser;
+ $this->server = $sqlserver . (($port) ? ':' . $port : '');
+ $this->dbname = $database;
+
+ $this->db_connect_id = ($this->persistency) ? @mysqli_pconnect($this->server, $this->user, $sqlpassword) : @mysqli_connect($this->server, $this->user, $sqlpassword);
+
+ if ($this->db_connect_id && $this->dbname != '')
+ {
+ if (@mysqli_select_db($this->db_connect_id, $this->dbname))
+ {
+ return $this->db_connect_id;
+ }
+ }
+
+ return $this->sql_error('');
+ }
+
+ //
+ // Other base methods
+ //
+ function sql_close()
+ {
+ if (!$this->db_connect_id)
+ {
+ return false;
+ }
+
+ if ($this->transaction)
+ {
+ @mysqli_commit($this->db_connect_id);
+ }
+
+ return @mysqli_close($this->db_connect_id);
+ }
+
+ function sql_return_on_error($fail = false)
+ {
+ $this->return_on_error = $fail;
+ }
+
+ function sql_num_queries()
+ {
+ return $this->num_queries;
+ }
+
+ function sql_transaction($status = 'begin')
+ {
+ switch ($status)
+ {
+ case 'begin':
+ $result = @mysqli_autocommit($this->db_connect_id, false);
+ $this->transaction = true;
+ break;
+
+ case 'commit':
+ $result = @mysqli_commit($this->db_connect_id);
+ @mysqli_autocommit($this->db_connect_id, true);
+ $this->transaction = false;
+
+ if (!$result)
+ {
+ @mysqli_rollback($this->db_connect_id);
+ @mysqli_autocommit($this->db_connect_id, true);
+ }
+ break;
+
+ case 'rollback':
+ $result = @mysqli_rollback($this->db_connect_id);
+ @mysqli_autocommit($this->db_connect_id, true);
+ $this->transaction = false;
+ break;
+
+ default:
+ $result = true;
+ }
+
+ return $result;
+ }
+
+ // Base query method
+ function sql_query($query = '', $cache_ttl = 0)
+ {
+ if ($query != '')
+ {
+ global $cache;
+
+ // EXPLAIN only in extra debug mode
+ if (defined('DEBUG_EXTRA'))
+ {
+ $this->sql_report('start', $query);
+ }
+
+ $this->query_result = ($cache_ttl && method_exists($cache, 'sql_load')) ? $cache->sql_load($query) : false;
+
+ if (!$this->query_result)
+ {
+ $this->num_queries++;
+
+ if (($this->query_result = @mysqli_query($this->db_connect_id, $query)) === false)
+ {
+ $this->sql_error($query);
+ }
+
+ if (is_object($this->query_result))
+ {
+ $this->query_result->cur_index = $this->indexed++;
+ }
+
+ if (defined('DEBUG_EXTRA'))
+ {
+ $this->sql_report('stop', $query);
+ }
+
+ if ($cache_ttl && method_exists($cache, 'sql_save'))
+ {
+ $cache->sql_save($query, $this->query_result, $cache_ttl);
+ }
+ }
+ else if (defined('DEBUG_EXTRA'))
+ {
+ $this->sql_report('fromcache', $query);
+ }
+ }
+ else
+ {
+ return false;
+ }
+
+ return ($this->query_result) ? $this->query_result : false;
+ }
+
+ function sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0) {
+ if ($query != '') {
+ $this->query_result = false;
+
+ // only limit the number of rows if $total is greater than 0
+ if ($total > 0)
+ $query .= "\n LIMIT " . ((!empty($offset)) ? $offset . ', ' . $total : $total);
+
+ return $this->sql_query($query, $cache_ttl);
+ } else {
+ return false;
+ }
+ }
+
+ // Idea for this from Ikonboard
+ function sql_build_array($query, $assoc_ary = false)
+ {
+ if (!is_array($assoc_ary))
+ {
+ return false;
+ }
+
+ $fields = array();
+ $values = array();
+ if ($query == 'INSERT')
+ {
+ foreach ($assoc_ary as $key => $var)
+ {
+ $fields[] = $key;
+
+ if (is_null($var))
+ {
+ $values[] = 'NULL';
+ }
+ elseif (is_string($var))
+ {
+ $values[] = "'" . $this->sql_escape($var) . "'";
+ }
+ else
+ {
+ $values[] = (is_bool($var)) ? intval($var) : $var;
+ }
+ }
+
+ $query = ' (' . implode(', ', $fields) . ') VALUES (' . implode(', ', $values) . ')';
+ }
+ else if ($query == 'UPDATE' || $query == 'SELECT')
+ {
+ $values = array();
+ foreach ($assoc_ary as $key => $var)
+ {
+ if (is_null($var))
+ {
+ $values[] = "$key = NULL";
+ }
+ elseif (is_string($var))
+ {
+ $values[] = "$key = '" . $this->sql_escape($var) . "'";
+ }
+ else
+ {
+ $values[] = (is_bool($var)) ? "$key = " . intval($var) : "$key = $var";
+ }
+ }
+ $query = implode(($query == 'UPDATE') ? ', ' : ' AND ', $values);
+ }
+
+ return $query;
+ }
+
+ // Other query methods
+ //
+ // NOTE :: Want to remove _ALL_ reliance on sql_numrows from core code ...
+ // don't want this here by a middle Milestone
+ function sql_numrows($query_id = false)
+ {
+ if (!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+
+ return ($query_id) ? @mysqli_num_rows($query_id) : false;
+ }
+
+ function sql_affectedrows()
+ {
+ return ($this->db_connect_id) ? @mysqli_affected_rows($this->db_connect_id) : false;
+ }
+
+ function sql_fetchrow($query_id = false)
+ {
+ global $cache;
+
+ if (!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+
+ if (!is_object($query_id) && isset($cache->sql_rowset[$query_id]))
+ {
+ return $cache->sql_fetchrow($query_id);
+ }
+
+ return ($query_id) ? @mysqli_fetch_assoc($query_id) : false;
+ }
+
+ function sql_fetchrowset($query_id = false)
+ {
+ if (!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+
+ if ($query_id)
+ {
+ $cur_index = (is_object($query_id)) ? $query_id->cur_index : $query_id;
+
+ unset($this->rowset[$cur_index]);
+ unset($this->row[$cur_index]);
+
+ $result = array();
+ while ($this->rowset[$cur_index] = $this->sql_fetchrow($query_id))
+ {
+ $result[] = $this->rowset[$cur_index];
+ }
+ return $result;
+ }
+
+ return false;
+ }
+
+ function sql_fetchfield($field, $rownum = -1, $query_id = false)
+ {
+ if (!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+
+ if ($query_id)
+ {
+ if ($rownum > -1)
+ {
+ @mysqli_data_seek($query_id, $rownum);
+ $row = @mysqli_fetch_assoc($query_id);
+ $result = isset($row[$field]) ? $row[$field] : false;
+ }
+ else
+ {
+ $cur_index = (is_object($query_id)) ? $query_id->cur_index : $query_id;
+
+ if (empty($this->row[$cur_index]) && empty($this->rowset[$cur_index]))
+ {
+ if ($this->row[$cur_index] = $this->sql_fetchrow($query_id))
+ {
+ $result = $this->row[$cur_index][$field];
+ }
+ }
+ else
+ {
+ if ($this->rowset[$cur_index])
+ {
+ $result = $this->rowset[$cur_index][$field];
+ }
+ elseif ($this->row[$cur_index])
+ {
+ $result = $this->row[$cur_index][$field];
+ }
+ }
+ }
+ return $result;
+ }
+ return false;
+ }
+
+ function sql_rowseek($rownum, $query_id = false)
+ {
+ if (!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+
+ return ($query_id) ? @mysqli_data_seek($query_id, $rownum) : false;
+ }
+
+ function sql_nextid()
+ {
+ return ($this->db_connect_id) ? @mysqli_insert_id($this->db_connect_id) : false;
+ }
+
+ function sql_freeresult($query_id = false)
+ {
+ if (!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+
+ $cur_index = (is_object($query_id)) ? $query_id->cur_index : $query_id;
+
+ unset($this->rowset[$cur_index]);
+ unset($this->row[$cur_index]);
+
+ if (is_object($query_id))
+ {
+ $this->indexed--;
+ return @mysqli_free_result($query_id);
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ function sql_escape($msg) {
+ if (function_exists('mysql_real_escape_string')) {
+ return @mysql_real_escape_string($msg, $this->db_connect_id);
+ } else {
+ return mysql_escape_string($msg);
+ }
+ }
+
+ function sql_error($sql = '')
+ {
+ if (!$this->return_on_error)
+ {
+ $this_page = (isset($_SERVER['PHP_SELF']) && !empty($_SERVER['PHP_SELF'])) ? $_SERVER['PHP_SELF'] : $_ENV['PHP_SELF'];
+ $this_page .= '&' . ((isset($_SERVER['QUERY_STRING']) && !empty($_SERVER['QUERY_STRING'])) ? $_SERVER['QUERY_STRING'] : (isset($_ENV['QUERY_STRING']) ? $_ENV['QUERY_STRING'] : ''));
+
+ $message = '<u>SQL ERROR</u> [ ' . SQL_LAYER . ' ]<br /><br />' . @mysqli_error($this->db_connect_id) . '<br /><br /><u>CALLING PAGE</u><br /><br />' . htmlspecialchars($this_page) . (($sql != '') ? '<br /><br /><u>SQL</u><br /><br />' . $sql : '') . '<br />';
+
+ if ($this->transaction)
+ {
+ $this->sql_transaction('rollback');
+ }
+
+ trigger_error($message, E_USER_ERROR);
+ }
+
+ $result = array(
+ 'message' => @mysqli_error($this->db_connect_id),
+ 'code' => @mysqli_errno($this->db_connect_id)
+ );
+
+ return $result;
+ }
+
+ function sql_report($mode, $query = '')
+ {
+ if (empty($_GET['explain']))
+ {
+ return;
+ }
+
+ global $db, $cache, $starttime, $phpbb_root_path;
+ static $curtime, $query_hold, $html_hold;
+ static $sql_report = '';
+ static $cache_num_queries = 0;
+
+ if (!$query && !empty($query_hold))
+ {
+ $query = $query_hold;
+ }
+
+ switch ($mode)
+ {
+ case 'display':
+ if (!empty($cache))
+ {
+ $cache->unload();
+ }
+ $db->sql_close();
+
+ $mtime = explode(' ', microtime());
+ $totaltime = $mtime[0] + $mtime[1] - $starttime;
+
+ echo '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><meta http-equiv="Content-Type" content="text/html; charset=iso-8869-1"><meta http-equiv="Content-Style-Type" content="text/css"><link rel="stylesheet" href="' . $phpbb_root_path . 'adm/subSilver.css" type="text/css"><style type="text/css">' . "\n";
+ echo 'th { background-image: url(\'' . $phpbb_root_path . 'adm/images/cellpic3.gif\') }' . "\n";
+ echo 'td.cat { background-image: url(\'' . $phpbb_root_path . 'adm/images/cellpic1.gif\') }' . "\n";
+ echo '</style><title>' . $msg_title . '</title></head><body>';
+ echo '<table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td><a href="' . htmlspecialchars(preg_replace('/&explain=([^&]*)/', '', $_SERVER['REQUEST_URI'])) . '"><img src="' . $phpbb_root_path . 'adm/images/header_left.jpg" width="200" height="60" alt="phpBB Logo" title="phpBB Logo" border="0"/></a></td><td width="100%" background="' . $phpbb_root_path . 'adm/images/header_bg.jpg" height="60" align="right" nowrap="nowrap"><span class="maintitle">SQL Report</span> &nbsp; &nbsp; &nbsp;</td></tr></table><br clear="all"/><table width="95%" cellspacing="1" cellpadding="4" border="0" align="center"><tr><td height="40" align="center" valign="middle"><b>Page generated in ' . round($totaltime, 4) . " seconds with {$this->num_queries} queries" . (($cache_num_queries) ? " + $cache_num_queries " . (($cache_num_queries == 1) ? 'query' : 'queries') . ' returning data from cache' : '') . '</b></td></tr><tr><td align="center" nowrap="nowrap">Time spent on MySQL queries: <b>' . round($this->sql_time, 5) . 's</b> | Time spent on PHP: <b>' . round($totaltime - $this->sql_time, 5) . 's</b></td></tr></table><table width="95%" cellspacing="1" cellpadding="4" border="0" align="center"><tr><td>';
+ echo $sql_report;
+ echo '</td></tr></table><br /></body></html>';
+ exit;
+ break;
+
+ case 'start':
+ $query_hold = $query;
+ $html_hold = '';
+
+ $explain_query = $query;
+ if (preg_match('/UPDATE ([a-z0-9_]+).*?WHERE(.*)/s', $query, $m))
+ {
+ $explain_query = 'SELECT * FROM ' . $m[1] . ' WHERE ' . $m[2];
+ }
+ elseif (preg_match('/DELETE FROM ([a-z0-9_]+).*?WHERE(.*)/s', $query, $m))
+ {
+ $explain_query = 'SELECT * FROM ' . $m[1] . ' WHERE ' . $m[2];
+ }
+
+ if (preg_match('/^SELECT/', $explain_query))
+ {
+ $html_table = FALSE;
+
+ if ($result = @mysqli_query($this->db_connect_id, "EXPLAIN $explain_query"))
+ {
+ while ($row = @mysqli_fetch_assoc($result))
+ {
+ if (!$html_table && sizeof($row))
+ {
+ $html_table = TRUE;
+ $html_hold .= '<table class="bg" width="100%" cellspacing="1" cellpadding="4" border="0" align="center"><tr>';
+
+ foreach (array_keys($row) as $val)
+ {
+ $html_hold .= '<th nowrap="nowrap">' . (($val) ? ucwords(str_replace('_', ' ', $val)) : '&nbsp;') . '</th>';
+ }
+ $html_hold .= '</tr>';
+ }
+ $html_hold .= '<tr>';
+
+ $class = 'row1';
+ foreach (array_values($row) as $val)
+ {
+ $class = ($class == 'row1') ? 'row2' : 'row1';
+ $html_hold .= '<td class="' . $class . '">' . (($val) ? $val : '&nbsp;') . '</td>';
+ }
+ $html_hold .= '</tr>';
+ }
+ }
+
+ if ($html_table)
+ {
+ $html_hold .= '</table>';
+ }
+ }
+
+ $curtime = explode(' ', microtime());
+ $curtime = $curtime[0] + $curtime[1];
+ break;
+
+ case 'fromcache':
+ $endtime = explode(' ', microtime());
+ $endtime = $endtime[0] + $endtime[1];
+
+ $result = @mysqli_query($this->db_connect_id, $query);
+ while ($void = @mysqli_fetch_assoc($result))
+ {
+ // Take the time spent on parsing rows into account
+ }
+ $splittime = explode(' ', microtime());
+ $splittime = $splittime[0] + $splittime[1];
+
+ $time_cache = $endtime - $curtime;
+ $time_db = $splittime - $endtime;
+ $color = ($time_db > $time_cache) ? 'green' : 'red';
+
+ $sql_report .= '<hr width="100%"/><br /><table class="bg" width="100%" cellspacing="1" cellpadding="4" border="0"><tr><th>Query results obtained from the cache</th></tr><tr><td class="row1"><textarea style="font-family:\'Courier New\',monospace;width:100%" rows="5">' . preg_replace('/\t(AND|OR)(\W)/', "\$1\$2", htmlspecialchars(preg_replace('/[\s]*[\n\r\t]+[\n\r\s\t]*/', "\n", $query))) . '</textarea></td></tr></table><p align="center">';
+
+ $sql_report .= 'Before: ' . sprintf('%.5f', $curtime - $starttime) . 's | After: ' . sprintf('%.5f', $endtime - $starttime) . 's | Elapsed [cache]: <b style="color: ' . $color . '">' . sprintf('%.5f', ($time_cache)) . 's</b> | Elapsed [db]: <b>' . sprintf('%.5f', $time_db) . 's</b></p>';
+
+ // Pad the start time to not interfere with page timing
+ $starttime += $time_db;
+
+ @mysqli_free_result($result);
+ $cache_num_queries++;
+ break;
+
+ case 'stop':
+ $endtime = explode(' ', microtime());
+ $endtime = $endtime[0] + $endtime[1];
+
+ $sql_report .= '<hr width="100%"/><br /><table class="bg" width="100%" cellspacing="1" cellpadding="4" border="0"><tr><th>Query #' . $this->num_queries . '</th></tr><tr><td class="row1"><textarea style="font-family:\'Courier New\',monospace;width:100%" rows="5">' . preg_replace('/\t(AND|OR)(\W)/', "\$1\$2", htmlspecialchars(preg_replace('/[\s]*[\n\r\t]+[\n\r\s\t]*/', "\n", $query))) . '</textarea></td></tr></table> ' . $html_hold . '<p align="center">';
+
+ if ($this->query_result)
+ {
+ if (preg_match('/^(UPDATE|DELETE|REPLACE)/', $query))
+ {
+ $sql_report .= "Affected rows: <b>" . $this->sql_affectedrows($this->query_result) . '</b> | ';
+ }
+ $sql_report .= 'Before: ' . sprintf('%.5f', $curtime - $starttime) . 's | After: ' . sprintf('%.5f', $endtime - $starttime) . 's | Elapsed: <b>' . sprintf('%.5f', $endtime - $curtime) . 's</b>';
+ }
+ else
+ {
+ $error = $this->sql_error();
+ $sql_report .= '<b style="color: red">FAILED</b> - MySQL Error ' . $error['code'] . ': ' . htmlspecialchars($error['message']);
+ }
+
+ $sql_report .= '</p>';
+
+ $this->sql_time += $endtime - $curtime;
+ break;
+ }
+ }
+} // class sql_db
+
+} // if ... define
+
+?> \ No newline at end of file
diff --git a/includes/db/oracle.php b/includes/db/oracle.php
new file mode 100644
index 0000000..7ef10e5
--- /dev/null
+++ b/includes/db/oracle.php
@@ -0,0 +1,468 @@
+<?php
+/**
+*
+* @package dbal_oracle
+* @version $Id: oracle.php,v 1.2 2005/06/10 08:52:03 devalley Exp $
+* @copyright (c) 2005 phpBB Group
+* @license http://opensource.org/licenses/gpl-license.php GNU Public License
+*
+*/
+
+/**
+* @ignore
+*/
+if(!defined("SQL_LAYER"))
+{
+
+define("SQL_LAYER","oracle");
+
+/**
+* @package dbal_oracle
+* Oracle Database Abstraction Layer
+*/
+class sql_db
+{
+
+ var $db_connect_id;
+ var $query_result;
+ var $in_transaction = 0;
+ var $row = array();
+ var $rowset = array();
+ var $num_queries = 0;
+ var $last_query_text = "";
+
+ //
+ // Constructor
+ //
+ function sql_db($sqlserver, $sqluser, $sqlpassword, $database="", $persistency = true)
+ {
+ $this->persistency = $persistency;
+ $this->user = $sqluser;
+ $this->password = $sqlpassword;
+ $this->server = $sqlserver;
+ $this->dbname = $database;
+
+ if($this->persistency)
+ {
+ $this->db_connect_id = @OCIPLogon($this->user, $this->password, $this->server);
+ }
+ else
+ {
+ $this->db_connect_id = @OCINLogon($this->user, $this->password, $this->server);
+ }
+ if($this->db_connect_id)
+ {
+ return $this->db_connect_id;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ //
+ // Other base methods
+ //
+ function sql_close()
+ {
+ if($this->db_connect_id)
+ {
+ // Commit outstanding transactions
+ if($this->in_transaction)
+ {
+ OCICommit($this->db_connect_id);
+ }
+
+ if($this->query_result)
+ {
+ @OCIFreeStatement($this->query_result);
+ }
+ $result = @OCILogoff($this->db_connect_id);
+ return $result;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ //
+ // Base query method
+ //
+ function sql_query($query = "", $transaction = FALSE)
+ {
+ // Remove any pre-existing queries
+ unset($this->query_result);
+
+ // Put us in transaction mode because with Oracle as soon as you make a query you're in a transaction
+ $this->in_transaction = TRUE;
+
+ if($query != "")
+ {
+ $this->last_query = $query;
+ $this->num_queries++;
+
+ if(eregi("LIMIT", $query))
+ {
+ preg_match("/^(.*)LIMIT ([0-9]+)[, ]*([0-9]+)*/s", $query, $limits);
+
+ $query = $limits[1];
+ if($limits[3])
+ {
+ $row_offset = $limits[2];
+ $num_rows = $limits[3];
+ }
+ else
+ {
+ $row_offset = 0;
+ $num_rows = $limits[2];
+ }
+ }
+
+ if(eregi("^(INSERT|UPDATE) ", $query))
+ {
+ $query = preg_replace("/\\\'/s", "''", $query);
+ }
+
+ $this->query_result = @OCIParse($this->db_connect_id, $query);
+ $success = @OCIExecute($this->query_result, OCI_DEFAULT);
+ }
+ if($success)
+ {
+ if($transaction == END_TRANSACTION)
+ {
+ OCICommit($this->db_connect_id);
+ $this->in_transaction = FALSE;
+ }
+
+ unset($this->row[$this->query_result]);
+ unset($this->rowset[$this->query_result]);
+ $this->last_query_text[$this->query_result] = $query;
+
+ return $this->query_result;
+ }
+ else
+ {
+ if($this->in_transaction)
+ {
+ OCIRollback($this->db_connect_id);
+ }
+ return false;
+ }
+ }
+
+ //
+ // Other query methods
+ //
+ function sql_numrows($query_id = 0)
+ {
+ if(!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+ if($query_id)
+ {
+ $result = @OCIFetchStatement($query_id, $this->rowset);
+ // OCIFetchStatment kills our query result so we have to execute the statment again
+ // if we ever want to use the query_id again.
+ @OCIExecute($query_id, OCI_DEFAULT);
+ return $result;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ function sql_affectedrows($query_id = 0)
+ {
+ if(!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+ if($query_id)
+ {
+ $result = @OCIRowCount($query_id);
+ return $result;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ function sql_numfields($query_id = 0)
+ {
+ if(!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+ if($query_id)
+ {
+ $result = @OCINumCols($query_id);
+ return $result;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ function sql_fieldname($offset, $query_id = 0)
+ {
+ // OCIColumnName uses a 1 based array so we have to up the offset by 1 in here to maintain
+ // full abstraction compatibitly
+ $offset += 1;
+ if(!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+ if($query_id)
+ {
+ $result = strtolower(@OCIColumnName($query_id, $offset));
+ return $result;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ function sql_fieldtype($offset, $query_id = 0)
+ {
+ // This situation is the same as fieldname
+ $offset += 1;
+ if(!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+ if($query_id)
+ {
+ $result = @OCIColumnType($query_id, $offset);
+ return $result;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ function sql_fetchrow($query_id = 0, $debug = FALSE)
+ {
+ if(!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+ if($query_id)
+ {
+ $result_row = "";
+ $result = @OCIFetchInto($query_id, $result_row, OCI_ASSOC+OCI_RETURN_NULLS);
+ if($debug)
+ {
+ echo "Query was: ".$this->last_query . "<br>";
+ echo "Result: $result<br>";
+ echo "Query ID: $query_id<br>";
+ echo "<pre>";
+ var_dump($result_row);
+ echo "</pre>";
+ }
+ if($result_row == "")
+ {
+ return false;
+ }
+
+ for($i = 0; $i < count($result_row); $i++)
+ {
+ list($key, $val) = each($result_row);
+ $return_arr[strtolower($key)] = $val;
+ }
+ $this->row[$query_id] = $return_arr;
+
+ return $this->row[$query_id];
+ }
+ else
+ {
+ return false;
+ }
+ }
+ // This function probably isn't as efficant is it could be but any other way I do it
+ // I end up losing 1 row...
+ function sql_fetchrowset($query_id = 0)
+ {
+ if(!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+ if($query_id)
+ {
+ $rows = @OCIFetchStatement($query_id, $results);
+ @OCIExecute($query_id, OCI_DEFAULT);
+ for($i = 0; $i <= $rows; $i++)
+ {
+ @OCIFetchInto($query_id, $tmp_result, OCI_ASSOC+OCI_RETURN_NULLS);
+
+ for($j = 0; $j < count($tmp_result); $j++)
+ {
+ list($key, $val) = each($tmp_result);
+ $return_arr[strtolower($key)] = $val;
+ }
+ $result[] = $return_arr;
+ }
+ return $result;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ function sql_fetchfield($field, $rownum = -1, $query_id = 0)
+ {
+ if(!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+ if($query_id)
+ {
+ if($rownum > -1)
+ {
+ // Reset the internal rownum pointer.
+ @OCIExecute($query_id, OCI_DEFAULT);
+ for($i = 0; $i < $rownum; $i++)
+ {
+ // Move the interal pointer to the row we want
+ @OCIFetch($query_id);
+ }
+ // Get the field data.
+ $result = @OCIResult($query_id, strtoupper($field));
+ }
+ else
+ {
+ // The internal pointer should be where we want it
+ // so we just grab the field out of the current row.
+ $result = @OCIResult($query_id, strtoupper($field));
+ }
+ return $result;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ function sql_rowseek($rownum, $query_id = 0)
+ {
+ if(!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+ if($query_id)
+ {
+ @OCIExecute($query_id, OCI_DEFAULT);
+ for($i = 0; $i < $rownum; $i++)
+ {
+ @OCIFetch($query_id);
+ }
+ $result = @OCIFetch($query_id);
+ return $result;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ function sql_nextid($query_id = 0)
+ {
+ if(!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+ if($query_id && $this->last_query_text[$query_id] != "")
+ {
+ if( eregi("^(INSERT{1}|^INSERT INTO{1})[[:space:]][\"]?([a-zA-Z0-9\_\-]+)[\"]?", $this->last_query_text[$query_id], $tablename))
+ {
+ $query = "SELECT ".$tablename[2]."_id_seq.currval FROM DUAL";
+ $stmt = @OCIParse($this->db_connect_id, $query);
+ @OCIExecute($stmt,OCI_DEFAULT );
+ $temp_result = @OCIFetchInto($stmt, $temp_result, OCI_ASSOC+OCI_RETURN_NULLS);
+ if($temp_result)
+ {
+ return $temp_result['CURRVAL'];
+ }
+ else
+ {
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ function sql_nextid($query_id = 0)
+ {
+ if(!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+ if($query_id && $this->last_query_text[$query_id] != "")
+ {
+ if( eregi("^(INSERT{1}|^INSERT INTO{1})[[:space:]][\"]?([a-zA-Z0-9\_\-]+)[\"]?", $this->last_query_text[$query_id], $tablename))
+ {
+ $query = "SELECT ".$tablename[2]."_id_seq.CURRVAL FROM DUAL";
+ $temp_q_id = @OCIParse($this->db_connect_id, $query);
+ @OCIExecute($temp_q_id, OCI_DEFAULT);
+ @OCIFetchInto($temp_q_id, $temp_result, OCI_ASSOC+OCI_RETURN_NULLS);
+
+ if($temp_result)
+ {
+ return $temp_result['CURRVAL'];
+ }
+ else
+ {
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+
+
+ function sql_freeresult($query_id = 0)
+ {
+ if(!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+ if($query_id)
+ {
+ $result = @OCIFreeStatement($query_id);
+ return $result;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ function sql_error($query_id = 0)
+ {
+ if(!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+ $result = @OCIError($query_id);
+ return $result;
+ }
+
+} // class sql_db
+
+} // if ... define
+
+?> \ No newline at end of file
diff --git a/includes/db/postgres.php b/includes/db/postgres.php
new file mode 100644
index 0000000..b5bad20
--- /dev/null
+++ b/includes/db/postgres.php
@@ -0,0 +1,597 @@
+<?php
+/**
+*
+* @package dbal_postgres
+* @version $Id: postgres.php,v 1.2 2005/06/10 08:52:03 devalley Exp $
+* @copyright (c) 2005 phpBB Group
+* @license http://opensource.org/licenses/gpl-license.php GNU Public License
+*
+*/
+
+/**
+* @ignore
+*/
+if (!defined('SQL_LAYER'))
+{
+
+define('SQL_LAYER', 'postgresql');
+
+/**
+* @package dbal_postgres
+* PostgreSQL Database Abstraction Layer
+* Minimum Requirement is Version 7.3+
+*/
+class sql_db
+{
+ var $db_connect_id;
+ var $query_result;
+ var $return_on_error = false;
+ var $transaction = false;
+ var $sql_time = 0;
+ var $num_queries = 0;
+ var $open_queries = array();
+
+ function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false)
+ {
+ $this->connect_string = '';
+
+ if ($sqluser)
+ {
+ $this->connect_string .= "user=$sqluser ";
+ }
+
+ if ($sqlpassword)
+ {
+ $this->connect_string .= "password=$sqlpassword ";
+ }
+
+ if ($sqlserver)
+ {
+ if (ereg(":", $sqlserver))
+ {
+ list($sqlserver, $sqlport) = split(":", $sqlserver);
+ $this->connect_string .= "host=$sqlserver port=$sqlport ";
+ }
+ else
+ {
+ if ($sqlserver != "localhost")
+ {
+ $this->connect_string .= "host=$sqlserver ";
+ }
+
+ if ($port)
+ {
+ $this->connect_string .= "port=$port ";
+ }
+ }
+ }
+
+ if ($database)
+ {
+ $this->dbname = $database;
+ $this->connect_string .= "dbname=$database";
+ }
+
+ $this->persistency = $persistency;
+
+ $this->db_connect_id = ($this->persistency) ? @pg_pconnect($this->connect_string) : @pg_connect($this->connect_string);
+
+ return ($this->db_connect_id) ? $this->db_connect_id : $this->sql_error('');
+ }
+
+ //
+ // Other base methods
+ //
+ function sql_close()
+ {
+ if (!$this->db_connect_id)
+ {
+ return false;
+ }
+
+ if ($this->transaction)
+ {
+ @pg_exec($this->db_connect_id, 'COMMIT');
+ }
+
+ return @pg_close($this->db_connect_id);
+ }
+
+ function sql_return_on_error($fail = false)
+ {
+ $this->return_on_error = $fail;
+ }
+
+ function sql_num_queries()
+ {
+ return $this->num_queries;
+ }
+
+ function sql_transaction($status = 'begin')
+ {
+ switch ($status)
+ {
+ case 'begin':
+ $result = @pg_exec($this->db_connect_id, 'BEGIN');
+ $this->transaction = true;
+ break;
+
+ case 'commit':
+ $result = @pg_exec($this->db_connect_id, 'COMMIT');
+ $this->transaction = false;
+
+ if (!$result)
+ {
+ @pg_exec($this->db_connect_id, 'ROLLBACK');
+ }
+ break;
+
+ case 'rollback':
+ $result = @pg_exec($this->db_connect_id, 'ROLLBACK');
+ $this->transaction = false;
+ break;
+
+ default:
+ $result = true;
+ }
+
+ return $result;
+ }
+
+ // Base query method
+ function sql_query($query = '', $cache_ttl = 0)
+ {
+ if ($query != '')
+ {
+ global $cache;
+
+ // EXPLAIN only in extra debug mode
+ if (defined('DEBUG_EXTRA'))
+ {
+ $this->sql_report('start', $query);
+ }
+
+ $this->query_result = ($cache_ttl && method_exists($cache, 'sql_load')) ? $cache->sql_load($query) : false;
+
+ if (!$this->query_result)
+ {
+ $this->num_queries++;
+ $this->last_query_text = $query;
+
+ if (($this->query_result = @pg_exec($this->db_connect_id, $query)) === false)
+ {
+ $this->sql_error($query);
+ }
+
+ if (defined('DEBUG_EXTRA'))
+ {
+ $this->sql_report('stop', $query);
+ }
+
+ if ($cache_ttl && method_exists($cache, 'sql_save'))
+ {
+ $cache->sql_save($query, $this->query_result, $cache_ttl);
+ }
+ }
+ else if (defined('DEBUG_EXTRA'))
+ {
+ $this->sql_report('fromcache', $query);
+ }
+ }
+ else
+ {
+ return false;
+ }
+
+ return ($this->query_result) ? $this->query_result : false;
+ }
+
+ function sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0)
+ {
+ if ($query != '')
+ {
+ $this->query_result = false;
+
+ // if $total is set to 0 we do not want to limit the number of rows
+ if ($total == 0)
+ {
+ $total = -1;
+ }
+
+ $query .= "\n LIMIT $total OFFSET $offset";
+
+ return $this->sql_query($query, $cache_ttl);
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ // Idea for this from Ikonboard
+ function sql_build_array($query, $assoc_ary = false)
+ {
+ if (!is_array($assoc_ary))
+ {
+ return false;
+ }
+
+ $fields = array();
+ $values = array();
+ if ($query == 'INSERT')
+ {
+ foreach ($assoc_ary as $key => $var)
+ {
+ $fields[] = $key;
+
+ if (is_null($var))
+ {
+ $values[] = 'NULL';
+ }
+ elseif (is_string($var))
+ {
+ $values[] = "'" . $this->sql_escape($var) . "'";
+ }
+ else
+ {
+ $values[] = (is_bool($var)) ? intval($var) : $var;
+ }
+ }
+
+ $query = ' (' . implode(', ', $fields) . ') VALUES (' . implode(', ', $values) . ')';
+ }
+ else if ($query == 'UPDATE' || $query == 'SELECT')
+ {
+ $values = array();
+ foreach ($assoc_ary as $key => $var)
+ {
+ if (is_null($var))
+ {
+ $values[] = "$key = NULL";
+ }
+ elseif (is_string($var))
+ {
+ $values[] = "$key = '" . $this->sql_escape($var) . "'";
+ }
+ else
+ {
+ $values[] = (is_bool($var)) ? "$key = " . intval($var) : "$key = $var";
+ }
+ }
+ $query = implode(($query == 'UPDATE') ? ', ' : ' AND ', $values);
+ }
+
+ return $query;
+ }
+
+ // Other query methods
+ //
+ // NOTE :: Want to remove _ALL_ reliance on sql_numrows from core code ...
+ // don't want this here by a middle Milestone
+ function sql_numrows($query_id = false)
+ {
+ if (!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+
+ return ($query_id) ? @pg_numrows($query_id) : false;
+ }
+
+ function sql_affectedrows($query_id = false)
+ {
+ if (!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+
+ return ($query_id) ? @pg_cmdtuples($query_id) : false;
+ }
+
+ function sql_fetchrow($query_id = false)
+ {
+ global $cache;
+
+ if (!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+
+ if (!isset($this->rownum[$query_id]))
+ {
+ $this->rownum[$query_id] = 0;
+ }
+
+ if (isset($cache->sql_rowset[$query_id]))
+ {
+ return $cache->sql_fetchrow($query_id);
+ }
+
+ $result = @pg_fetch_array($query_id, NULL, PGSQL_ASSOC);
+
+ if ($result)
+ {
+ $this->rownum[$query_id]++;
+ }
+
+ return $result;
+ }
+
+ function sql_fetchrowset($query_id = false)
+ {
+ if (!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+
+ $result = array();
+
+ if ($query_id)
+ {
+ unset($this->rowset[$query_id]);
+ unset($this->row[$query_id]);
+
+ $result = array();
+ while ($this->rowset[$query_id] = $this->sql_fetchrow($query_id))
+ {
+ $result[] = $this->rowset[$query_id];
+ }
+ return $result;
+ }
+
+ return false;
+ }
+
+ function sql_fetchfield($field, $rownum = -1, $query_id = false)
+ {
+ if (!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+
+ if ($query_id)
+ {
+ if ($rownum > -1)
+ {
+ if (@function_exists('pg_result_seek'))
+ {
+ @pg_result_seek($query_id, $rownum);
+ $row = @pg_fetch_assoc($query_id);
+ $result = isset($row[$field]) ? $row[$field] : false;
+ }
+ else
+ {
+ $this->sql_rowseek($offset, $query_id);
+ $row = $this->sql_fetchrow($query_id);
+ $result = isset($row[$field]) ? $row[$field] : false;
+ }
+ }
+ else
+ {
+ if (empty($this->row[$query_id]) && empty($this->rowset[$query_id]))
+ {
+ if ($this->sql_fetchrow($query_id))
+ {
+ $result = $this->row[$query_id][$field];
+ }
+ }
+ else
+ {
+ if ($this->rowset[$query_id])
+ {
+ $result = $this->rowset[$query_id][$field];
+ }
+ elseif ($this->row[$query_id])
+ {
+ $result = $this->row[$query_id][$field];
+ }
+ }
+ }
+ return $result;
+ }
+ return false;
+ }
+
+ function sql_rowseek($offset, $query_id = false)
+ {
+ if (!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+
+ if ($query_id)
+ {
+ if ($offset > -1)
+ {
+ if (@function_exists('pg_result_seek'))
+ {
+ @pg_result_seek($query_id, $rownum);
+ }
+ else
+ {
+ for ($i = $this->rownum[$query_id]; $i < $offset; $i++)
+ {
+ $this->sql_fetchrow($query_id);
+ }
+ }
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ return false;
+ }
+
+ function sql_nextid()
+ {
+ $query_id = $this->query_result;
+
+ if ($query_id && $this->last_query_text != '')
+ {
+ if (preg_match("/^INSERT[\t\n ]+INTO[\t\n ]+([a-z0-9\_\-]+)/is", $this->last_query_text, $tablename))
+ {
+ $query = "SELECT currval('" . $tablename[1] . "_id_seq') AS last_value";
+ $temp_q_id = @pg_exec($this->db_connect_id, $query);
+ if (!$temp_q_id)
+ {
+ return false;
+ }
+
+ $temp_result = @pg_fetch_array($temp_q_id, NULL, PGSQL_ASSOC);
+
+ return ($temp_result) ? $temp_result['last_value'] : false;
+ }
+ }
+
+ return false;
+ }
+
+ function sql_freeresult($query_id = false)
+ {
+ if (!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+
+ return (is_resource($query_id)) ? @pg_freeresult($query_id) : false;
+ }
+
+ function sql_escape($msg)
+ {
+ return str_replace("'", "''", str_replace('\\', '\\\\', $msg));
+ }
+
+ function sql_error($sql = '')
+ {
+ if (!$this->return_on_error)
+ {
+ $this_page = (isset($_SERVER['PHP_SELF']) && !empty($_SERVER['PHP_SELF'])) ? $_SERVER['PHP_SELF'] : $_ENV['PHP_SELF'];
+ $this_page .= '&' . ((isset($_SERVER['QUERY_STRING']) && !empty($_SERVER['QUERY_STRING'])) ? $_SERVER['QUERY_STRING'] : (isset($_ENV['QUERY_STRING']) ? $_ENV['QUERY_STRING'] : ''));
+
+ $message = '<u>SQL ERROR</u> [ ' . SQL_LAYER . ' ]<br /><br />' . @pg_errormessage() . '<br /><br /><u>CALLING PAGE</u><br /><br />' . htmlspecialchars($this_page) . (($sql != '') ? '<br /><br /><u>SQL</u><br /><br />' . $sql : '') . '<br />';
+
+ if ($this->transaction)
+ {
+ $this->sql_transaction('rollback');
+ }
+
+ trigger_error($message, E_USER_ERROR);
+ }
+
+ $result = array(
+ 'message' => @pg_errormessage(),
+ 'code' => ''
+ );
+
+ return $result;
+ }
+
+ function sql_report($mode, $query = '')
+ {
+ if (empty($_GET['explain']))
+ {
+ return;
+ }
+
+ global $cache, $starttime, $phpbb_root_path;
+ static $curtime, $query_hold, $html_hold;
+ static $sql_report = '';
+ static $cache_num_queries = 0;
+
+ if (!$query && !empty($query_hold))
+ {
+ $query = $query_hold;
+ }
+
+ switch ($mode)
+ {
+ case 'display':
+ if (!empty($cache))
+ {
+ $cache->unload();
+ }
+ $this->sql_close();
+
+ $mtime = explode(' ', microtime());
+ $totaltime = $mtime[0] + $mtime[1] - $starttime;
+
+ echo '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><meta http-equiv="Content-Type" content="text/html; charset=iso-8869-1"><meta http-equiv="Content-Style-Type" content="text/css"><link rel="stylesheet" href="' . $phpbb_root_path . 'adm/subSilver.css" type="text/css"><style type="text/css">' . "\n";
+ echo 'th { background-image: url(\'' . $phpbb_root_path . 'adm/images/cellpic3.gif\') }' . "\n";
+ echo 'td.cat { background-image: url(\'' . $phpbb_root_path . 'adm/images/cellpic1.gif\') }' . "\n";
+ echo '</style><title>' . $msg_title . '</title></head><body>';
+ echo '<table width="100%" cellspacing="0" cellpadding="0" border="0"><tr><td><a href="' . htmlspecialchars(preg_replace('/&explain=([^&]*)/', '', $_SERVER['REQUEST_URI'])) . '"><img src="' . $phpbb_root_path . 'adm/images/header_left.jpg" width="200" height="60" alt="phpBB Logo" title="phpBB Logo" border="0"/></a></td><td width="100%" background="' . $phpbb_root_path . 'adm/images/header_bg.jpg" height="60" align="right" nowrap="nowrap"><span class="maintitle">SQL Report</span> &nbsp; &nbsp; &nbsp;</td></tr></table><br clear="all"/><table width="95%" cellspacing="1" cellpadding="4" border="0" align="center"><tr><td height="40" align="center" valign="middle"><b>Page generated in ' . round($totaltime, 4) . " seconds with {$this->num_queries} queries" . (($cache_num_queries) ? " + $cache_num_queries " . (($cache_num_queries == 1) ? 'query' : 'queries') . ' returning data from cache' : '') . '</b></td></tr><tr><td align="center" nowrap="nowrap">Time spent on MySQL queries: <b>' . round($this->sql_time, 5) . 's</b> | Time spent on PHP: <b>' . round($totaltime - $this->sql_time, 5) . 's</b></td></tr></table><table width="95%" cellspacing="1" cellpadding="4" border="0" align="center"><tr><td>';
+ echo $sql_report;
+ echo '</td></tr></table><br /></body></html>';
+ exit;
+ break;
+
+ case 'start':
+ $query_hold = $query;
+ $html_hold = '';
+
+ $curtime = explode(' ', microtime());
+ $curtime = $curtime[0] + $curtime[1];
+ break;
+
+ case 'fromcache':
+ $endtime = explode(' ', microtime());
+ $endtime = $endtime[0] + $endtime[1];
+
+ $result = @pg_exec($this->db_connect_id, $query);
+ while ($void = @pg_fetch_array($result, NULL, PGSQL_ASSOC))
+ {
+ // Take the time spent on parsing rows into account
+ }
+ $splittime = explode(' ', microtime());
+ $splittime = $splittime[0] + $splittime[1];
+
+ $time_cache = $endtime - $curtime;
+ $time_db = $splittime - $endtime;
+ $color = ($time_db > $time_cache) ? 'green' : 'red';
+
+ $sql_report .= '<hr width="100%"/><br /><table class="bg" width="100%" cellspacing="1" cellpadding="4" border="0"><tr><th>Query results obtained from the cache</th></tr><tr><td class="row1"><textarea style="font-family:\'Courier New\',monospace;width:100%" rows="5">' . preg_replace('/\t(AND|OR)(\W)/', "\$1\$2", htmlspecialchars(preg_replace('/[\s]*[\n\r\t]+[\n\r\s\t]*/', "\n", $query))) . '</textarea></td></tr></table><p align="center">';
+
+ $sql_report .= 'Before: ' . sprintf('%.5f', $curtime - $starttime) . 's | After: ' . sprintf('%.5f', $endtime - $starttime) . 's | Elapsed [cache]: <b style="color: ' . $color . '">' . sprintf('%.5f', ($time_cache)) . 's</b> | Elapsed [db]: <b>' . sprintf('%.5f', $time_db) . 's</b></p>';
+
+ // Pad the start time to not interfere with page timing
+ $starttime += $time_db;
+
+ @pg_freeresult($result);
+ $cache_num_queries++;
+ break;
+
+ case 'stop':
+ $endtime = explode(' ', microtime());
+ $endtime = $endtime[0] + $endtime[1];
+
+ $sql_report .= '<hr width="100%"/><br /><table class="bg" width="100%" cellspacing="1" cellpadding="4" border="0"><tr><th>Query #' . $this->num_queries . '</th></tr><tr><td class="row1"><textarea style="font-family:\'Courier New\',monospace;width:100%" rows="5">' . preg_replace('/\t(AND|OR)(\W)/', "\$1\$2", htmlspecialchars(preg_replace('/[\s]*[\n\r\t]+[\n\r\s\t]*/', "\n", $query))) . '</textarea></td></tr></table> ' . $html_hold . '<p align="center">';
+
+ if ($this->query_result)
+ {
+ if (preg_match('/^(UPDATE|DELETE|REPLACE)/', $query))
+ {
+ $sql_report .= "Affected rows: <b>" . $this->sql_affectedrows($this->query_result) . '</b> | ';
+ }
+ $sql_report .= 'Before: ' . sprintf('%.5f', $curtime - $starttime) . 's | After: ' . sprintf('%.5f', $endtime - $starttime) . 's | Elapsed: <b>' . sprintf('%.5f', $endtime - $curtime) . 's</b>';
+ }
+ else
+ {
+ $error = $this->sql_error();
+ $sql_report .= '<b style="color: red">FAILED</b> - ' . SQL_LAYER . ' Error ' . $error['code'] . ': ' . htmlspecialchars($error['message']);
+ }
+
+ $sql_report .= '</p>';
+
+ $this->sql_time += $endtime - $curtime;
+ break;
+ }
+ }
+
+} // class ... db_sql
+
+} // if ... defined
+
+?> \ No newline at end of file
diff --git a/includes/db/sqlite.php b/includes/db/sqlite.php
new file mode 100644
index 0000000..1591396
--- /dev/null
+++ b/includes/db/sqlite.php
@@ -0,0 +1,387 @@
+<?php
+/**
+*
+* @package dbal_sqlite
+* @version $Id: sqlite.php,v 1.2 2005/06/10 08:52:03 devalley Exp $
+* @copyright (c) 2005 phpBB Group
+* @license http://opensource.org/licenses/gpl-license.php GNU Public License
+*
+*/
+
+/**
+* @ignore
+*/
+if (!defined("SQL_LAYER"))
+{
+
+define("SQL_LAYER","sqlite");
+
+/**
+* @package dbal_sqlite
+* Sqlite Database Abstraction Layer
+*/
+class sql_db
+{
+ var $db_connect_id;
+ var $query_result;
+ var $return_on_error = false;
+ var $transaction = false;
+ var $sql_report = '';
+ var $sql_time = 0;
+ var $num_queries = 0;
+ var $open_queries = array();
+
+ function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port, $persistency = false)
+ {
+ $this->persistency = $persistency;
+ $this->user = $sqluser;
+ $this->server = $sqlserver . (($port) ? ':' . $port : '');
+ $this->dbname = $database;
+
+ $this->db_connect_id = ($this->persistency) ? @sqlite_popen($this->server, 0, $error) : @sqlite_open($this->server, 0, $error);
+
+ return ($this->db_connect_id) ? true : $error;
+ }
+
+ // Other base methods
+ function sql_close()
+ {
+ if (!$this->db_connect_id)
+ {
+ return false;
+ }
+
+ return @sqlite_close($this->db_connect_id);
+ }
+
+ function sql_return_on_error($fail = false)
+ {
+ $this->return_on_error = $fail;
+ }
+
+ function sql_num_queries()
+ {
+ return $this->num_queries;
+ }
+
+ function sql_transaction($status = 'begin')
+ {
+ switch ($status)
+ {
+ case 'begin':
+ $this->transaction = true;
+ $result = @sqlite_query('BEGIN', $this->db_connect_id);
+ break;
+
+ case 'commit':
+ $this->transaction = false;
+ $result = @sqlite_query('COMMIT', $this->db_connect_id);
+ break;
+
+ case 'rollback':
+ $this->transaction = false;
+ $result = @sqlite_query('ROLLBACK', $this->db_connect_id);
+ break;
+
+ default:
+ $result = true;
+ }
+
+ return $result;
+ }
+
+ // Base query method
+ function sql_query($query = '', $expire_time = 0)
+ {
+ if ($query != '')
+ {
+ global $cache;
+
+ $query = preg_replace('#FROM \((.*?)\)(,|[\n\t ]+?WHERE) #s', 'FROM \1\2 ', $query);
+
+ if (!$expire_time || !$cache->sql_load($query, $expire_time))
+ {
+ if ($expire_time)
+ {
+ $cache_result = true;
+ }
+
+ $this->query_result = false;
+ $this->num_queries++;
+
+ if (!empty($_GET['explain']))
+ {
+ global $starttime;
+
+ $curtime = explode(' ', microtime());
+ $curtime = $curtime[0] + $curtime[1] - $starttime;
+ }
+
+ if (!($this->query_result = @sqlite_query($query, $this->db_connect_id)))
+ {
+ $this->sql_error($query);
+ }
+
+ if (!empty($_GET['explain']))
+ {
+ $endtime = explode(' ', microtime());
+ $endtime = $endtime[0] + $endtime[1] - $starttime;
+
+ $this->sql_report .= "<pre>Query:\t" . htmlspecialchars(preg_replace('/[\s]*[\n\r\t]+[\n\r\s\t]*/', "\n\t", $query)) . "\n\n";
+
+ if ($this->query_result)
+ {
+ $this->sql_report .= "Time before: $curtime\nTime after: $endtime\nElapsed time: <b>" . ($endtime - $curtime) . "</b>\n</pre>";
+ }
+ else
+ {
+ $error = $this->sql_error();
+ $this->sql_report .= '<b>FAILED</b> - SQLite ' . $error['code'] . ': ' . htmlspecialchars($error['message']) . '<br><br><pre>';
+ }
+
+ $this->sql_time += $endtime - $curtime;
+
+ if (preg_match('#^SELECT#', $query))
+ {
+ $html_table = FALSE;
+ if ($result = @sqlite_query("EXPLAIN $query", $this->db_connect_id))
+ {
+ while ($row = @sqlite_fetch_array($result, @sqlite_ASSOC))
+ {
+ if (!$html_table && sizeof($row))
+ {
+ $html_table = TRUE;
+ $this->sql_report .= "<table width=100% border=1 cellpadding=2 cellspacing=1>\n";
+ $this->sql_report .= "<tr>\n<td><b>" . implode("</b></td>\n<td><b>", array_keys($row)) . "</b></td>\n</tr>\n";
+ }
+ $this->sql_report .= "<tr>\n<td>" . implode("&nbsp;</td>\n<td>", array_values($row)) . "&nbsp;</td>\n</tr>\n";
+ }
+ }
+
+ if ($html_table)
+ {
+ $this->sql_report .= '</table><br>';
+ }
+ }
+
+ $this->sql_report .= "<hr>\n";
+ }
+
+ if (preg_match('#^SELECT#', $query))
+ {
+ $this->open_queries[] = $this->query_result;
+ }
+ }
+
+ if (!empty($cache_result))
+ {
+ $cache->sql_save($query, $this->query_result);
+ }
+ }
+ else
+ {
+ return false;
+ }
+
+ return ($this->query_result) ? $this->query_result : false;
+ }
+
+ function sql_query_limit($query, $total, $offset = 0, $expire_time = 0)
+ {
+ if ($query != '')
+ {
+ $this->query_result = false;
+
+ $query .= ' LIMIT ' . ((!empty($offset)) ? $total . ' OFFSET ' . $offset : $total);
+
+ return $this->sql_query($query, $expire_time);
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ // Idea for this from Ikonboard
+ function sql_build_array($query, $assoc_ary = false)
+ {
+ if (!is_array($assoc_ary))
+ {
+ return false;
+ }
+
+ $fields = array();
+ $values = array();
+ if ($query == 'INSERT')
+ {
+ foreach ($assoc_ary as $key => $var)
+ {
+ $fields[] = $key;
+
+ if (is_null($var))
+ {
+ $values[] = 'NULL';
+ }
+ elseif (is_string($var))
+ {
+ $values[] = "'" . $this->sql_escape($var) . "'";
+ }
+ else
+ {
+ $values[] = (is_bool($var)) ? intval($var) : $var;
+ }
+ }
+
+ $query = ' (' . implode(', ', $fields) . ') VALUES (' . implode(', ', $values) . ')';
+ }
+ else if ($query == 'UPDATE')
+ {
+ $values = array();
+ foreach ($assoc_ary as $key => $var)
+ {
+ if (is_null($var))
+ {
+ $values[] = "$key = NULL";
+ }
+ elseif (is_string($var))
+ {
+ $values[] = "$key = '" . $this->sql_escape($var) . "'";
+ }
+ else
+ {
+ $values[] = (is_bool($var)) ? "$key = " . intval($var) : "$key = $var";
+ }
+ }
+ $query = implode(', ', $values);
+ }
+
+ return $query;
+ }
+
+ // Other query methods
+ //
+ // NOTE :: Want to remove _ALL_ reliance on sql_numrows from core code ...
+ // don't want this here by a middle Milestone
+ function sql_numrows($query_id = false)
+ {
+ if (!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+
+ return ($query_id) ? @sqlite_num_rows($query_id) : false;
+ }
+
+ function sql_affectedrows()
+ {
+ return ($this->db_connect_id) ? @sqlite_changes($this->db_connect_id) : false;
+ }
+
+ function sql_fetchrow($query_id = 0)
+ {
+ global $cache;
+
+ if (!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+
+ if ($cache->sql_exists($query_id))
+ {
+ return $cache->sql_fetchrow($query_id);
+ }
+
+ return ($query_id) ? @sqlite_fetch_array($query_id, @sqlite_ASSOC) : false;
+ }
+
+ function sql_fetchrowset($query_id = 0)
+ {
+ if (!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+
+ if ($query_id)
+ {
+ unset($this->rowset[$query_id]);
+ unset($this->row[$query_id]);
+ while ($this->rowset[$query_id] = @sqlite_fetch_array($query_id, @sqlite_ASSOC))
+ {
+ $result[] = $this->rowset[$query_id];
+ }
+ return $result;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ function sql_fetchfield($field, $rownum = -1, $query_id = 0)
+ {
+ if (!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+
+ if ($query_id)
+ {
+ return ($rownum > -1) ? ((@sqlite_seek($query_id, $rownum)) ? @sqlite_column($query_id, $field) : false) : @sqlite_column($query_id, $field);
+ }
+ }
+
+ function sql_rowseek($rownum, $query_id = 0)
+ {
+ if (!$query_id)
+ {
+ $query_id = $this->query_result;
+ }
+
+ return ($query_id) ? @sqlite_seek($query_id, $rownum) : false;
+ }
+
+ function sql_nextid()
+ {
+ return ($this->db_connect_id) ? @sqlite_last_insert_rowid($this->db_connect_id) : false;
+ }
+
+ function sql_freeresult($query_id = false)
+ {
+ return true;
+ }
+
+ function sql_escape($msg)
+ {
+ return @sqlite_escape_string(stripslashes($msg));
+ }
+
+ function sql_error($sql = '')
+ {
+ if (!$this->return_on_error)
+ {
+ $this_page = (!empty($_SERVER['PHP_SELF'])) ? $_SERVER['PHP_SELF'] : $_ENV['PHP_SELF'];
+ $this_page .= '&' . ((!empty($_SERVER['QUERY_STRING'])) ? $_SERVER['QUERY_STRING'] : $_ENV['QUERY_STRING']);
+
+ $message = '<u>SQL ERROR</u> [ ' . SQL_LAYER . ' ]<br /><br />' . @sqlite_error_string(@sqlite_last_error($this->db_connect_id)) . '<br /><br /><u>CALLING PAGE</u><br /><br />' . htmlspecialchars($this_page) . (($sql != '') ? '<br /><br /><u>SQL</u><br /><br />' . $sql : '') . '<br />';
+
+ if ($this->transaction)
+ {
+ $this->sql_transaction('rollback');
+ }
+
+ trigger_error($message, E_USER_ERROR);
+ }
+
+ $result = array(
+ 'message' => @sqlite_error_string(@sqlite_last_error($this->db_connect_id)),
+ 'code' => @sqlite_last_error($this->db_connect_id)
+ );
+
+ return $result;
+ }
+
+} // class sql_db
+
+} // if ... define
+
+?> \ No newline at end of file
diff --git a/includes/php-gettext/AUTHORS b/includes/php-gettext/AUTHORS
new file mode 100644
index 0000000..da6ade7
--- /dev/null
+++ b/includes/php-gettext/AUTHORS
@@ -0,0 +1,3 @@
+Danilo Segan <danilo@kvota.net>
+Nico Kaiser <nico@siriux.net> (contributed most changes between 1.0.2 and 1.0.3, bugfix for 1.0.5)
+Steven Armstrong <sa@c-area.ch> (gettext.inc, leading to 1.0.6)
diff --git a/includes/php-gettext/COPYING b/includes/php-gettext/COPYING
new file mode 100644
index 0000000..5b6e7c6
--- /dev/null
+++ b/includes/php-gettext/COPYING
@@ -0,0 +1,340 @@
+ 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.
diff --git a/includes/php-gettext/ChangeLog b/includes/php-gettext/ChangeLog
new file mode 100644
index 0000000..5e0949d
--- /dev/null
+++ b/includes/php-gettext/ChangeLog
@@ -0,0 +1,144 @@
+2006-02-07 Danilo Å egan <danilo@gnome.org>
+
+ * examples/pigs_dropin.php: comment-out bind_textdomain_codeset
+
+ * gettext.inc (T_bind_textdomain_codeset): bind_textdomain_codeset
+ is available only in PHP 4.2.0+ (thanks to Jens A. Tkotz).
+
+ * Makefile: Include gettext.inc in DIST_FILES, VERSION up to
+ 1.0.7.
+
+2006-02-03 Danilo Å egan <danilo@gnome.org>
+
+ Added setlocale() emulation as well.
+
+ * examples/pigs_dropin.php: Use T_setlocale() and locale_emulation().
+ * examples/pigs_fallback.php: Use T_setlocale() and locale_emulation().
+
+ * gettext.inc: Added globals $EMULATEGETTEXT and $CURRENTLOCALE.
+ (locale_emulation): Whether emulation is active.
+ (_check_locale): Rewrite.
+ (_setlocale): Added emulated setlocale function.
+ (T_setlocale): Wrapper around _setlocale.
+ (_get_reader): Use variables and _setlocale.
+
+2006-02-02 Danilo Å egan <danilo@gnome.org>
+
+ Fix bug #12192.
+
+ * examples/locale/sr_CS/LC_MESSAGES/messages.po: Correct grammar.
+ * examples/locale/sr_CS/LC_MESSAGES/messages.mo: Rebuild.
+
+2006-02-02 Danilo Å egan <danilo@gnome.org>
+
+ Fix bug #15419.
+
+ * streams.php: Support for PHP 5.1.1 fread() which reads most 8kb.
+ (Fix by Piotr Szotkowski <shot@hot.pl>)
+
+2006-02-02 Danilo Å egan <danilo@gnome.org>
+
+ Merge Steven Armstrong's changes, supporting standard gettext
+ interfaces:
+
+ * examples/*: Restructured examples.
+ * gettext.inc: Added.
+ * AUTHORS: Added Steven.
+ * Makefile (VERSION): Up to 1.0.6.
+
+2006-01-28 Nico Kaiser <nico@siriux.net>
+
+ * gettext.php (select_string): Fix "true" <-> 1 difference of PHP
+
+2005-07-29 Danilo Å egan <danilo@gnome.org>
+
+ * Makefile (VERSION): Up to 1.0.5.
+
+2005-07-29 Danilo Å egan <danilo@gnome.org>
+
+ Fixes bug #13850.
+
+ * gettext.php (gettext_reader): check $Reader->error as well.
+
+2005-07-29 Danilo Å egan <danilo@gnome.org>
+
+ * Makefile (VERSION): Up to 1.0.4.
+
+2005-07-29 Danilo Å egan <danilo@gnome.org>
+
+ Fixes bug #13771.
+
+ * gettext.php (gettext_reader->get_plural_forms): Plural forms
+ header extraction regex change. Reported by Edgar Gonzales.
+
+2005-02-28 Danilo Å egan <dsegan@gmx.net>
+
+ * AUTHORS: Added Nico to the list.
+
+ * Makefile (VERSION): Up to 1.0.3.
+
+ * README: Updated.
+
+2005-02-28 Danilo Å egan <dsegan@gmx.net>
+
+ * gettext.php: Added pre-loading, code documentation, and many
+ code clean-ups by Nico Kaiser <nico@siriux.net>.
+
+2005-02-28 Danilo Å egan <dsegan@gmx.net>
+
+ * streams.php (FileReader.read): Handle read($bytes = 0).
+
+ * examples/pigs.php: Prefix gettext function names with T or T_.
+
+ * examples/update: Use the same keywords T_ and T_ngettext.
+
+ * streams.php: Added CachedFileReader.
+
+2003-11-11 Danilo Å egan <dsegan@gmx.net>
+
+ * gettext.php: Added hashing to find_string.
+
+2003-11-01 Danilo Å egan <dsegan@gmx.net>
+
+ * Makefile (DIST_FILES): Replaced LICENSE with COPYING.
+ (VERSION): Up to 1.0.2.
+
+ * AUTHORS: Minor edits.
+
+ * README: Minor edits.
+
+ * COPYING: Removed LICENSE, added this file.
+
+ * gettext.php: Added copyright notice and disclaimer.
+ * streams.php: Same.
+ * examples/pigs.php: Same.
+
+2003-10-23 Danilo Å egan <dsegan@gmx.net>
+
+ * Makefile: Upped version to 1.0.1.
+
+ * gettext.php (gettext_reader): Remove a call to set_total_plurals.
+ (set_total_plurals): Removed unused function for some better days.
+
+2003-10-23 Danilo Å egan <dsegan@gmx.net>
+
+ * Makefile: Added, version 1.0.0.
+
+ * examples/*: Added an example of usage.
+
+ * README: Described all the crap.
+
+2003-10-22 Danilo Å egan <dsegan@gmx.net>
+
+ * gettext.php: Plural forms implemented too.
+
+ * streams.php: Added FileReader for direct access to files (no
+ need to keep file in memory).
+
+ * gettext.php: It works, except for plural forms.
+
+ * streams.php: Created abstract class StreamReader.
+ Added StringReader class.
+
+ * gettext.php: Started writing gettext_reader.
+
diff --git a/includes/php-gettext/Makefile b/includes/php-gettext/Makefile
new file mode 100644
index 0000000..2dba911
--- /dev/null
+++ b/includes/php-gettext/Makefile
@@ -0,0 +1,32 @@
+PACKAGE = php-gettext-$(VERSION)
+VERSION = 1.0.7
+
+DIST_FILES = \
+ gettext.php \
+ gettext.inc \
+ streams.php \
+ AUTHORS \
+ ChangeLog \
+ README \
+ COPYING \
+ Makefile \
+ examples/index.php \
+ examples/pigs_dropin.php \
+ examples/pigs_fallback.php \
+ examples/locale/sr_CS/LC_MESSAGES/messages.po \
+ examples/locale/sr_CS/LC_MESSAGES/messages.mo \
+ examples/locale/de_CH/LC_MESSAGES/messages.po \
+ examples/locale/de_CH/LC_MESSAGES/messages.mo \
+ examples/update
+
+dist:
+ if [ -d $(PACKAGE) ]; then \
+ rm -rf $(PACKAGE); \
+ fi; \
+ mkdir $(PACKAGE); \
+ if [ -d $(PACKAGE) ]; then \
+ cp -rp --parents $(DIST_FILES) $(PACKAGE); \
+ tar cvzf $(PACKAGE).tar.gz $(PACKAGE); \
+ rm -rf $(PACKAGE); \
+ fi;
+
diff --git a/includes/php-gettext/README b/includes/php-gettext/README
new file mode 100644
index 0000000..c7525e2
--- /dev/null
+++ b/includes/php-gettext/README
@@ -0,0 +1,189 @@
+PHP-gettext 1.0
+
+Copyright 2003, 2006 -- Danilo "angry with PHP[1]" Segan
+Licensed under GPLv2 (or any later version, see COPYING)
+
+[1] PHP is actually cyrillic, and translates roughly to
+ "works-doesn't-work" (UTF-8: Ради-Ðе-Ради)
+
+
+Introduction
+
+ How many times did you look for a good translation tool, and
+ found out that gettext is best for the job? Many times.
+
+ How many times did you try to use gettext in PHP, but failed
+ miserably, because either your hosting provider didn't support
+ it, or the server didn't have adequate locale? Many times.
+
+ Well, this is a solution to your needs. It allows using gettext
+ tools for managing translations, yet it doesn't require gettext
+ library at all. It parses generated MO files directly, and thus
+ might be a bit slower than the (maybe provided) gettext library.
+
+ PHP-gettext is a simple reader for GNU gettext MO files. Those
+ are binary containers for translations, produced by GNU msgfmt.
+
+Why?
+
+ I got used to having gettext work even without gettext
+ library. It's there in my favourite language Python, so I was
+ surprised that I couldn't find it in PHP. I even Googled for it,
+ but to no avail.
+
+ So, I said, what the heck, I'm going to write it for this
+ disguisting language of PHP, because I'm often constrained to it.
+
+Features
+
+ o Support for simple translations
+ Just define a simple alias for translate() function (suggested
+ use of _() or gettext(); see provided example).
+
+ o Support for ngettext calls (plural forms, see a note under bugs)
+ You may also use plural forms. Translations in MO files need to
+ provide this, and they must also provide "plural-forms" header.
+ Please see 'info gettext' for more details.
+
+ o Support for reading straight files, or strings (!!!)
+ Since I can imagine many different backends for reading in the MO
+ file data, I used imaginary abstract class StreamReader to do all
+ the input (check streams.php). For your convenience, I've already
+ provided two classes for reading files: FileReader and
+ StringReader (CachedFileReader is a combination of the two: it
+ loads entire file contents into a string, and then works on that).
+ See example below for usage. You can for instance use StringReader
+ when you read in data from a database, or you can create your own
+ derivative of StreamReader for anything you like.
+
+
+Bugs
+
+ Plural-forms field in MO header (translation for empty string,
+ i.e. "") is treated according to PHP syntactic rules (it's
+ eval()ed). Since these should actually follow C syntax, there are
+ some problems.
+
+ For instance, I'm used to using this:
+ Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : \
+ n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;
+ but it fails with PHP (it sets $plural=2 instead of 0 for $n==1).
+
+ The fix is usually simple, but I'm lazy to go into the details of
+ PHP operator precedence, and maybe try to fix it. In here, I had
+ to put everything after the first ':' in parenthesis:
+ Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : \
+ (n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);
+ That works, and I'm satisfied.
+
+ Besides this one, there are probably a bunch of other bugs, since
+ I hate PHP (did I mention it already? no? strange), and don't
+ know it very well. So, feel free to fix any of those and report
+ them back to me at <danilo@kvota.net>.
+
+Usage
+
+ Put files streams.php and gettext.php somewhere you can load them
+ from, and require 'em in where you want to use them.
+
+ Then, create one 'stream reader' (a class that provides functions
+ like read(), seekto(), currentpos() and length()) which will
+ provide data for the 'gettext_reader', with eg.
+ $streamer = new FileStream('data.mo');
+
+ Then, use that as a parameter to gettext_reader constructor:
+ $wohoo = new gettext_reader($streamer);
+
+ If you want to disable pre-loading of entire message catalog in
+ memory (if, for example, you have a multi-thousand message catalog
+ which you'll use only occasionally), use "false" for second
+ parameter to gettext_reader constructor:
+ $wohoo = new gettext_reader($streamer, false);
+
+ From now on, you have all the benefits of gettext data at your
+ disposal, so may run:
+ print $wohoo->translate("This is a test");
+ print $wohoo->ngettext("%d bird", "%d birds", $birds);
+
+ You might need to pass parameter "-k" to xgettext to make it
+ extract all the strings. In above example, try with
+ xgettext -ktranslate -kngettext:1,2 file.php
+ what should create messages.po which contains two messages for
+ translation.
+
+ I suggest creating simple aliases for these functions (see
+ example/pigs.php for how do I do it, which means it's probably a
+ bad way).
+
+
+Usage with gettext.inc (standard gettext interfaces emulation)
+
+ Check example in examples/pig_dropin.php, basically you include
+ gettext.inc and use all the standard gettext interfaces as
+ documented on:
+
+ http://www.php.net/gettext
+
+ The only catch is that you can check return value of setlocale()
+ to see if your locale is system supported or not.
+
+
+Example
+
+ See in examples/ subdirectory. There are a couple of files.
+ pigs.php is an example, serbian.po is a translation to Serbian
+ language, and serbian.mo is generated with
+ msgfmt -o serbian.mo serbian.po
+ There is also simple "update" script that can be used to generate
+ POT file and to update the translation using msgmerge.
+
+Interesting TODO:
+
+ o Try to parse "plural-forms" header field, and to follow C syntax
+ rules. This won't be easy.
+
+Boring TODO:
+
+ o Learn PHP and fix bugs, slowness and other stuff resulting from
+ my lack of knowledge (but *maybe*, it's not my knowledge that is
+ bad, but PHP itself ;-).
+
+ (This is mostly done thanks to Nico Kaiser.)
+
+ o Try to use hash tables in MO files: with pre-loading, would it
+ be useful at all?
+
+Never-asked-questions:
+
+ o Why did you mark this as version 1.0 when this is the first code
+ release?
+
+ Well, it's quite simple. I consider that the first released thing
+ should be labeled "version 1" (first, right?). Zero is there to
+ indicate that there's zero improvement and/or change compared to
+ "version 1".
+
+ I plan to use version numbers 1.0.* for small bugfixes, and to
+ release 1.1 as "first stable release of version 1".
+
+ This may trick someone that this is actually useful software, but
+ as with any other free software, I take NO RESPONSIBILITY for
+ creating such a masterpiece that will smoke crack, trash your
+ hard disk, and make lasers in your CD device dance to the tune of
+ Mozart's 40th Symphony (there is one like that, right?).
+
+ o Can I...?
+
+ Yes, you can. This is free software (as in freedom, free speech),
+ and you might do whatever you wish with it, provided you do not
+ limit freedom of others (GPL).
+
+ I'm considering licensing this under LGPL, but I *do* want
+ *every* PHP-gettext user to contribute and respect ideas of free
+ software, so don't count on it happening anytime soon.
+
+ I'm sorry that I'm taking away your freedom of taking others'
+ freedom away, but I believe that's neglible as compared to what
+ freedoms you could take away. ;-)
+
+ Uhm, whatever.
diff --git a/includes/php-gettext/bin/gettexts.bat b/includes/php-gettext/bin/gettexts.bat
new file mode 100644
index 0000000..212ffce
--- /dev/null
+++ b/includes/php-gettext/bin/gettexts.bat
@@ -0,0 +1,20 @@
+@echo off
+xgettext -kT_ngettext:1,2 -kT_ -L PHP -o ..\..\..\locales\messages.po ..\..\..\*.php ..\..\..\services\*.php ..\..\..\templates\*.php
+if /i "%1" == "-p" goto stats
+if exist "..\..\..\locales\%1.po" goto merge
+echo "Usage: $0 [-p|<basename>]"
+goto end
+
+:stats
+msgfmt --statistics ..\..\..\locales\messages.po
+goto end
+
+:merge
+msgmerge -o ..\..\..\locales\tmp%1.po ..\..\..\locales\%1.po ..\..\..\locales\messages.po
+if exist "..\..\..\locales\%1.po" rename ..\..\..\locales\%1.po %1.po.bak
+rename ..\..\..\locales\tmp%1.po %1.po
+if exist "..\..\..\locales\%1.po.bak" del ..\..\..\locales\%1.po.bak
+msgfmt --statistics "..\..\..\locales\%1.po"
+
+:end
+echo Finished \ No newline at end of file
diff --git a/includes/php-gettext/examples/index.php b/includes/php-gettext/examples/index.php
new file mode 100644
index 0000000..263cd3d
--- /dev/null
+++ b/includes/php-gettext/examples/index.php
@@ -0,0 +1,27 @@
+<html>
+<head>
+<title>PHP-gettext examples</title>
+</head>
+<body>
+<h1>PHP-gettext</h1>
+
+<h2>Introduction</h2>
+<p>PHP-gettext provides a simple gettext replacement that works independently from the system's gettext abilities.
+It can read MO files and use them for translating strings.</p>
+<p>This version has the ability to cache all strings and translations to speed up the string lookup.
+While the cache is enabled by default, it can be switched off with the second parameter in the constructor (e.g. when using very large MO files
+that you don't want to keep in memory)</p>
+
+
+<h2>Examples</h2>
+<ul>
+ <li><a href="pigs_dropin.php">PHP-gettext as a dropin replacement</a></li>
+ <li><a href="pigs_fallback.php">PHP-gettext as a fallback solution</a></li>
+</ul>
+
+<hr />
+<p>Copyright (c) 2003-2006 Danilo Segan</p>
+<p>Copyright (c) 2005-2006 Steven Armstrong</p>
+
+</body>
+</html>
diff --git a/includes/php-gettext/examples/locale/de_CH/LC_MESSAGES/messages.mo b/includes/php-gettext/examples/locale/de_CH/LC_MESSAGES/messages.mo
new file mode 100644
index 0000000..9193037
--- /dev/null
+++ b/includes/php-gettext/examples/locale/de_CH/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/includes/php-gettext/examples/locale/de_CH/LC_MESSAGES/messages.po b/includes/php-gettext/examples/locale/de_CH/LC_MESSAGES/messages.po
new file mode 100644
index 0000000..6e4886b
--- /dev/null
+++ b/includes/php-gettext/examples/locale/de_CH/LC_MESSAGES/messages.po
@@ -0,0 +1,30 @@
+# Sample translation for PHP-gettext 1.0
+# Copyright (c) 2003 Danilo Segan <danilo@kvota.net>
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: pigs\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2003-10-23 04:50+0200\n"
+"PO-Revision-Date: 2003-11-01 23:40+0100\n"
+"Last-Translator: Danilo Segan <danilo@kvota.net>\n"
+"Language-Team: Serbian (sr) <danilo@kvota.net>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+#"Plural-Forms: nplurals=2; plural=n != 1;\n"
+
+#: pigs.php:19
+msgid ""
+"This is how the story goes.\n"
+"\n"
+msgstr ""
+"Und so geht die Geschichte.\n"
+"\n"
+
+#: pigs.php:21
+#, php-format
+msgid "%d pig went to the market\n"
+msgid_plural "%d pigs went to the market\n"
+msgstr[0] "%d Schwein ging zum Markt\n"
+msgstr[1] "%d Schweine gingen zum Markt\n"
diff --git a/includes/php-gettext/examples/locale/sr_CS/LC_MESSAGES/messages.mo b/includes/php-gettext/examples/locale/sr_CS/LC_MESSAGES/messages.mo
new file mode 100644
index 0000000..6ffccfd
--- /dev/null
+++ b/includes/php-gettext/examples/locale/sr_CS/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/includes/php-gettext/examples/locale/sr_CS/LC_MESSAGES/messages.po b/includes/php-gettext/examples/locale/sr_CS/LC_MESSAGES/messages.po
new file mode 100644
index 0000000..7e620cc
--- /dev/null
+++ b/includes/php-gettext/examples/locale/sr_CS/LC_MESSAGES/messages.po
@@ -0,0 +1,29 @@
+# Sample translation for PHP-gettext 1.0
+# Copyright (c) 2003,2006 Danilo Segan <danilo@kvota.net>
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: pigs\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2003-10-23 04:50+0200\n"
+"PO-Revision-Date: 2006-02-02 21:06+0100\n"
+"Last-Translator: Danilo Segan <danilo@kvota.net>\n"
+"Language-Team: Serbian (sr) <danilo@kvota.net>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : (n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
+
+#: pigs.php:19
+msgid ""
+"This is how the story goes.\n"
+"\n"
+msgstr "Овако иде прича.\n\n"
+
+#: pigs.php:21
+#, php-format
+msgid "%d pig went to the market\n"
+msgid_plural "%d pigs went to the market\n"
+msgstr[0] "%d мало праÑе је отишло на пијац\n"
+msgstr[1] "%d мала праÑета Ñу отишла на пијац\n"
+msgstr[2] "%d малих праÑића је отишло на пијац\n"
diff --git a/includes/php-gettext/examples/pigs_dropin.php b/includes/php-gettext/examples/pigs_dropin.php
new file mode 100644
index 0000000..edd2b0d
--- /dev/null
+++ b/includes/php-gettext/examples/pigs_dropin.php
@@ -0,0 +1,87 @@
+<?php
+/*
+ Copyright (c) 2003,2004,2005 Danilo Segan <danilo@kvota.net>.
+ Copyright (c) 2005,2006 Steven Armstrong <sa@c-area.ch>
+
+ This file is part of PHP-gettext.
+
+ PHP-gettext is free software; 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.
+
+ PHP-gettext is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with PHP-gettext; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+// define constants
+define(PROJECT_DIR, realpath('./'));
+define(LOCALE_DIR, PROJECT_DIR .'/locale');
+define(DEFAULT_LOCALE, 'en_US');
+
+require_once('../gettext.inc');
+
+$supported_locales = array('en_US', 'sr_CS', 'de_CH');
+$encoding = 'UTF-8';
+
+$locale = (isset($_GET['lang']))? $_GET['lang'] : DEFAULT_LOCALE;
+
+// gettext setup
+T_setlocale(LC_MESSAGES, $locale);
+// Set the text domain as 'messages'
+$domain = 'messages';
+bindtextdomain($domain, LOCALE_DIR);
+// bind_textdomain_codeset is supported only in PHP 4.2.0+
+if (function_exists('bind_textdomain_codeset'))
+ bind_textdomain_codeset($domain, $encoding);
+textdomain($domain);
+
+header("Content-type: text/html; charset=$encoding");
+?>
+<html>
+<head>
+<title>PHP-gettext dropin example</title>
+</head>
+<body>
+<h1>PHP-gettext as a dropin replacement</h1>
+<p>Example showing how to use PHP-gettext as a dropin replacement for the native gettext library.</p>
+<?php
+print "<p>";
+foreach($supported_locales as $l) {
+ print "[<a href=\"?lang=$l\">$l</a>] ";
+}
+print "</p>\n";
+
+if (!locale_emulation()) {
+ print "<p>locale '$locale' is supported by your system, using native gettext implementation.</p>\n";
+}
+else {
+ print "<p>locale '$locale' is _not_ supported on your system, using the default locale '". DEFAULT_LOCALE ."'.</p>\n";
+}
+?>
+
+<hr />
+
+<?php
+// using PHP-gettext
+print "<pre>";
+print _("This is how the story goes.\n\n");
+for ($number=6; $number>=0; $number--) {
+ print sprintf(T_ngettext("%d pig went to the market\n",
+ "%d pigs went to the market\n", $number),
+ $number );
+}
+print "</pre>\n";
+?>
+
+<hr />
+<p>&laquo; <a href="./">back</a></p>
+</body>
+</html>
diff --git a/includes/php-gettext/examples/pigs_fallback.php b/includes/php-gettext/examples/pigs_fallback.php
new file mode 100644
index 0000000..b50f752
--- /dev/null
+++ b/includes/php-gettext/examples/pigs_fallback.php
@@ -0,0 +1,86 @@
+<?php
+/*
+ Copyright (c) 2003,2004,2005 Danilo Segan <danilo@kvota.net>.
+ Copyright (c) 2005,2006 Steven Armstrong <sa@c-area.ch>
+
+ This file is part of PHP-gettext.
+
+ PHP-gettext is free software; 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.
+
+ PHP-gettext is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with PHP-gettext; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+// define constants
+define(PROJECT_DIR, realpath('./'));
+define(LOCALE_DIR, PROJECT_DIR .'/locale');
+define(DEFAULT_LOCALE, 'en_US');
+
+require_once('../gettext.inc');
+
+$supported_locales = array('en_US', 'sr_CS', 'de_CH');
+$encoding = 'UTF-8';
+
+$locale = (isset($_GET['lang']))? $_GET['lang'] : DEFAULT_LOCALE;
+
+// gettext setup
+T_setlocale(LC_MESSAGES, $locale);
+// Set the text domain as 'messages'
+$domain = 'messages';
+T_bindtextdomain($domain, LOCALE_DIR);
+T_bind_textdomain_codeset($domain, $encoding);
+T_textdomain($domain);
+
+header("Content-type: text/html; charset=$encoding");
+?>
+<html>
+<head>
+<title>PHP-gettext fallback example</title>
+</head>
+<body>
+<h1>PHP-gettext as a fallback solution</h1>
+<p>Example showing how to use PHP-gettext as a fallback solution if the native gettext library is not available or the system does not support the requested locale.</p>
+
+<?php
+print "<p>";
+foreach($supported_locales as $l) {
+ print "[<a href=\"?lang=$l\">$l</a>] ";
+}
+print "</p>\n";
+
+if (!locale_emulation()) {
+ print "<p>locale '$locale' is supported by your system, using native gettext implementation.</p>\n";
+}
+else {
+ print "<p>locale '$locale' is <strong>not</strong> supported on your system, using custom gettext implementation.</p>\n";
+}
+?>
+
+<hr />
+
+<?php
+// using PHP-gettext
+print "<pre>";
+print T_("This is how the story goes.\n\n");
+for ($number=6; $number>=0; $number--) {
+ print sprintf( T_ngettext("%d pig went to the market\n",
+ "%d pigs went to the market\n", $number),
+ $number );
+}
+print "</pre>\n";
+?>
+
+<hr />
+<p>&laquo; <a href="./">back</a></p>
+</body>
+</html>
diff --git a/includes/php-gettext/examples/update b/includes/php-gettext/examples/update
new file mode 100644
index 0000000..c8d8b61
--- /dev/null
+++ b/includes/php-gettext/examples/update
@@ -0,0 +1,14 @@
+#!/bin/sh
+TEMPLATE=pigs.pot
+xgettext -kT_ngettext:1,2 -kT_ -L PHP -o $TEMPLATE pigs.php
+if [ x$1 == 'x-p' ]; then
+ msgfmt --statistics $TEMPLATE
+else
+ if [ -f $1.po ]; then
+ msgmerge -o .tmp$1.po $1.po $TEMPLATE
+ mv .tmp$1.po $1.po
+ msgfmt --statistics $1.po
+ else
+ echo "Usage: $0 [-p|<basename>]"
+ fi
+fi
diff --git a/includes/php-gettext/gettext.inc b/includes/php-gettext/gettext.inc
new file mode 100644
index 0000000..eb94b25
--- /dev/null
+++ b/includes/php-gettext/gettext.inc
@@ -0,0 +1,318 @@
+<?php
+/*
+ Copyright (c) 2005 Steven Armstrong <sa at c-area dot ch>
+
+ Drop in replacement for native gettext.
+
+ This file is part of PHP-gettext.
+
+ PHP-gettext is free software; 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.
+
+ PHP-gettext is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with PHP-gettext; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+/*
+LC_CTYPE 0
+LC_NUMERIC 1
+LC_TIME 2
+LC_COLLATE 3
+LC_MONETARY 4
+LC_MESSAGES 5
+LC_ALL 6
+*/
+
+require('streams.php');
+require('gettext.php');
+
+
+// Variables
+
+global $text_domains, $default_domain, $LC_CATEGORIES, $EMULATEGETTEXT, $CURRENTLOCALE;
+$text_domains = array();
+$default_domain = 'messages';
+$LC_CATEGORIES = array('LC_CTYPE', 'LC_NUMERIC', 'LC_TIME', 'LC_COLLATE', 'LC_MONETARY', 'LC_MESSAGES', 'LC_ALL');
+$EMULATEGETTEXT = 0;
+$CURRENTLOCALE = '';
+
+
+// Utility functions
+
+/**
+ * Utility function to get a StreamReader for the given text domain.
+ */
+function _get_reader($domain=null, $category=5, $enable_cache=true) {
+ global $text_domains, $default_domain, $LC_CATEGORIES;
+ if (!isset($domain)) $domain = $default_domain;
+ if (!isset($text_domains[$domain]->l10n)) {
+ // get the current locale
+ $locale = _setlocale(LC_MESSAGES, 0);
+ $p = isset($text_domains[$domain]->path) ? $text_domains[$domain]->path : './';
+ $path = $p . "$locale/". $LC_CATEGORIES[$category] ."/$domain.mo";
+ if (file_exists($path)) {
+ $input = new FileReader($path);
+ }
+ else {
+ $input = null;
+ }
+ $text_domains[$domain]->l10n = new gettext_reader($input, $enable_cache);
+ }
+ return $text_domains[$domain]->l10n;
+}
+
+/**
+ * Returns whether we are using our emulated gettext API or PHP built-in one.
+ */
+function locale_emulation() {
+ global $EMULATEGETTEXT;
+ return $EMULATEGETTEXT;
+}
+
+/**
+ * Checks if the current locale is supported on this system.
+ */
+function _check_locale() {
+ global $EMULATEGETTEXT;
+ return !$EMULATEGETTEXT;
+}
+
+/**
+ * Get the codeset for the given domain.
+ */
+function _get_codeset($domain=null) {
+ global $text_domains, $default_domain, $LC_CATEGORIES;
+ if (!isset($domain)) $domain = $default_domain;
+ return (isset($text_domains[$domain]->codeset))? $text_domains[$domain]->codeset : ini_get('mbstring.internal_encoding');
+}
+
+/**
+ * Convert the given string to the encoding set by bind_textdomain_codeset.
+ */
+function _encode($text) {
+ $source_encoding = mb_detect_encoding($text);
+ $target_encoding = _get_codeset();
+ if ($source_encoding != $target_encoding) {
+ return mb_convert_encoding($text, $target_encoding, $source_encoding);
+ }
+ else {
+ return $text;
+ }
+}
+
+
+
+
+// Custom implementation of the standard gettext related functions
+
+/**
+ * Sets a requested locale, if needed emulates it.
+ */
+function _setlocale($category, $locale) {
+ global $CURRENTLOCALE, $EMULATEGETTEXT;
+ if ($locale === 0) { // use === to differentiate between string "0"
+ if ($CURRENTLOCALE != '')
+ return $CURRENTLOCALE;
+ else
+ // obey LANG variable, maybe extend to support all of LC_* vars
+ // even if we tried to read locale without setting it first
+ return _setlocale($category, $CURRENTLOCALE);
+ } else {
+ $ret = 0;
+ if (function_exists('setlocale')) // I don't know if this ever happens ;)
+ $ret = setlocale($category, $locale);
+ if (($ret and $locale == '') or ($ret == $locale)) {
+ $EMULATEGETTEXT = 0;
+ $CURRENTLOCALE = $ret;
+ } else {
+ if ($locale == '') // emulate variable support
+ $CURRENTLOCALE = getenv('LANG');
+ else
+ $CURRENTLOCALE = $locale;
+ $EMULATEGETTEXT = 1;
+ }
+ return $CURRENTLOCALE;
+ }
+}
+
+/**
+ * Sets the path for a domain.
+ */
+function _bindtextdomain($domain, $path) {
+ global $text_domains;
+ // ensure $path ends with a slash
+ if ($path[strlen($path) - 1] != '/') $path .= '/';
+ elseif ($path[strlen($path) - 1] != '\\') $path .= '\\';
+ $text_domains[$domain]->path = $path;
+}
+
+/**
+ * Specify the character encoding in which the messages from the DOMAIN message catalog will be returned.
+ */
+function _bind_textdomain_codeset($domain, $codeset) {
+ global $text_domains;
+ $text_domains[$domain]->codeset = $codeset;
+}
+
+/**
+ * Sets the default domain.
+ */
+function _textdomain($domain) {
+ global $default_domain;
+ $default_domain = $domain;
+}
+
+/**
+ * Lookup a message in the current domain.
+ */
+function _gettext($msgid) {
+ $l10n = _get_reader();
+ //return $l10n->translate($msgid);
+ return _encode($l10n->translate($msgid));
+}
+/**
+ * Alias for gettext.
+ */
+function __($msgid) {
+ return _gettext($msgid);
+}
+/**
+ * Plural version of gettext.
+ */
+function _ngettext($single, $plural, $number) {
+ $l10n = _get_reader();
+ //return $l10n->ngettext($single, $plural, $number);
+ return _encode($l10n->ngettext($single, $plural, $number));
+}
+
+/**
+ * Override the current domain.
+ */
+function _dgettext($domain, $msgid) {
+ $l10n = _get_reader($domain);
+ //return $l10n->translate($msgid);
+ return _encode($l10n->translate($msgid));
+}
+/**
+ * Plural version of dgettext.
+ */
+function _dngettext($domain, $single, $plural, $number) {
+ $l10n = _get_reader($domain);
+ //return $l10n->ngettext($single, $plural, $number);
+ return _encode($l10n->ngettext($single, $plural, $number));
+}
+
+/**
+ * Overrides the domain and category for a single lookup.
+ */
+function _dcgettext($domain, $msgid, $category) {
+ $l10n = _get_reader($domain, $category);
+ //return $l10n->translate($msgid);
+ return _encode($l10n->translate($msgid));
+}
+/**
+ * Plural version of dcgettext.
+ */
+function _dcngettext($domain, $single, $plural, $number, $category) {
+ $l10n = _get_reader($domain, $category);
+ //return $l10n->ngettext($single, $plural, $number);
+ return _encode($l10n->ngettext($single, $plural, $number));
+}
+
+
+
+// Wrappers to use if the standard gettext functions are available, but the current locale is not supported by the system.
+// Use the standard impl if the current locale is supported, use the custom impl otherwise.
+
+function T_setlocale($category, $locale) {
+ return _setlocale($category, $locale);
+}
+
+function T_bindtextdomain($domain, $path) {
+ if (_check_locale()) return bindtextdomain($domain, $path);
+ else return _bindtextdomain($domain, $path);
+}
+function T_bind_textdomain_codeset($domain, $codeset) {
+ // bind_textdomain_codeset is available only in PHP 4.2.0+
+ if (_check_locale() and function_exists('bind_textdomain_codeset')) return bind_textdomain_codeset($domain, $codeset);
+ else return _bind_textdomain_codeset($domain, $codeset);
+}
+function T_textdomain($domain) {
+ if (_check_locale()) return textdomain($domain);
+ else return _textdomain($domain);
+}
+function T_gettext($msgid) {
+ if (_check_locale()) return gettext($msgid);
+ else return _gettext($msgid);
+}
+function T_($msgid) {
+ if (_check_locale()) return _($msgid);
+ return __($msgid);
+}
+function T_ngettext($single, $plural, $number) {
+ if (_check_locale()) return ngettext($single, $plural, $number);
+ else return _ngettext($single, $plural, $number);
+}
+function T_dgettext($domain, $msgid) {
+ if (_check_locale()) return dgettext($domain, $msgid);
+ else return _dgettext($domain, $msgid);
+}
+function T_dngettext($domain, $single, $plural, $number) {
+ if (_check_locale()) return dngettext($domain, $single, $plural, $number);
+ else return _dngettext($domain, $single, $plural, $number);
+}
+function T_dcgettext($domain, $msgid, $category) {
+ if (_check_locale()) return dcgettext($domain, $msgid, $category);
+ else return _dcgettext($domain, $msgid, $category);
+}
+function T_dcngettext($domain, $single, $plural, $number, $category) {
+ if (_check_locale()) return dcngettext($domain, $single, $plural, $number, $category);
+ else return _dcngettext($domain, $single, $plural, $number, $category);
+}
+
+
+
+// Wrappers used as a drop in replacement for the standard gettext functions
+
+if (!function_exists('gettext')) {
+ function bindtextdomain($domain, $path) {
+ return _bindtextdomain($domain, $path);
+ }
+ function bind_textdomain_codeset($domain, $codeset) {
+ return _bind_textdomain_codeset($domain, $codeset);
+ }
+ function textdomain($domain) {
+ return _textdomain($domain);
+ }
+ function gettext($msgid) {
+ return _gettext($msgid);
+ }
+ function _($msgid) {
+ return __($msgid);
+ }
+ function ngettext($single, $plural, $number) {
+ return _ngettext($single, $plural, $number);
+ }
+ function dgettext($domain, $msgid) {
+ return _dgettext($domain, $msgid);
+ }
+ function dngettext($domain, $single, $plural, $number) {
+ return _dngettext($domain, $single, $plural, $number);
+ }
+ function dcgettext($domain, $msgid, $category) {
+ return _dcgettext($domain, $msgid, $category);
+ }
+ function dcngettext($domain, $single, $plural, $number, $category) {
+ return _dcngettext($domain, $single, $plural, $number, $category);
+ }
+}
+
+?> \ No newline at end of file
diff --git a/includes/php-gettext/gettext.php b/includes/php-gettext/gettext.php
new file mode 100644
index 0000000..ad94a98
--- /dev/null
+++ b/includes/php-gettext/gettext.php
@@ -0,0 +1,358 @@
+<?php
+/*
+ Copyright (c) 2003 Danilo Segan <danilo@kvota.net>.
+ Copyright (c) 2005 Nico Kaiser <nico@siriux.net>
+
+ This file is part of PHP-gettext.
+
+ PHP-gettext is free software; 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.
+
+ PHP-gettext is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with PHP-gettext; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+/**
+ * Provides a simple gettext replacement that works independently from
+ * the system's gettext abilities.
+ * It can read MO files and use them for translating strings.
+ * The files are passed to gettext_reader as a Stream (see streams.php)
+ *
+ * This version has the ability to cache all strings and translations to
+ * speed up the string lookup.
+ * While the cache is enabled by default, it can be switched off with the
+ * second parameter in the constructor (e.g. whenusing very large MO files
+ * that you don't want to keep in memory)
+ */
+class gettext_reader {
+ //public:
+ var $error = 0; // public variable that holds error code (0 if no error)
+
+ //private:
+ var $BYTEORDER = 0; // 0: low endian, 1: big endian
+ var $STREAM = NULL;
+ var $short_circuit = false;
+ var $enable_cache = false;
+ var $originals = NULL; // offset of original table
+ var $translations = NULL; // offset of translation table
+ var $pluralheader = NULL; // cache header field for plural forms
+ var $total = 0; // total string count
+ var $table_originals = NULL; // table for original strings (offsets)
+ var $table_translations = NULL; // table for translated strings (offsets)
+ var $cache_translations = NULL; // original -> translation mapping
+
+
+ /* Methods */
+
+
+ /**
+ * Reads a 32bit Integer from the Stream
+ *
+ * @access private
+ * @return Integer from the Stream
+ */
+ function readint() {
+ if ($this->BYTEORDER == 0) {
+ // low endian
+ return array_shift(unpack('V', $this->STREAM->read(4)));
+ } else {
+ // big endian
+ return array_shift(unpack('N', $this->STREAM->read(4)));
+ }
+ }
+
+ /**
+ * Reads an array of Integers from the Stream
+ *
+ * @param int count How many elements should be read
+ * @return Array of Integers
+ */
+ function readintarray($count) {
+ if ($this->BYTEORDER == 0) {
+ // low endian
+ return unpack('V'.$count, $this->STREAM->read(4 * $count));
+ } else {
+ // big endian
+ return unpack('N'.$count, $this->STREAM->read(4 * $count));
+ }
+ }
+
+ /**
+ * Constructor
+ *
+ * @param object Reader the StreamReader object
+ * @param boolean enable_cache Enable or disable caching of strings (default on)
+ */
+ function gettext_reader($Reader, $enable_cache = true) {
+ // If there isn't a StreamReader, turn on short circuit mode.
+ if (! $Reader || isset($Reader->error) ) {
+ $this->short_circuit = true;
+ return;
+ }
+
+ // Caching can be turned off
+ $this->enable_cache = $enable_cache;
+
+ // $MAGIC1 = (int)0x950412de; //bug in PHP 5
+ $MAGIC1 = (int) - 1794895138;
+ // $MAGIC2 = (int)0xde120495; //bug
+ $MAGIC2 = (int) - 569244523;
+
+ $this->STREAM = $Reader;
+ $magic = $this->readint();
+ if ($magic == $MAGIC1) {
+ $this->BYTEORDER = 0;
+ } elseif ($magic == $MAGIC2) {
+ $this->BYTEORDER = 1;
+ } else {
+ $this->error = 1; // not MO file
+ return false;
+ }
+
+ // FIXME: Do we care about revision? We should.
+ $revision = $this->readint();
+
+ $this->total = $this->readint();
+ $this->originals = $this->readint();
+ $this->translations = $this->readint();
+ }
+
+ /**
+ * Loads the translation tables from the MO file into the cache
+ * If caching is enabled, also loads all strings into a cache
+ * to speed up translation lookups
+ *
+ * @access private
+ */
+ function load_tables() {
+ if (is_array($this->cache_translations) &&
+ is_array($this->table_originals) &&
+ is_array($this->table_translations))
+ return;
+
+ /* get original and translations tables */
+ $this->STREAM->seekto($this->originals);
+ $this->table_originals = $this->readintarray($this->total * 2);
+ $this->STREAM->seekto($this->translations);
+ $this->table_translations = $this->readintarray($this->total * 2);
+
+ if ($this->enable_cache) {
+ $this->cache_translations = array ();
+ /* read all strings in the cache */
+ for ($i = 0; $i < $this->total; $i++) {
+ $this->STREAM->seekto($this->table_originals[$i * 2 + 2]);
+ $original = $this->STREAM->read($this->table_originals[$i * 2 + 1]);
+ $this->STREAM->seekto($this->table_translations[$i * 2 + 2]);
+ $translation = $this->STREAM->read($this->table_translations[$i * 2 + 1]);
+ $this->cache_translations[$original] = $translation;
+ }
+ }
+ }
+
+ /**
+ * Returns a string from the "originals" table
+ *
+ * @access private
+ * @param int num Offset number of original string
+ * @return string Requested string if found, otherwise ''
+ */
+ function get_original_string($num) {
+ $length = $this->table_originals[$num * 2 + 1];
+ $offset = $this->table_originals[$num * 2 + 2];
+ if (! $length)
+ return '';
+ $this->STREAM->seekto($offset);
+ $data = $this->STREAM->read($length);
+ return (string)$data;
+ }
+
+ /**
+ * Returns a string from the "translations" table
+ *
+ * @access private
+ * @param int num Offset number of original string
+ * @return string Requested string if found, otherwise ''
+ */
+ function get_translation_string($num) {
+ $length = $this->table_translations[$num * 2 + 1];
+ $offset = $this->table_translations[$num * 2 + 2];
+ if (! $length)
+ return '';
+ $this->STREAM->seekto($offset);
+ $data = $this->STREAM->read($length);
+ return (string)$data;
+ }
+
+ /**
+ * Binary search for string
+ *
+ * @access private
+ * @param string string
+ * @param int start (internally used in recursive function)
+ * @param int end (internally used in recursive function)
+ * @return int string number (offset in originals table)
+ */
+ function find_string($string, $start = -1, $end = -1) {
+ if (($start == -1) or ($end == -1)) {
+ // find_string is called with only one parameter, set start end end
+ $start = 0;
+ $end = $this->total;
+ }
+ if (abs($start - $end) <= 1) {
+ // We're done, now we either found the string, or it doesn't exist
+ $txt = $this->get_original_string($start);
+ if ($string == $txt)
+ return $start;
+ else
+ return -1;
+ } else if ($start > $end) {
+ // start > end -> turn around and start over
+ return $this->find_string($string, $end, $start);
+ } else {
+ // Divide table in two parts
+ $half = (int)(($start + $end) / 2);
+ $cmp = strcmp($string, $this->get_original_string($half));
+ if ($cmp == 0)
+ // string is exactly in the middle => return it
+ return $half;
+ else if ($cmp < 0)
+ // The string is in the upper half
+ return $this->find_string($string, $start, $half);
+ else
+ // The string is in the lower half
+ return $this->find_string($string, $half, $end);
+ }
+ }
+
+ /**
+ * Translates a string
+ *
+ * @access public
+ * @param string string to be translated
+ * @return string translated string (or original, if not found)
+ */
+ function translate($string) {
+ if ($this->short_circuit)
+ return $string;
+ $this->load_tables();
+
+ if ($this->enable_cache) {
+ // Caching enabled, get translated string from cache
+ if (array_key_exists($string, $this->cache_translations))
+ return $this->cache_translations[$string];
+ else
+ return $string;
+ } else {
+ // Caching not enabled, try to find string
+ $num = $this->find_string($string);
+ if ($num == -1)
+ return $string;
+ else
+ return $this->get_translation_string($num);
+ }
+ }
+
+ /**
+ * Get possible plural forms from MO header
+ *
+ * @access private
+ * @return string plural form header
+ */
+ function get_plural_forms() {
+ // lets assume message number 0 is header
+ // this is true, right?
+ $this->load_tables();
+
+ // cache header field for plural forms
+ if (! is_string($this->pluralheader)) {
+ if ($this->enable_cache) {
+ $header = $this->cache_translations[""];
+ } else {
+ $header = $this->get_translation_string(0);
+ }
+ if (eregi("plural-forms: ([^\n]*)\n", $header, $regs))
+ $expr = $regs[1];
+ else
+ $expr = "nplurals=2; plural=n == 1 ? 0 : 1;";
+ $this->pluralheader = $expr;
+ }
+ return $this->pluralheader;
+ }
+
+ /**
+ * Detects which plural form to take
+ *
+ * @access private
+ * @param n count
+ * @return int array index of the right plural form
+ */
+ function select_string($n) {
+ $string = $this->get_plural_forms();
+ $string = str_replace('nplurals',"\$total",$string);
+ $string = str_replace("n",$n,$string);
+ $string = str_replace('plural',"\$plural",$string);
+
+ $total = 0;
+ $plural = 0;
+
+ eval("$string");
+ if ($plural >= $total) $plural = $total - 1;
+ return $plural;
+ }
+
+ /**
+ * Plural version of gettext
+ *
+ * @access public
+ * @param string single
+ * @param string plural
+ * @param string number
+ * @return translated plural form
+ */
+ function ngettext($single, $plural, $number) {
+ if ($this->short_circuit) {
+ if ($number != 1)
+ return $plural;
+ else
+ return $single;
+ }
+
+ // find out the appropriate form
+ $select = $this->select_string($number);
+
+ // this should contains all strings separated by NULLs
+ $key = $single.chr(0).$plural;
+
+
+ if ($this->enable_cache) {
+ if (! array_key_exists($key, $this->cache_translations)) {
+ return ($number != 1) ? $plural : $single;
+ } else {
+ $result = $this->cache_translations[$key];
+ $list = explode(chr(0), $result);
+ return $list[$select];
+ }
+ } else {
+ $num = $this->find_string($key);
+ if ($num == -1) {
+ return ($number != 1) ? $plural : $single;
+ } else {
+ $result = $this->get_translation_string($num);
+ $list = explode(chr(0), $result);
+ return $list[$select];
+ }
+ }
+ }
+
+}
+
+?>
diff --git a/includes/php-gettext/streams.php b/includes/php-gettext/streams.php
new file mode 100644
index 0000000..d57aac6
--- /dev/null
+++ b/includes/php-gettext/streams.php
@@ -0,0 +1,166 @@
+<?php
+/*
+ Copyright (c) 2003, 2005 Danilo Segan <danilo@kvota.net>.
+
+ This file is part of PHP-gettext.
+
+ PHP-gettext is free software; 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.
+
+ PHP-gettext is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with PHP-gettext; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+
+// Simple class to wrap file streams, string streams, etc.
+// seek is essential, and it should be byte stream
+class StreamReader {
+ // should return a string [FIXME: perhaps return array of bytes?]
+ function read($bytes) {
+ return false;
+ }
+
+ // should return new position
+ function seekto($position) {
+ return false;
+ }
+
+ // returns current position
+ function currentpos() {
+ return false;
+ }
+
+ // returns length of entire stream (limit for seekto()s)
+ function length() {
+ return false;
+ }
+}
+
+class StringReader {
+ var $_pos;
+ var $_str;
+
+ function StringReader($str='') {
+ $this->_str = $str;
+ $this->_pos = 0;
+ }
+
+ function read($bytes) {
+ $data = substr($this->_str, $this->_pos, $bytes);
+ $this->_pos += $bytes;
+ if (strlen($this->_str)<$this->_pos)
+ $this->_pos = strlen($this->_str);
+
+ return $data;
+ }
+
+ function seekto($pos) {
+ $this->_pos = $pos;
+ if (strlen($this->_str)<$this->_pos)
+ $this->_pos = strlen($this->_str);
+ return $this->_pos;
+ }
+
+ function currentpos() {
+ return $this->_pos;
+ }
+
+ function length() {
+ return strlen($this->_str);
+ }
+
+}
+
+
+class FileReader {
+ var $_pos;
+ var $_fd;
+ var $_length;
+
+ function FileReader($filename) {
+ if (file_exists($filename)) {
+
+ $this->_length=filesize($filename);
+ $this->_pos = 0;
+ $this->_fd = fopen($filename,'rb');
+ if (!$this->_fd) {
+ $this->error = 3; // Cannot read file, probably permissions
+ return false;
+ }
+ } else {
+ $this->error = 2; // File doesn't exist
+ return false;
+ }
+ }
+
+ function read($bytes) {
+ if ($bytes) {
+ fseek($this->_fd, $this->_pos);
+
+ // PHP 5.1.1 does not read more than 8192 bytes in one fread()
+ // the discussions at PHP Bugs suggest it's the intended behaviour
+ while ($bytes > 0) {
+ $chunk = fread($this->_fd, $bytes);
+ $data .= $chunk;
+ $bytes -= strlen($chunk);
+ }
+ $this->_pos = ftell($this->_fd);
+
+ return $data;
+ } else return '';
+ }
+
+ function seekto($pos) {
+ fseek($this->_fd, $pos);
+ $this->_pos = ftell($this->_fd);
+ return $this->_pos;
+ }
+
+ function currentpos() {
+ return $this->_pos;
+ }
+
+ function length() {
+ return $this->_length;
+ }
+
+ function close() {
+ fclose($this->_fd);
+ }
+
+}
+
+// Preloads entire file in memory first, then creates a StringReader
+// over it (it assumes knowledge of StringReader internals)
+class CachedFileReader extends StringReader {
+ function CachedFileReader($filename) {
+ if (file_exists($filename)) {
+
+ $length=filesize($filename);
+ $fd = fopen($filename,'rb');
+
+ if (!$fd) {
+ $this->error = 3; // Cannot read file, probably permissions
+ return false;
+ }
+ $this->_str = fread($fd, $length);
+ fclose($fd);
+
+ } else {
+ $this->error = 2; // File doesn't exist
+ return false;
+ }
+ }
+}
+
+
+?> \ No newline at end of file
diff --git a/includes/player/error.swf b/includes/player/error.swf
new file mode 100644
index 0000000..fc440f3
--- /dev/null
+++ b/includes/player/error.swf
Binary files differ
diff --git a/includes/player/license.txt b/includes/player/license.txt
new file mode 100644
index 0000000..2111a50
--- /dev/null
+++ b/includes/player/license.txt
@@ -0,0 +1,10 @@
+Copyright (c) 2005, Fabricio Zuardi
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+ * Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/includes/player/load.swf b/includes/player/load.swf
new file mode 100644
index 0000000..6da4ce6
--- /dev/null
+++ b/includes/player/load.swf
Binary files differ
diff --git a/includes/player/musicplayer_f6.swf b/includes/player/musicplayer_f6.swf
new file mode 100644
index 0000000..2eb5d57
--- /dev/null
+++ b/includes/player/musicplayer_f6.swf
Binary files differ
diff --git a/includes/player/play.swf b/includes/player/play.swf
new file mode 100644
index 0000000..95415a6
--- /dev/null
+++ b/includes/player/play.swf
Binary files differ
diff --git a/includes/player/stop.swf b/includes/player/stop.swf
new file mode 100644
index 0000000..e66556d
--- /dev/null
+++ b/includes/player/stop.swf
Binary files differ
diff --git a/includes/utf8.php b/includes/utf8.php
new file mode 100644
index 0000000..9ef8113
--- /dev/null
+++ b/includes/utf8.php
@@ -0,0 +1,478 @@
+<?php
+/**
+ * UTF8 helper functions
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+/**
+ * URL-Encode a filename to allow unicodecharacters
+ *
+ * Slashes are not encoded
+ *
+ * When the second parameter is true the string will
+ * be encoded only if non ASCII characters are detected -
+ * This makes it safe to run it multiple times on the
+ * same string (default is true)
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @see urlencode
+ */
+function utf8_encodeFN($file,$safe=true){
+ if($safe && preg_match('#^[a-zA-Z0-9/_\-.%]+$#',$file)){
+ return $file;
+ }
+ $file = urlencode($file);
+ $file = str_replace('%2F','/',$file);
+ return $file;
+}
+
+/**
+ * URL-Decode a filename
+ *
+ * This is just a wrapper around urldecode
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @see urldecode
+ */
+function utf8_decodeFN($file){
+ $file = urldecode($file);
+ return $file;
+}
+
+/**
+ * Checks if a string contains 7bit ASCII only
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function utf8_isASCII($str){
+ for($i=0; $i<strlen($str); $i++){
+ if(ord($str{$i}) >127) return false;
+ }
+ return true;
+}
+
+/**
+ * Tries to detect if a string is in Unicode encoding
+ *
+ * @author <bmorel@ssi.fr>
+ * @link http://www.php.net/manual/en/function.utf8-encode.php
+ */
+function utf8_check($Str) {
+ 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;
+}
+
+/**
+ * This is a unicode aware replacement for strlen()
+ *
+ * Uses mb_string extension if available
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @see strlen()
+ */
+function utf8_strlen($string){
+ if(!defined('UTF8_NOMBSTRING') && function_exists('mb_strlen'))
+ return mb_strlen($string,'utf-8');
+
+ $uni = utf8_to_unicode($string);
+ return count($uni);
+}
+
+/**
+ * This is a unicode aware replacement for substr()
+ *
+ * Uses mb_string extension if available
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @see substr()
+ */
+function utf8_substr($str, $start, $length=null){
+ if(!defined('UTF8_NOMBSTRING') && function_exists('mb_substr'))
+ return mb_substr($str,$start,$length,'utf-8');
+
+ $uni = utf8_to_unicode($str);
+ return unicode_to_utf8(array_slice($uni,$start,$length));
+}
+
+/**
+ * This is a unicode aware replacement for strtolower()
+ *
+ * Uses mb_string extension if available
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @see strtolower()
+ * @see utf8_strtoupper()
+ */
+function utf8_strtolower($string){
+ if(!defined('UTF8_NOMBSTRING') && function_exists('mb_strtolower'))
+ return mb_strtolower($string,'utf-8');
+
+ global $UTF8_UPPER_TO_LOWER;
+ $uni = utf8_to_unicode($string);
+ for ($i=0; $i < count($uni); $i++){
+ if($UTF8_UPPER_TO_LOWER[$uni[$i]]){
+ $uni[$i] = $UTF8_UPPER_TO_LOWER[$uni[$i]];
+ }
+ }
+ return unicode_to_utf8($uni);
+}
+
+/**
+ * This is a unicode aware replacement for strtoupper()
+ *
+ * Uses mb_string extension if available
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @see strtoupper()
+ * @see utf8_strtoupper()
+ */
+function utf8_strtoupper($string){
+ if(!defined('UTF8_NOMBSTRING') && function_exists('mb_strtolower'))
+ return mb_strtolower($string,'utf-8');
+
+ global $UTF8_LOWER_TO_UPPER;
+ $uni = utf8_to_unicode($string);
+ for ($i=0; $i < count($uni); $i++){
+ if($UTF8_LOWER_TO_UPPER[$uni[$i]]){
+ $uni[$i] = $UTF8_LOWER_TO_UPPER[$uni[$i]];
+ }
+ }
+ return unicode_to_utf8($uni);
+}
+
+/**
+ * Replace accented UTF-8 characters by unaccented ASCII-7 equivalents
+ *
+ * Use the optional parameter to just deaccent lower ($case = -1) or upper ($case = 1)
+ * letters. Default is to deaccent both cases ($case = 0)
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function utf8_deaccent($string,$case=0){
+ if($case <= 0){
+ global $UTF8_LOWER_ACCENTS;
+ $string = str_replace(array_keys($UTF8_LOWER_ACCENTS),array_values($UTF8_LOWER_ACCENTS),$string);
+ }
+ if($case >= 0){
+ global $UTF8_UPPER_ACCENTS;
+ $string = str_replace(array_keys($UTF8_UPPER_ACCENTS),array_values($UTF8_UPPER_ACCENTS),$string);
+ }
+ return $string;
+}
+
+/**
+ * Removes special characters (nonalphanumeric) from a UTF-8 string
+ *
+ * Be sure to specify all specialchars you give in $repl in $keep, too
+ * or it won't work.
+ *
+ * This function adds the controlchars 0x00 to 0x19 to the array of
+ * stripped chars (they are not included in $UTF8_SPECIAL_CHARS)
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @param string $string The UTF8 string to strip of special chars
+ * @param string $repl Replace special with this string
+ * @param string $keep Special chars to keep (in UTF8)
+ */
+function utf8_stripspecials($string,$repl='',$keep=''){
+ global $UTF8_SPECIAL_CHARS;
+ if($keep != ''){
+ $specials = array_diff($UTF8_SPECIAL_CHARS, utf8_to_unicode($keep));
+ }else{
+ $specials = $UTF8_SPECIAL_CHARS;
+ }
+
+ $specials = unicode_to_utf8($specials);
+ $specials = preg_quote($specials, '/');
+
+ return preg_replace('/[\x00-\x19'.$specials.']/u',$repl,$string);
+}
+
+/**
+ * This is an Unicode aware replacement for strpos
+ *
+ * Uses mb_string extension if available
+ *
+ * @author Scott Michael Reynen <scott@randomchaos.com>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @link http://www.randomchaos.com/document.php?source=php_and_unicode
+ * @see strpos()
+ */
+function utf8_strpos($haystack, $needle,$offset=0) {
+ if(!defined('UTF8_NOMBSTRING') && function_exists('mb_strpos'))
+ return mb_strpos($haystack,$needle,$offset,'utf-8');
+
+ $haystack = utf8_to_unicode($haystack);
+ $needle = utf8_to_unicode($needle);
+ $position = $offset;
+ $found = false;
+
+ while( (! $found ) && ( $position < count( $haystack ) ) ) {
+ if ( $needle[0] == $haystack[$position] ) {
+ for ($i = 1; $i < count( $needle ); $i++ ) {
+ if ( $needle[$i] != $haystack[ $position + $i ] ) break;
+ }
+ if ( $i == count( $needle ) ) {
+ $found = true;
+ $position--;
+ }
+ }
+ $position++;
+ }
+ return ( $found == true ) ? $position : false;
+}
+
+/**
+ * This function will any UTF-8 encoded text and return it as
+ * a list of Unicode values:
+ *
+ * @author Scott Michael Reynen <scott@randomchaos.com>
+ * @link http://www.randomchaos.com/document.php?source=php_and_unicode
+ * @see unicode_to_utf8()
+ */
+function utf8_to_unicode( $str ) {
+ $unicode = array();
+ $values = array();
+ $lookingFor = 1;
+
+ for ($i = 0; $i < strlen( $str ); $i++ ) {
+ $thisValue = ord( $str[ $i ] );
+ if ( $thisValue < 128 ) $unicode[] = $thisValue;
+ else {
+ if ( count( $values ) == 0 ) $lookingFor = ( $thisValue < 224 ) ? 2 : 3;
+ $values[] = $thisValue;
+ if ( count( $values ) == $lookingFor ) {
+ $number = ( $lookingFor == 3 ) ?
+ ( ( $values[0] % 16 ) * 4096 ) + ( ( $values[1] % 64 ) * 64 ) + ( $values[2] % 64 ):
+ ( ( $values[0] % 32 ) * 64 ) + ( $values[1] % 64 );
+ $unicode[] = $number;
+ $values = array();
+ $lookingFor = 1;
+ }
+ }
+ }
+ return $unicode;
+}
+
+/**
+ * This function will convert a Unicode array back to its UTF-8 representation
+ *
+ * @author Scott Michael Reynen <scott@randomchaos.com>
+ * @link http://www.randomchaos.com/document.php?source=php_and_unicode
+ * @see utf8_to_unicode()
+ */
+function unicode_to_utf8( $str ) {
+ $utf8 = '';
+ foreach( $str as $unicode ) {
+ if ( $unicode < 128 ) {
+ $utf8.= chr( $unicode );
+ } elseif ( $unicode < 2048 ) {
+ $utf8.= chr( 192 + ( ( $unicode - ( $unicode % 64 ) ) / 64 ) );
+ $utf8.= chr( 128 + ( $unicode % 64 ) );
+ } else {
+ $utf8.= chr( 224 + ( ( $unicode - ( $unicode % 4096 ) ) / 4096 ) );
+ $utf8.= chr( 128 + ( ( ( $unicode % 4096 ) - ( $unicode % 64 ) ) / 64 ) );
+ $utf8.= chr( 128 + ( $unicode % 64 ) );
+ }
+ }
+ return $utf8;
+}
+
+/**
+ * UTF-8 Case lookup table
+ *
+ * This lookuptable defines the upper case letters to their correspponding
+ * lower case letter in UTF-8
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+$UTF8_LOWER_TO_UPPER = array(
+ 0x0061=>0x0041, 0x03C6=>0x03A6, 0x0163=>0x0162, 0x00E5=>0x00C5, 0x0062=>0x0042,
+ 0x013A=>0x0139, 0x00E1=>0x00C1, 0x0142=>0x0141, 0x03CD=>0x038E, 0x0101=>0x0100,
+ 0x0491=>0x0490, 0x03B4=>0x0394, 0x015B=>0x015A, 0x0064=>0x0044, 0x03B3=>0x0393,
+ 0x00F4=>0x00D4, 0x044A=>0x042A, 0x0439=>0x0419, 0x0113=>0x0112, 0x043C=>0x041C,
+ 0x015F=>0x015E, 0x0144=>0x0143, 0x00EE=>0x00CE, 0x045E=>0x040E, 0x044F=>0x042F,
+ 0x03BA=>0x039A, 0x0155=>0x0154, 0x0069=>0x0049, 0x0073=>0x0053, 0x1E1F=>0x1E1E,
+ 0x0135=>0x0134, 0x0447=>0x0427, 0x03C0=>0x03A0, 0x0438=>0x0418, 0x00F3=>0x00D3,
+ 0x0440=>0x0420, 0x0454=>0x0404, 0x0435=>0x0415, 0x0449=>0x0429, 0x014B=>0x014A,
+ 0x0431=>0x0411, 0x0459=>0x0409, 0x1E03=>0x1E02, 0x00F6=>0x00D6, 0x00F9=>0x00D9,
+ 0x006E=>0x004E, 0x0451=>0x0401, 0x03C4=>0x03A4, 0x0443=>0x0423, 0x015D=>0x015C,
+ 0x0453=>0x0403, 0x03C8=>0x03A8, 0x0159=>0x0158, 0x0067=>0x0047, 0x00E4=>0x00C4,
+ 0x03AC=>0x0386, 0x03AE=>0x0389, 0x0167=>0x0166, 0x03BE=>0x039E, 0x0165=>0x0164,
+ 0x0117=>0x0116, 0x0109=>0x0108, 0x0076=>0x0056, 0x00FE=>0x00DE, 0x0157=>0x0156,
+ 0x00FA=>0x00DA, 0x1E61=>0x1E60, 0x1E83=>0x1E82, 0x00E2=>0x00C2, 0x0119=>0x0118,
+ 0x0146=>0x0145, 0x0070=>0x0050, 0x0151=>0x0150, 0x044E=>0x042E, 0x0129=>0x0128,
+ 0x03C7=>0x03A7, 0x013E=>0x013D, 0x0442=>0x0422, 0x007A=>0x005A, 0x0448=>0x0428,
+ 0x03C1=>0x03A1, 0x1E81=>0x1E80, 0x016D=>0x016C, 0x00F5=>0x00D5, 0x0075=>0x0055,
+ 0x0177=>0x0176, 0x00FC=>0x00DC, 0x1E57=>0x1E56, 0x03C3=>0x03A3, 0x043A=>0x041A,
+ 0x006D=>0x004D, 0x016B=>0x016A, 0x0171=>0x0170, 0x0444=>0x0424, 0x00EC=>0x00CC,
+ 0x0169=>0x0168, 0x03BF=>0x039F, 0x006B=>0x004B, 0x00F2=>0x00D2, 0x00E0=>0x00C0,
+ 0x0434=>0x0414, 0x03C9=>0x03A9, 0x1E6B=>0x1E6A, 0x00E3=>0x00C3, 0x044D=>0x042D,
+ 0x0436=>0x0416, 0x01A1=>0x01A0, 0x010D=>0x010C, 0x011D=>0x011C, 0x00F0=>0x00D0,
+ 0x013C=>0x013B, 0x045F=>0x040F, 0x045A=>0x040A, 0x00E8=>0x00C8, 0x03C5=>0x03A5,
+ 0x0066=>0x0046, 0x00FD=>0x00DD, 0x0063=>0x0043, 0x021B=>0x021A, 0x00EA=>0x00CA,
+ 0x03B9=>0x0399, 0x017A=>0x0179, 0x00EF=>0x00CF, 0x01B0=>0x01AF, 0x0065=>0x0045,
+ 0x03BB=>0x039B, 0x03B8=>0x0398, 0x03BC=>0x039C, 0x045C=>0x040C, 0x043F=>0x041F,
+ 0x044C=>0x042C, 0x00FE=>0x00DE, 0x00F0=>0x00D0, 0x1EF3=>0x1EF2, 0x0068=>0x0048,
+ 0x00EB=>0x00CB, 0x0111=>0x0110, 0x0433=>0x0413, 0x012F=>0x012E, 0x00E6=>0x00C6,
+ 0x0078=>0x0058, 0x0161=>0x0160, 0x016F=>0x016E, 0x03B1=>0x0391, 0x0457=>0x0407,
+ 0x0173=>0x0172, 0x00FF=>0x0178, 0x006F=>0x004F, 0x043B=>0x041B, 0x03B5=>0x0395,
+ 0x0445=>0x0425, 0x0121=>0x0120, 0x017E=>0x017D, 0x017C=>0x017B, 0x03B6=>0x0396,
+ 0x03B2=>0x0392, 0x03AD=>0x0388, 0x1E85=>0x1E84, 0x0175=>0x0174, 0x0071=>0x0051,
+ 0x0437=>0x0417, 0x1E0B=>0x1E0A, 0x0148=>0x0147, 0x0105=>0x0104, 0x0458=>0x0408,
+ 0x014D=>0x014C, 0x00ED=>0x00CD, 0x0079=>0x0059, 0x010B=>0x010A, 0x03CE=>0x038F,
+ 0x0072=>0x0052, 0x0430=>0x0410, 0x0455=>0x0405, 0x0452=>0x0402, 0x0127=>0x0126,
+ 0x0137=>0x0136, 0x012B=>0x012A, 0x03AF=>0x038A, 0x044B=>0x042B, 0x006C=>0x004C,
+ 0x03B7=>0x0397, 0x0125=>0x0124, 0x0219=>0x0218, 0x00FB=>0x00DB, 0x011F=>0x011E,
+ 0x043E=>0x041E, 0x1E41=>0x1E40, 0x03BD=>0x039D, 0x0107=>0x0106, 0x03CB=>0x03AB,
+ 0x0446=>0x0426, 0x00FE=>0x00DE, 0x00E7=>0x00C7, 0x03CA=>0x03AA, 0x0441=>0x0421,
+ 0x0432=>0x0412, 0x010F=>0x010E, 0x00F8=>0x00D8, 0x0077=>0x0057, 0x011B=>0x011A,
+ 0x0074=>0x0054, 0x006A=>0x004A, 0x045B=>0x040B, 0x0456=>0x0406, 0x0103=>0x0102,
+ 0x03BB=>0x039B, 0x00F1=>0x00D1, 0x043D=>0x041D, 0x03CC=>0x038C, 0x00E9=>0x00C9,
+ 0x00F0=>0x00D0, 0x0457=>0x0407, 0x0123=>0x0122,
+);
+
+/**
+ * UTF-8 Case lookup table
+ *
+ * This lookuptable defines the lower case letters to their correspponding
+ * upper case letter in UTF-8 (it does so by flipping $UTF8_LOWER_TO_UPPER)
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+$UTF8_UPPER_TO_LOWER = @array_flip($UTF8_LOWER_TO_UPPER);
+
+/**
+ * UTF-8 lookup table for lower case accented letters
+ *
+ * This lookuptable defines replacements for accented characters from the ASCII-7
+ * range. This are lower case letters only.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @see utf8_deaccent()
+ */
+$UTF8_LOWER_ACCENTS = array(
+ 'à ' => 'a', 'ô' => 'o', 'Ä' => 'd', 'ḟ' => 'f', 'ë' => 'e', 'Å¡' => 's', 'Æ¡' => 'o',
+ 'ß' => 'ss', 'ă' => 'a', 'Å™' => 'r', 'È›' => 't', 'ň' => 'n', 'Ä' => 'a', 'Ä·' => 'k',
+ 'Å' => 's', 'ỳ' => 'y', 'ņ' => 'n', 'ĺ' => 'l', 'ħ' => 'h', 'á¹—' => 'p', 'ó' => 'o',
+ 'ú' => 'u', 'Ä›' => 'e', 'é' => 'e', 'ç' => 'c', 'áº' => 'w', 'Ä‹' => 'c', 'õ' => 'o',
+ 'ṡ' => 's', 'ø' => 'o', 'ģ' => 'g', 'ŧ' => 't', 'ș' => 's', 'ė' => 'e', 'ĉ' => 'c',
+ 'ś' => 's', 'î' => 'i', 'ű' => 'u', 'ć' => 'c', 'ę' => 'e', 'ŵ' => 'w', 'ṫ' => 't',
+ 'Å«' => 'u', 'Ä' => 'c', 'ö' => 'oe', 'è' => 'e', 'Å·' => 'y', 'Ä…' => 'a', 'Å‚' => 'l',
+ 'ų' => 'u', 'ů' => 'u', 'ş' => 's', 'ğ' => 'g', 'ļ' => 'l', 'ƒ' => 'f', 'ž' => 'z',
+ 'ẃ' => 'w', 'ḃ' => 'b', 'å' => 'a', 'ì' => 'i', 'ï' => 'i', 'ḋ' => 'd', 'ť' => 't',
+ 'ŗ' => 'r', 'ä' => 'ae', 'í' => 'i', 'ŕ' => 'r', 'ê' => 'e', 'ü' => 'ue', 'ò' => 'o',
+ 'Ä“' => 'e', 'ñ' => 'n', 'Å„' => 'n', 'Ä¥' => 'h', 'Ä' => 'g', 'Ä‘' => 'd', 'ĵ' => 'j',
+ 'ÿ' => 'y', 'ũ' => 'u', 'ŭ' => 'u', 'ư' => 'u', 'ţ' => 't', 'ý' => 'y', 'ő' => 'o',
+ 'â' => 'a', 'ľ' => 'l', 'ẅ' => 'w', 'ż' => 'z', 'ī' => 'i', 'ã' => 'a', 'ġ' => 'g',
+ 'á¹' => 'm', 'Å' => 'o', 'Ä©' => 'i', 'ù' => 'u', 'į' => 'i', 'ź' => 'z', 'á' => 'a',
+ 'û' => 'u', 'þ' => 'th', 'ð' => 'dh', 'æ' => 'ae', 'µ' => 'u',
+);
+
+/**
+ * UTF-8 lookup table for upper case accented letters
+ *
+ * This lookuptable defines replacements for accented characters from the ASCII-7
+ * range. This are upper case letters only.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @see utf8_deaccent()
+ */
+$UTF8_UPPER_ACCENTS = array(
+ 'à ' => 'A', 'ô' => 'O', 'Ä' => 'D', 'ḟ' => 'F', 'ë' => 'E', 'Å¡' => 'S', 'Æ¡' => 'O',
+ 'ß' => 'Ss', 'ă' => 'A', 'Å™' => 'R', 'È›' => 'T', 'ň' => 'N', 'Ä' => 'A', 'Ä·' => 'K',
+ 'Å' => 'S', 'ỳ' => 'Y', 'ņ' => 'N', 'ĺ' => 'L', 'ħ' => 'H', 'á¹—' => 'P', 'ó' => 'O',
+ 'ú' => 'U', 'Ä›' => 'E', 'é' => 'E', 'ç' => 'C', 'áº' => 'W', 'Ä‹' => 'C', 'õ' => 'O',
+ 'ṡ' => 'S', 'ø' => 'O', 'ģ' => 'G', 'ŧ' => 'T', 'ș' => 'S', 'ė' => 'E', 'ĉ' => 'C',
+ 'ś' => 'S', 'î' => 'I', 'ű' => 'U', 'ć' => 'C', 'ę' => 'E', 'ŵ' => 'W', 'ṫ' => 'T',
+ 'Å«' => 'U', 'Ä' => 'C', 'ö' => 'Oe', 'è' => 'E', 'Å·' => 'Y', 'Ä…' => 'A', 'Å‚' => 'L',
+ 'ų' => 'U', 'ů' => 'U', 'ş' => 'S', 'ğ' => 'G', 'ļ' => 'L', 'ƒ' => 'F', 'ž' => 'Z',
+ 'ẃ' => 'W', 'ḃ' => 'B', 'å' => 'A', 'ì' => 'I', 'ï' => 'I', 'ḋ' => 'D', 'ť' => 'T',
+ 'ŗ' => 'R', 'ä' => 'Ae', 'í' => 'I', 'ŕ' => 'R', 'ê' => 'E', 'ü' => 'Ue', 'ò' => 'O',
+ 'Ä“' => 'E', 'ñ' => 'N', 'Å„' => 'N', 'Ä¥' => 'H', 'Ä' => 'G', 'Ä‘' => 'D', 'ĵ' => 'J',
+ 'ÿ' => 'Y', 'ũ' => 'U', 'ŭ' => 'U', 'ư' => 'U', 'ţ' => 'T', 'ý' => 'Y', 'ő' => 'O',
+ 'â' => 'A', 'ľ' => 'L', 'ẅ' => 'W', 'ż' => 'Z', 'ī' => 'I', 'ã' => 'A', 'ġ' => 'G',
+ 'á¹' => 'M', 'Å' => 'O', 'Ä©' => 'I', 'ù' => 'U', 'į' => 'I', 'ź' => 'Z', 'á' => 'A',
+ 'û' => 'U', 'Þ' => 'Th', 'Ã' => 'Dh', 'Æ' => 'Ae',
+);
+
+/**
+ * UTF-8 array of common special characters
+ *
+ * This array should contain all special characters (not a letter or digit)
+ * defined in the various local charsets - it's not a complete list of non-alphanum
+ * characters in UTF-8. It's not perfect but should match most cases of special
+ * chars.
+ *
+ * The controlchars 0x00 to 0x19 are _not_ included in this array. The space 0x20 is!
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @see utf8_stripspecials()
+ */
+$UTF8_SPECIAL_CHARS = array(
+ 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, 0x0020, 0x0021, 0x0022, 0x0023,
+ 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d,
+ 0x002e, 0x002f, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, 0x005b,
+ 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0142, 0x007b, 0x007c, 0x007d, 0x007e,
+ 0x007f, 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088,
+ 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, 0x0090, 0x0091, 0x0092,
+ 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009a, 0x009b, 0x009c,
+ 0x009d, 0x009e, 0x009f, 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6,
+ 0x00a7, 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, 0x00b0,
+ 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x00ba,
+ 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, 0x00d7, 0x00f7, 0x02c7, 0x02d8, 0x02d9,
+ 0x02da, 0x02db, 0x02dc, 0x02dd, 0x0300, 0x0301, 0x0303, 0x0309, 0x0323, 0x0384,
+ 0x0385, 0x0387, 0x03b2, 0x03c6, 0x03d1, 0x03d2, 0x03d5, 0x03d6, 0x05b0, 0x05b1,
+ 0x05b2, 0x05b3, 0x05b4, 0x05b5, 0x05b6, 0x05b7, 0x05b8, 0x05b9, 0x05bb, 0x05bc,
+ 0x05bd, 0x05be, 0x05bf, 0x05c0, 0x05c1, 0x05c2, 0x05c3, 0x05f3, 0x05f4, 0x060c,
+ 0x061b, 0x061f, 0x0640, 0x064b, 0x064c, 0x064d, 0x064e, 0x064f, 0x0650, 0x0651,
+ 0x0652, 0x066a, 0x0e3f, 0x200c, 0x200d, 0x200e, 0x200f, 0x2013, 0x2014, 0x2015,
+ 0x2017, 0x2018, 0x2019, 0x201a, 0x201c, 0x201d, 0x201e, 0x2020, 0x2021, 0x2022,
+ 0x2026, 0x2030, 0x2032, 0x2033, 0x2039, 0x203a, 0x2044, 0x20a7, 0x20aa, 0x20ab,
+ 0x20ac, 0x2116, 0x2118, 0x2122, 0x2126, 0x2135, 0x2190, 0x2191, 0x2192, 0x2193,
+ 0x2194, 0x2195, 0x21b5, 0x21d0, 0x21d1, 0x21d2, 0x21d3, 0x21d4, 0x2200, 0x2202,
+ 0x2203, 0x2205, 0x2206, 0x2207, 0x2208, 0x2209, 0x220b, 0x220f, 0x2211, 0x2212,
+ 0x2215, 0x2217, 0x2219, 0x221a, 0x221d, 0x221e, 0x2220, 0x2227, 0x2228, 0x2229,
+ 0x222a, 0x222b, 0x2234, 0x223c, 0x2245, 0x2248, 0x2260, 0x2261, 0x2264, 0x2265,
+ 0x2282, 0x2283, 0x2284, 0x2286, 0x2287, 0x2295, 0x2297, 0x22a5, 0x22c5, 0x2310,
+ 0x2320, 0x2321, 0x2329, 0x232a, 0x2469, 0x2500, 0x2502, 0x250c, 0x2510, 0x2514,
+ 0x2518, 0x251c, 0x2524, 0x252c, 0x2534, 0x253c, 0x2550, 0x2551, 0x2552, 0x2553,
+ 0x2554, 0x2555, 0x2556, 0x2557, 0x2558, 0x2559, 0x255a, 0x255b, 0x255c, 0x255d,
+ 0x255e, 0x255f, 0x2560, 0x2561, 0x2562, 0x2563, 0x2564, 0x2565, 0x2566, 0x2567,
+ 0x2568, 0x2569, 0x256a, 0x256b, 0x256c, 0x2580, 0x2584, 0x2588, 0x258c, 0x2590,
+ 0x2591, 0x2592, 0x2593, 0x25a0, 0x25b2, 0x25bc, 0x25c6, 0x25ca, 0x25cf, 0x25d7,
+ 0x2605, 0x260e, 0x261b, 0x261e, 0x2660, 0x2663, 0x2665, 0x2666, 0x2701, 0x2702,
+ 0x2703, 0x2704, 0x2706, 0x2707, 0x2708, 0x2709, 0x270c, 0x270d, 0x270e, 0x270f,
+ 0x2710, 0x2711, 0x2712, 0x2713, 0x2714, 0x2715, 0x2716, 0x2717, 0x2718, 0x2719,
+ 0x271a, 0x271b, 0x271c, 0x271d, 0x271e, 0x271f, 0x2720, 0x2721, 0x2722, 0x2723,
+ 0x2724, 0x2725, 0x2726, 0x2727, 0x2729, 0x272a, 0x272b, 0x272c, 0x272d, 0x272e,
+ 0x272f, 0x2730, 0x2731, 0x2732, 0x2733, 0x2734, 0x2735, 0x2736, 0x2737, 0x2738,
+ 0x2739, 0x273a, 0x273b, 0x273c, 0x273d, 0x273e, 0x273f, 0x2740, 0x2741, 0x2742,
+ 0x2743, 0x2744, 0x2745, 0x2746, 0x2747, 0x2748, 0x2749, 0x274a, 0x274b, 0x274d,
+ 0x274f, 0x2750, 0x2751, 0x2752, 0x2756, 0x2758, 0x2759, 0x275a, 0x275b, 0x275c,
+ 0x275d, 0x275e, 0x2761, 0x2762, 0x2763, 0x2764, 0x2765, 0x2766, 0x2767, 0x277f,
+ 0x2789, 0x2793, 0x2794, 0x2798, 0x2799, 0x279a, 0x279b, 0x279c, 0x279d, 0x279e,
+ 0x279f, 0x27a0, 0x27a1, 0x27a2, 0x27a3, 0x27a4, 0x27a5, 0x27a6, 0x27a7, 0x27a8,
+ 0x27a9, 0x27aa, 0x27ab, 0x27ac, 0x27ad, 0x27ae, 0x27af, 0x27b1, 0x27b2, 0x27b3,
+ 0x27b4, 0x27b5, 0x27b6, 0x27b7, 0x27b8, 0x27b9, 0x27ba, 0x27bb, 0x27bc, 0x27bd,
+ 0x27be, 0xf6d9, 0xf6da, 0xf6db, 0xf8d7, 0xf8d8, 0xf8d9, 0xf8da, 0xf8db, 0xf8dc,
+ 0xf8dd, 0xf8de, 0xf8df, 0xf8e0, 0xf8e1, 0xf8e2, 0xf8e3, 0xf8e4, 0xf8e5, 0xf8e6,
+ 0xf8e7, 0xf8e8, 0xf8e9, 0xf8ea, 0xf8eb, 0xf8ec, 0xf8ed, 0xf8ee, 0xf8ef, 0xf8f0,
+ 0xf8f1, 0xf8f2, 0xf8f3, 0xf8f4, 0xf8f5, 0xf8f6, 0xf8f7, 0xf8f8, 0xf8f9, 0xf8fa,
+ 0xf8fb, 0xf8fc, 0xf8fd, 0xf8fe, 0xfe7c, 0xfe7d,
+);
+?>
diff --git a/index.php b/index.php
new file mode 100644
index 0000000..b760bd7
--- /dev/null
+++ b/index.php
@@ -0,0 +1,87 @@
+<?php
+/***************************************************************************
+Copyright (C) 2004 - 2006 Scuttle project
+http://sourceforge.net/projects/scuttle/
+http://scuttle.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; 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
+***************************************************************************/
+
+require_once('header.inc.php');
+$bookmarkservice =& ServiceFactory::getServiceInstance('BookmarkService');
+$templateservice =& ServiceFactory::getServiceInstance('TemplateService');
+$userservice =& ServiceFactory::getServiceInstance('UserService');
+$cacheservice =& ServiceFactory::getServiceInstance('CacheService');
+
+$tplvars = array();
+if (isset($_GET['action'])){
+ if ($_GET['action'] == "logout") {
+ $userservice->logout();
+ $tplvars['msg'] = T_('You have now logged out');
+ }
+}
+
+// Header variables
+$tplVars['loadjs'] = true;
+$tplVars['rsschannels'] = array(
+ array(sprintf(T_('%s: Recent bookmarks'), $sitename), createURL('rss'))
+);
+
+if ($usecache) {
+ // Generate hash for caching on
+ $hashtext = $_SERVER['REQUEST_URI'];
+ if ($userservice->isLoggedOn()) {
+ $hashtext .= $userservice->getCurrentUserID();
+ }
+ $hash = md5($hashtext);
+
+ // Cache for 15 minutes
+ $cacheservice->Start($hash, 900);
+}
+
+// Pagination
+$perpage = getPerPageCount();
+if (isset($_GET['page']) && intval($_GET['page']) > 1) {
+ $page = $_GET['page'];
+ $start = ($page - 1) * $perpage;
+} else {
+ $page = 0;
+ $start = 0;
+}
+
+$dtend = date('Y-m-d H:i:s', strtotime('tomorrow'));
+$dtstart = date('Y-m-d H:i:s', strtotime($dtend .' -'. $defaultRecentDays .' days'));
+
+$tplVars['page'] = $page;
+$tplVars['start'] = $start;
+$tplVars['popCount'] = 30;
+$tplVars['sidebar_blocks'] = array('recent');
+$tplVars['range'] = 'all';
+$tplVars['pagetitle'] = T_('Store, share and tag your favourite links');
+$tplVars['subtitle'] = T_('Recent Bookmarks');
+$tplVars['bookmarkCount'] = $start + 1;
+$bookmarks =& $bookmarkservice->getBookmarks($start, $perpage, NULL, NULL, NULL, getSortOrder(), NULL, $dtstart, $dtend);
+$tplVars['total'] = $bookmarks['total'];
+$tplVars['bookmarks'] =& $bookmarks['bookmarks'];
+$tplVars['cat_url'] = createURL('tags', '%2$s');
+$tplVars['nav_url'] = createURL('index', '%3$s');
+
+$templateservice->loadTemplate('bookmarks.tpl', $tplVars);
+
+if ($usecache) {
+ // Cache output if existing copy has expired
+ $cacheservice->End($hash);
+}
+?> \ No newline at end of file
diff --git a/jsScuttle.php b/jsScuttle.php
new file mode 100644
index 0000000..fbe1e20
--- /dev/null
+++ b/jsScuttle.php
@@ -0,0 +1,141 @@
+<?php
+header('Content-Type: text/javascript');
+require_once('header.inc.php');
+require_once('functions.inc.php');
+$player_root = $root .'includes/player/';
+?>
+
+function _playerAdd(anchor) {
+ var url = anchor.href;
+ var code = '<object type="application/x-shockwave-flash" data="<?php echo $player_root ?>musicplayer_f6.swf?song_url=' + url +'&amp;b_bgcolor=ffffff&amp;b_fgcolor=000000&amp;b_colors=0000ff,0000ff,ff0000,ff0000&buttons=<?php echo $player_root ?>load.swf,<?php echo $player_root ?>play.swf,<?php echo $player_root ?>stop.swf,<?php echo $player_root ?>error.swf" width="14" height="14">';
+ var code = code + '<param name="movie" value="<?php echo $player_root ?>musicplayer.swf?song_url=' + url +'&amp;b_bgcolor=ffffff&amp;b_fgcolor=000000&amp;b_colors=0000ff,0000ff,ff0000,ff0000&amp;buttons=<?php echo $player_root ?>load.swf,<?php echo $player_root ?>play.swf,<?php echo $player_root ?>stop.swf,<?php echo $player_root ?>error.swf" />';
+ var code = code + '</object>';
+ anchor.parentNode.innerHTML = code +' '+ anchor.parentNode.innerHTML;
+}
+
+String.prototype.trim = function() {
+ return this.replace(/^\s+|\s+$/g, '');
+};
+
+var deleted = false;
+function deleteBookmark(ele, input){
+ var confirmDelete = "<span><?php echo T_('Are you sure?') ?> <a href=\"#\" onclick=\"deleteConfirmed(this, " + input + ", \'\'); return false;\"><?php echo T_('Yes'); ?></a> - <a href=\"#\" onclick=\"deleteCancelled(this); return false;\"><?php echo T_('No'); ?></a></span>";
+ ele.style.display = 'none';
+ ele.parentNode.innerHTML = ele.parentNode.innerHTML + confirmDelete;
+}
+
+function deleteCancelled(ele) {
+ var del = previousElement(ele.parentNode);
+ del.style.display = 'inline';
+ ele.parentNode.parentNode.removeChild(ele.parentNode);
+ return false;
+}
+
+function deleteConfirmed(ele, input, response) {
+ if (deleted == false) {
+ deleted = ele.parentNode.parentNode.parentNode;
+ }
+ var post = deleted;
+ post.className = 'xfolkentry deleted';
+ if (response != '') {
+ post.style.display = 'none';
+ deleted = false;
+ } else {
+ loadXMLDoc('<?php echo $root; ?>ajaxDelete.php?id=' + input);
+ }
+}
+
+function previousElement(ele) {
+ ele = ele.previousSibling;
+ while (ele.nodeType != 1) {
+ ele = ele.previousSibling;
+ }
+ return ele;
+}
+
+function isAvailable(input, response){
+ var usernameField = document.getElementById("username");
+ var username = usernameField.value;
+ username = username.toLowerCase();
+ username = username.trim();
+ var availability = document.getElementById("availability");
+ if (username != '') {
+ usernameField.style.backgroundImage = 'url(<?php echo $root; ?>loading.gif)';
+ if (response != '') {
+ usernameField.style.backgroundImage = 'none';
+ if (response == 'true') {
+ availability.className = 'available';
+ availability.innerHTML = '<?php echo T_('Available'); ?>';
+ } else {
+ availability.className = 'not-available';
+ availability.innerHTML = '<?php echo T_('Not Available'); ?>';
+ }
+ } else {
+ loadXMLDoc('<?php echo $root; ?>ajaxIsAvailable.php?username=' + username);
+ }
+ }
+}
+
+function useAddress(ele) {
+ var address = ele.value;
+ if (address != '') {
+ if (address.indexOf(':') < 0) {
+ address = 'http:\/\/' + address;
+ }
+ getTitle(address, null);
+ ele.value = address;
+ }
+}
+
+function getTitle(input, response){
+ var title = document.getElementById('titleField');
+ if (title.value == '') {
+ title.style.backgroundImage = 'url(<?php echo $root; ?>loading.gif)';
+ if (response != null) {
+ title.style.backgroundImage = 'none';
+ title.value = response;
+ } else if (input.indexOf('http') > -1) {
+ loadXMLDoc('<?php echo $root; ?>ajaxGetTitle.php?url=' + input);
+ } else {
+ return false;
+ }
+ }
+}
+
+var xmlhttp;
+function loadXMLDoc(url) {
+ // Native
+ if (window.XMLHttpRequest) {
+ xmlhttp = new XMLHttpRequest();
+ xmlhttp.onreadystatechange = processStateChange;
+ xmlhttp.open("GET", url, true);
+ xmlhttp.send(null);
+ // ActiveX
+ } else if (window.ActiveXObject) {
+ xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
+ if (xmlhttp) {
+ xmlhttp.onreadystatechange = processStateChange;
+ xmlhttp.open("GET", url, true);
+ xmlhttp.send();
+ }
+ }
+}
+
+function processStateChange() {
+ if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
+ response = xmlhttp.responseXML.documentElement;
+ method = response.getElementsByTagName('method')[0].firstChild.data;
+ result = response.getElementsByTagName('result')[0].firstChild.data;
+ eval(method + '(\'\', result)');
+ }
+}
+
+function playerLoad() {
+ var anchors = document.getElementsByTagName('a');
+ var anchors_length = anchors.length;
+ for (var i = 0; i < anchors_length; i++) {
+ if (anchors[i].className == 'taggedlink' && anchors[i].href.match(/\.mp3$/i)) {
+ _playerAdd(anchors[i]);
+ }
+ }
+} \ No newline at end of file
diff --git a/licence.txt b/licence.txt
new file mode 100644
index 0000000..72188c3
--- /dev/null
+++ b/licence.txt
@@ -0,0 +1,340 @@
+ 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. \ No newline at end of file
diff --git a/loading.gif b/loading.gif
new file mode 100644
index 0000000..859126e
--- /dev/null
+++ b/loading.gif
Binary files differ
diff --git a/locales/de_DE/LC_MESSAGES/messages.mo b/locales/de_DE/LC_MESSAGES/messages.mo
new file mode 100644
index 0000000..6c78acb
--- /dev/null
+++ b/locales/de_DE/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/locales/de_DE/LC_MESSAGES/messages.po b/locales/de_DE/LC_MESSAGES/messages.po
new file mode 100644
index 0000000..208f26f
--- /dev/null
+++ b/locales/de_DE/LC_MESSAGES/messages.po
@@ -0,0 +1,808 @@
+# Scuttle de-DE Translation
+# Copyright (C) 2005 - 2006 Scuttle project
+# This file is distributed under the same license as the Scuttle package.
+# Ogee <ogee@ogee.de>
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Scuttle\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2005-04-29 11:17+0200\n"
+"PO-Revision-Date: 2006-03-27 01:41-0800\n"
+"Last-Translator: Marcus Campbell <marcus.campbell@gmail.com>\n"
+"Language-Team: de-DE <ogee@ogee.de>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-Language: German\n"
+"X-Poedit-Country: Germany\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: ..\..\..\about.php:25
+#: ..\..\..\templates\toolbar.inc.php:24
+msgid "About"
+msgstr "Ãœber"
+
+#: ..\..\..\ajaxDelete.php:29
+msgid "You are not allowed to delete this bookmark"
+msgstr "Du hast keine Rechte diesen Favoriten zu löschen"
+
+#: ..\..\..\ajaxDelete.php:33
+msgid "Failed to delete bookmark"
+msgstr "Favorit löschen ist fehlgeschlagen"
+
+#: ..\..\..\alltags.php:50
+msgid "All Tags"
+msgstr "Alle Tags"
+
+#: ..\..\..\alltags.php:59
+#: ..\..\..\populartags.php:63
+#: ..\..\..\profile.php:46
+#: ..\..\..\rss.php:55
+#: ..\..\..\search.php:61
+#: ..\..\..\watch.php:35
+#: ..\..\..\watched.php:62
+#, php-format
+msgid "User with username %s not was not found"
+msgstr "Mitglied %s wurde nicht gefunden"
+
+#: ..\..\..\bookmarks.php:71
+#, php-format
+msgid "User with username %s was not found"
+msgstr "Mitglied %s wurde nicht gefunden"
+
+#: ..\..\..\bookmarks.php:94
+#: ..\..\..\edit.php:44
+msgid "Your bookmark must have a title and an address"
+msgstr "Favoriten Titel und Adresse fehlt"
+
+#: ..\..\..\bookmarks.php:114
+#: ..\..\..\edit.php:58
+msgid "Bookmark saved"
+msgstr "Favorit gespeichert"
+
+#: ..\..\..\bookmarks.php:122
+#: ..\..\..\import.php:99
+#: ..\..\..\importNetscape.php:74
+msgid "There was an error saving your bookmark. Please try again or contact the administrator."
+msgstr "Favorit konnte nicht gespeichert werden. Bitte versuche es erneut oder kontaktiere den Administrator"
+
+#: ..\..\..\bookmarks.php:160
+#: ..\..\..\templates\toolbar.inc.php:13
+msgid "Add a Bookmark"
+msgstr "Favorit hinzufügen"
+
+#: ..\..\..\bookmarks.php:163
+msgid "Add Bookmark"
+msgstr "Favorit hinzufügen"
+
+#: ..\..\..\bookmarks.php:166
+msgid "You must be logged in before you can add bookmarks."
+msgstr "Um Favoriten hinzuzufügen must Du Dich zuerst einloggen"
+
+#: ..\..\..\bookmarks.php:213
+msgid "My Bookmarks"
+msgstr "Meine Favoriten"
+
+#: ..\..\..\edit.php:29
+msgid "Edit Bookmark"
+msgstr "Favorit bearbeiten"
+
+#: ..\..\..\edit.php:34
+#, php-format
+msgid "Bookmark with id %s not was not found"
+msgstr "Favorit mit der id %s wurde nicht gefunden"
+
+#: ..\..\..\edit.php:39
+msgid "You are not allowed to edit this bookmark"
+msgstr "Du hast keine Rechte diesen Favoriten zu bearbeiten"
+
+#: ..\..\..\edit.php:55
+msgid "Error while saving your bookmark"
+msgstr "Fehler beim Speichern Deines Favoriten"
+
+#: ..\..\..\edit.php:78
+msgid "Failed to delete the bookmark"
+msgstr "Fehler beim Löschen dieses Favoriten"
+
+#: ..\..\..\edit.php:88
+#: ..\..\..\templates\editprofile.tpl.php:52
+msgid "Save Changes"
+msgstr "Änderungen speichern"
+
+#: ..\..\..\functions.inc.php:92
+msgid "message_die() was called multiple times."
+msgstr "message_die() wurde öfters aufgerufen."
+
+#: ..\..\..\functions.inc.php:104
+msgid "SQL Error"
+msgstr "SQL Fehler"
+
+#: ..\..\..\functions.inc.php:110
+msgid "Line"
+msgstr "Linie"
+
+#: ..\..\..\functions.inc.php:110
+#: ..\..\..\templates\importDelicious.tpl.php:8
+#: ..\..\..\templates\importNetscape.tpl.php:9
+msgid "File"
+msgstr "Verzeichnis"
+
+#: ..\..\..\functions.inc.php:116
+msgid "Information"
+msgstr "Information"
+
+#: ..\..\..\functions.inc.php:121
+msgid "Critical Information"
+msgstr "Kritische Information"
+
+#: ..\..\..\functions.inc.php:126
+msgid "An error occured"
+msgstr "Ein Fehler ist aufgetreten"
+
+#: ..\..\..\functions.inc.php:129
+msgid "General Error"
+msgstr "Genereller Fehler"
+
+#: ..\..\..\functions.inc.php:137
+msgid "An critical error occured"
+msgstr "Ein kritischer Fehler ist aufgetreten"
+
+#: ..\..\..\functions.inc.php:140
+msgid "Critical Error"
+msgstr "Kritischer Fehler"
+
+#: ..\..\..\functions.inc.php:149
+msgid "DEBUG MODE"
+msgstr "Prüfungs Modus"
+
+#: ..\..\..\history.php:65
+msgid "History"
+msgstr "Verlauf"
+
+#: ..\..\..\history.php:66
+#, php-format
+msgid "History for %s"
+msgstr "Verlauf von %s"
+
+#: ..\..\..\history.php:81
+msgid "Address was not found"
+msgstr "Addresse wurde nicht gefunden"
+
+#: ..\..\..\import.php:41
+msgid "Could not open XML input"
+msgstr "Kann XML Input nicht öffnen"
+
+#: ..\..\..\import.php:45
+#, php-format
+msgid "XML error: %s at line %d"
+msgstr "XML Fehler: %s in Linie %d"
+
+#: ..\..\..\import.php:54
+msgid "Import Bookmarks from del.icio.us"
+msgstr "Importiere Favoriten von del.icio.us"
+
+#: ..\..\..\import.php:86
+#: ..\..\..\importNetscape.php:64
+msgid "You have already submitted this bookmark."
+msgstr "Du hast diesen Favoriten schon eingetragen"
+
+#: ..\..\..\import.php:97
+#: ..\..\..\importNetscape.php:72
+msgid "Bookmark imported."
+msgstr "Favorit importiert"
+
+#: ..\..\..\importNetscape.php:81
+msgid "Import Bookmarks from Browser File"
+msgstr "Importiere Favoriten eines Browsers"
+
+#: ..\..\..\index.php:32
+msgid "You have now logged out"
+msgstr "Du bist jetzt ausgeloggt"
+
+#: ..\..\..\index.php:39
+#, php-format
+msgid "%s: Recent bookmarks"
+msgstr "%s: neue Favoriten"
+
+#: ..\..\..\index.php:72
+msgid "Store, share and tag your favourite links"
+msgstr "Speicher, Teile und Tagge Deine Favoriten"
+
+#: ..\..\..\index.php:73
+msgid "Recent Bookmarks"
+msgstr "Neue Favoriten"
+
+#: ..\..\..\jsScuttle.php:22
+msgid "Are you sure?"
+msgstr "Bist Du sicher?"
+
+#: ..\..\..\jsScuttle.php:22
+msgid "Yes"
+msgstr "Ja"
+
+#: ..\..\..\jsScuttle.php:22
+msgid "No"
+msgstr "Nein"
+
+#: ..\..\..\jsScuttle.php:68
+msgid "Available"
+msgstr "Vorhanden"
+
+#: ..\..\..\jsScuttle.php:71
+msgid "Not Available"
+msgstr "Nicht Vorhanden "
+
+#: ..\..\..\login.php:38
+msgid "The details you have entered are incorrect. Please try again."
+msgstr "Die Details die Du eingetragen hast sind nicht korrekt. Bitte versuche es erneut."
+
+#: ..\..\..\login.php:48
+#: ..\..\..\templates\login.tpl.php:26
+#: ..\..\..\templates\toolbar.inc.php:28
+msgid "Log In"
+msgstr "Login"
+
+#: ..\..\..\password.php:31
+msgid "You must enter your username."
+msgstr "Du must Deinen Mitgliedsnamen eingeben"
+
+#: ..\..\..\password.php:35
+msgid "You must enter your <abbr title=\"electronic mail\">e-mail</abbr> address."
+msgstr "Du musst Deine <abbr title=\"electronic mail\">E-Mail</abbr> Addresse angeben."
+
+#: ..\..\..\password.php:42
+msgid "No matches found for that username."
+msgstr "Keine Resultate zu diesem Mitgliedsnamen gefunden"
+
+#: ..\..\..\password.php:45
+msgid "No matches found for that combination of username and <abbr title=\"electronic mail\">e-mail</abbr> address."
+msgstr "Keine Resultate gefunden für den Mitgliedsnamen und diese <abbr title=\"electronic mail\">e-mail</abbr> Addresse."
+
+#: ..\..\..\password.php:53
+msgid "There was an error while generating your new password. Please try again."
+msgstr "Fehler beim generieren des Passwortes. Bitte versuche es erneut."
+
+#: ..\..\..\password.php:57
+msgid "Your new password is:"
+msgstr "Dein neues Passwort:"
+
+#: ..\..\..\password.php:57
+msgid "To keep your bookmarks secure, you should change this password in your profile the next time you log in."
+msgstr "Um Deine Favoriten sicher zu bewahren, solltest Du Dein Passwort beim nächsten Login in Deinem Profil ändern."
+
+#: ..\..\..\password.php:60
+#, php-format
+msgid "%s Account Information"
+msgstr "%s Account Information"
+
+#: ..\..\..\password.php:62
+#, php-format
+msgid "New password generated and sent to %s"
+msgstr "Neues Passwort wurde generiert und an %s gesendet"
+
+#: ..\..\..\password.php:69
+msgid "Forgotten Password"
+msgstr "Vergessenes Passwort"
+
+#: ..\..\..\populartags.php:54
+#: ..\..\..\templates\dynamictags.inc.php:101
+#: ..\..\..\templates\sidebar.block.common.php:9
+#: ..\..\..\templates\sidebar.block.popular.php:15
+#: ..\..\..\templates\sidebar.block.recent.php:25
+msgid "Popular Tags"
+msgstr "Populäre Tags"
+
+#: ..\..\..\profile.php:54
+#: ..\..\..\watched.php:114
+msgid "Username was not specified"
+msgstr "Mitgliedsname wurde nicht spezifiziert"
+
+#: ..\..\..\profile.php:60
+msgid "My Profile"
+msgstr "Mein Profil"
+
+#: ..\..\..\profile.php:62
+#: ..\..\..\templates\sidebar.block.profile.php:12
+msgid "Profile"
+msgstr "Profil"
+
+#: ..\..\..\profile.php:80
+msgid "Password and confirmation do not match."
+msgstr "Passwort und Bestätigung passen nicht zusammen."
+
+#: ..\..\..\profile.php:84
+msgid "Password must be at least 6 characters long."
+msgstr "Passwort muss mindestens 6 Zeichen lang sein."
+
+#: ..\..\..\profile.php:88
+msgid "E-mail address is not valid."
+msgstr "E-Mail Adresse ist unzulässig."
+
+#: ..\..\..\profile.php:92
+msgid "An error occurred while saving your changes."
+msgstr "Eine Fehler trat beim Speichern Deiner Änderungen auf."
+
+#: ..\..\..\profile.php:94
+msgid "Changes saved."
+msgstr "Änderungen gespeichert."
+
+#: ..\..\..\register.php:33
+msgid "You <em>must</em> enter a username, password and e-mail address."
+msgstr "Du <em>musst</em> einen Mitgliedsnamen, Passwort und <abbr title=\"electronic mail\">eine E-Mail</abbr> Addresse angeben."
+
+#: ..\..\..\register.php:37
+msgid "This username already exists, please make another choice."
+msgstr "Dieser Mitgliedsname existiert schon. Bitte versuche einen anderen."
+
+#: ..\..\..\register.php:41
+msgid "E-mail address is not valid. Please try again."
+msgstr "E-Mail Adresse ist unzulässig. Bitte versuche es erneut."
+
+#: ..\..\..\register.php:50
+msgid "You have successfully registered. Enjoy!"
+msgstr "Du hast Dich erfolgreich registriert. Viel Spass!"
+
+#: ..\..\..\register.php:52
+msgid "Registration failed. Please try again."
+msgstr "Registrierung fehlgeschlagen. Bitte versuche es erneut."
+
+#: ..\..\..\register.php:57
+#: ..\..\..\templates\register.tpl.php:32
+#: ..\..\..\templates\toolbar.inc.php:27
+msgid "Register"
+msgstr "Registrieren"
+
+#: ..\..\..\search.inc.php:29
+#: ..\..\..\search.inc.php:57
+msgid "Search"
+msgstr "Suche in"
+
+#: ..\..\..\search.inc.php:35
+msgid "this user's bookmarks"
+msgstr "Favoriten dieses Benutzers"
+
+#: ..\..\..\search.inc.php:40
+msgid "my bookmarks"
+msgstr "Meine Favoriten"
+
+#: ..\..\..\search.inc.php:41
+msgid "my watchlist"
+msgstr "Meine Beobachtungsliste"
+
+#: ..\..\..\search.inc.php:45
+msgid "all bookmarks"
+msgstr "Alle Favoriten"
+
+#: ..\..\..\search.inc.php:48
+msgid "for"
+msgstr "nach"
+
+#: ..\..\..\search.php:91
+#: ..\..\..\search.php:128
+msgid "Search Bookmarks"
+msgstr "Suche Favoriten"
+
+#: ..\..\..\search.php:97
+msgid "Search Results"
+msgstr "Suche Resultate"
+
+#: ..\..\..\tags.php:38
+#: ..\..\..\templates\editbookmark.tpl.php:44
+#: ..\..\..\templates\sidebar.block.profile.php:13
+msgid "Tags"
+msgstr "Tags"
+
+#: ..\..\..\watch.php:79
+#, php-format
+msgid "%s Bookmarks"
+msgstr "%s Favoriten"
+
+#: ..\..\..\watch.php:84
+msgid "User removed from your watchlist"
+msgstr "Mitglied wurde von Deiner Beobachtungsliste entfernt"
+
+#: ..\..\..\watch.php:86
+msgid "User added to your watchlist"
+msgstr "Mitglied wurde zu Deiner Favoritenliste hinzugefügt"
+
+#: ..\..\..\watched.php:105
+msgid "My Watchlist"
+msgstr "Meine Beobachtungsliste"
+
+#: ..\..\..\watched.php:107
+#: ..\..\..\templates\sidebar.block.profile.php:14
+#: ..\..\..\templates\toolbar.inc.php:12
+msgid "Watchlist"
+msgstr "Beobachtungsliste"
+
+#: ..\..\..\templates\about.tpl.php:6
+msgid "<strong>Store</strong> all your favourite links in one place, accessible from anywhere."
+msgstr "<strong>Speicher</strong> alle Deine Webseiten-Favoriten an einem Ort, von überall erreichbar."
+
+#: ..\..\..\templates\about.tpl.php:7
+msgid "<strong>Share</strong> your bookmarks with everyone, with friends on your watchlist or just keep them private."
+msgstr "<strong>Teile</strong> Deine Webseiten-Favoriten mit Anderen, Deinen Freunden oder speichere sie für Dich privat."
+
+#: ..\..\..\templates\about.tpl.php:8
+msgid "<strong>Tag</strong> your bookmarks with as many labels as you want, instead of wrestling with folders."
+msgstr "<strong>Tagge</strong> Deine Webseiten-Favoriten mit so vielen Schlagwörtern wie Du möchtest, ansatt sie in unübersichtlichen Verzeichnissen zu speichern."
+
+#: ..\..\..\templates\about.tpl.php:9
+#, php-format
+msgid "<strong><a href=\"register.php\">Register now</a></strong> to start using %s!"
+msgstr "<strong><a href=\"register.php\">Registriere Dich jetzt</a></strong> und verwende %s!"
+
+#: ..\..\..\templates\about.tpl.php:12
+msgid "Geek Stuff"
+msgstr "Geek Stuff"
+
+#: ..\..\..\templates\about.tpl.php:14
+#, php-format
+msgid "%s is based on <a href=\"http://sourceforge.net/projects/scuttle/\">an open-source project</a> licensed under the <a href=\"http://www.gnu.org/copyleft/gpl.html\"><acronym title=\"GNU's Not Unix\">GNU</acronym> General Public License</a>. This means you can host it on your own web server for free, whether it is on the Internet, a private network or just your own computer."
+msgstr "%s basiert auf <a href=\"http://sourceforge.net/projects/scuttle/\">einem Open-Source Projekt</a> lizensiert unter der <a href=\"http://www.gnu.org/copyleft/gpl.html\"><acronym title=\"GNU's Not Unix\">GNU</acronym> General Public Lizenz</a>. Das bedeutet, Du kannst es kostenlos auf Deinem Server im Internet verwenden, einem privaten Netzwerk oder auf Deinem eigenen Computer."
+
+#: ..\..\..\templates\about.tpl.php:15
+#, php-format
+msgid "%1$s supports most of the <a href=\"http://del.icio.us/doc/api\">del.icio.us <abbr title=\"Application Programming Interface\">API</abbr></a>. Almost all of the neat tools made for that system can be modified to work with %1$s instead. If you find a tool that won't let you change the API address, ask the creator to add this setting. You never know, they might just do it."
+msgstr "%1$s unterstützt die <a href=\"http://del.icio.us/doc/api\">del.icio.us <abbr title=\"Application Programming Interface\">API</abbr></a>. Fast alle del.icio.us Tools können so modifiziert werden das %1$s sie verwenden kann. Findest Du ein inkompatibles Tool, so Frage beim entsprechenden Service nach. Du weisst nie - vielleicht wird Dir geholfen."
+
+#: ..\..\..\templates\bookmarks.tpl.php:17
+#: ..\..\..\templates\tags.tpl.php:7
+msgid "Sort by:"
+msgstr "Sortieren nach:"
+
+#: ..\..\..\templates\bookmarks.tpl.php:18
+msgid "Date"
+msgstr "Datum"
+
+#: ..\..\..\templates\bookmarks.tpl.php:19
+#: ..\..\..\templates\editbookmark.tpl.php:34
+msgid "Title"
+msgstr "Titel"
+
+#: ..\..\..\templates\bookmarks.tpl.php:23
+msgid "URL"
+msgstr "URL"
+
+#: ..\..\..\templates\bookmarks.tpl.php:60
+msgid "Edit"
+msgstr "Bearbeiten"
+
+#: ..\..\..\templates\bookmarks.tpl.php:60
+msgid "Delete"
+msgstr "Löschen"
+
+#: ..\..\..\templates\bookmarks.tpl.php:66
+msgid "by"
+msgstr "von"
+
+#: ..\..\..\templates\bookmarks.tpl.php:78
+#, php-format
+msgid " and %s1 other%s"
+msgstr "und %s1 andere%s"
+
+#: ..\..\..\templates\bookmarks.tpl.php:81
+#, php-format
+msgid " and %2$s%1$s others%3$s"
+msgstr "und %2$s%1$s andere%3$s"
+
+#: ..\..\..\templates\bookmarks.tpl.php:90
+msgid "Copy"
+msgstr "Kopieren"
+
+#: ..\..\..\templates\bookmarks.tpl.php:136
+#: ..\..\..\templates\bookmarks.tpl.php:142
+msgid "First"
+msgstr "Erste"
+
+#: ..\..\..\templates\bookmarks.tpl.php:137
+#: ..\..\..\templates\bookmarks.tpl.php:143
+msgid "Previous"
+msgstr "Neuer"
+
+#: ..\..\..\templates\bookmarks.tpl.php:150
+#: ..\..\..\templates\bookmarks.tpl.php:153
+msgid "Next"
+msgstr "Älter"
+
+#: ..\..\..\templates\bookmarks.tpl.php:151
+#: ..\..\..\templates\bookmarks.tpl.php:154
+msgid "Last"
+msgstr "Letzte"
+
+#: ..\..\..\templates\bookmarks.tpl.php:156
+#, php-format
+msgid "Page %d of %d"
+msgstr "Seite %d von %d"
+
+#: ..\..\..\templates\bookmarks.tpl.php:160
+msgid "No bookmarks available"
+msgstr "Keine Favoriten verfügbar"
+
+#: ..\..\..\templates\dynamictags.inc.php:108
+#: ..\..\..\templates\sidebar.block.common.php:15
+#: ..\..\..\templates\sidebar.block.popular.php:21
+#: ..\..\..\templates\sidebar.block.recent.php:20
+#: ..\..\..\templates\tags.tpl.php:16
+msgid "bookmark"
+msgid_plural "bookmarks"
+msgstr[0] "Favorit"
+msgstr[1] "Favoriten"
+
+#: ..\..\..\templates\editbookmark.tpl.php:29
+msgid "Address"
+msgstr "Adresse"
+
+#: ..\..\..\templates\editbookmark.tpl.php:31
+#: ..\..\..\templates\editbookmark.tpl.php:36
+#: ..\..\..\templates\editprofile.tpl.php:31
+msgid "Required"
+msgstr "Erforderlich"
+
+#: ..\..\..\templates\editbookmark.tpl.php:39
+#: ..\..\..\templates\editprofile.tpl.php:47
+#: ..\..\..\templates\profile.tpl.php:28
+msgid "Description"
+msgstr "Beschreibung"
+
+#: ..\..\..\templates\editbookmark.tpl.php:46
+msgid "Comma-separated"
+msgstr "Mit Komma trennen"
+
+#: ..\..\..\templates\editbookmark.tpl.php:49
+#: ..\..\..\templates\importDelicious.tpl.php:15
+#: ..\..\..\templates\importNetscape.tpl.php:16
+msgid "Privacy"
+msgstr "Status"
+
+#: ..\..\..\templates\editbookmark.tpl.php:52
+#: ..\..\..\templates\importDelicious.tpl.php:18
+#: ..\..\..\templates\importNetscape.tpl.php:19
+msgid "Public"
+msgstr "Öffentlich"
+
+#: ..\..\..\templates\editbookmark.tpl.php:53
+#: ..\..\..\templates\importDelicious.tpl.php:19
+#: ..\..\..\templates\importNetscape.tpl.php:20
+msgid "Shared with Watch List"
+msgstr "Zur Beobachtungsliste hinzufügen"
+
+#: ..\..\..\templates\editbookmark.tpl.php:54
+#: ..\..\..\templates\importDelicious.tpl.php:20
+#: ..\..\..\templates\importNetscape.tpl.php:21
+msgid "Private"
+msgstr "Privat"
+
+#: ..\..\..\templates\editbookmark.tpl.php:66
+msgid "Delete Bookmark"
+msgstr "Favorit löschen"
+
+#: ..\..\..\templates\editbookmark.tpl.php:93
+msgid "Bookmarklet"
+msgstr "Bookmarklet"
+
+#: ..\..\..\templates\editbookmark.tpl.php:94
+#, php-format
+msgid "Drag one of the following bookmarklets to your browser's bookmarks and click it whenever you want to add the page you are on to %s"
+msgstr "Ziehe einen der folgenden Bookmarklets in Deine Browser Favoriten und klicke es an wann immer Du eine Seite zu %s hinzufügen möchtest"
+
+#: ..\..\..\templates\editbookmark.tpl.php:106
+#, php-format
+msgid "Post to %s"
+msgstr "Hinzufügen zu %s"
+
+#: ..\..\..\templates\editbookmark.tpl.php:107
+#, php-format
+msgid "Post to %s (Pop-up)"
+msgstr "Hinzufügen zu %s (Pop-up)"
+
+#: ..\..\..\templates\editbookmark.tpl.php:111
+#: ..\..\..\templates\importDelicious.tpl.php:26
+#: ..\..\..\templates\importNetscape.tpl.php:27
+msgid "Import"
+msgstr "Importieren"
+
+#: ..\..\..\templates\editbookmark.tpl.php:113
+msgid "Import bookmarks from bookmark file"
+msgstr "Importiere Favoriten aus einer Datei"
+
+#: ..\..\..\templates\editbookmark.tpl.php:113
+msgid "Internet Explorer, Mozilla Firefox and Netscape"
+msgstr "Internet Explorer, Mozilla Firefox und Netscape"
+
+#: ..\..\..\templates\editbookmark.tpl.php:114
+msgid "Import bookmarks from del.icio.us"
+msgstr "Importiere Favoriten aus del.icio.us"
+
+#: ..\..\..\templates\editprofile.tpl.php:10
+msgid "Account Details"
+msgstr "Account Details"
+
+#: ..\..\..\templates\editprofile.tpl.php:14
+#: ..\..\..\templates\login.tpl.php:15
+#: ..\..\..\templates\password.tpl.php:10
+#: ..\..\..\templates\profile.tpl.php:7
+#: ..\..\..\templates\register.tpl.php:16
+msgid "Username"
+msgstr "Mitgliedsname"
+
+#: ..\..\..\templates\editprofile.tpl.php:19
+msgid "New Password"
+msgstr "Neues Passwort"
+
+#: ..\..\..\templates\editprofile.tpl.php:24
+msgid "Confirm Password"
+msgstr "Passwort bestätigen"
+
+#: ..\..\..\templates\editprofile.tpl.php:29
+#: ..\..\..\templates\register.tpl.php:26
+msgid "E-mail"
+msgstr "E-Mail"
+
+#: ..\..\..\templates\editprofile.tpl.php:35
+msgid "Personal Details"
+msgstr "Persönliche Details"
+
+#: ..\..\..\templates\editprofile.tpl.php:39
+#: ..\..\..\templates\profile.tpl.php:12
+msgid "Name"
+msgstr "Name"
+
+#: ..\..\..\templates\editprofile.tpl.php:43
+#: ..\..\..\templates\profile.tpl.php:18
+msgid "Homepage"
+msgstr "Homepage"
+
+#: ..\..\..\templates\error.404.tpl.php:5
+msgid "Not Found"
+msgstr "Nicht gefunden"
+
+#: ..\..\..\templates\error.404.tpl.php:6
+msgid "The requested URL was not found on this server"
+msgstr "Die URL konnte auf diesem Server nicht gefunden werden"
+
+#: ..\..\..\templates\error.500.tpl.php:5
+msgid "General server error"
+msgstr "Genereller Server Fehler"
+
+#: ..\..\..\templates\error.500.tpl.php:6
+msgid "The requested URL could not be processed"
+msgstr "Die URL konnte nicht fortgeführt werden"
+
+#: ..\..\..\templates\importDelicious.tpl.php:33
+msgid "Log in to the <a href=\"http://del.icio.us/api/posts/all\">export page at del.icio.us</a>"
+msgstr "Logge Dich ein auf die <a href=\"http://del.icio.us/api/posts/all\">del.icio.us Export Seite</a>"
+
+#: ..\..\..\templates\importDelicious.tpl.php:34
+msgid "Save the resulting <abbr title=\"Extensible Markup Language\">XML</abbr> file to your computer"
+msgstr "Speicher die resultierende <abbr title=\"Extensible Markup Language\">XML</abbr> Datei auf Deinem Computer"
+
+#: ..\..\..\templates\importDelicious.tpl.php:35
+msgid "Click <kbd>Browse...</kbd> to find this file on your computer. The maximum size the file can be is 1MB"
+msgstr "Klicke <kbd>Browse...</kbd> um die Datei auf Deinem Computer zu finden. Dateigröße darf nicht größer sein als 1MB"
+
+#: ..\..\..\templates\importDelicious.tpl.php:36
+#: ..\..\..\templates\importNetscape.tpl.php:43
+msgid "Select the default privacy setting for your imported bookmarks"
+msgstr "Wähle den Status für Deine importierten Favoriten"
+
+#: ..\..\..\templates\importDelicious.tpl.php:37
+#: ..\..\..\templates\importNetscape.tpl.php:44
+msgid "Click <kbd>Import</kbd> to start importing the bookmarks; it may take a minute"
+msgstr "Klicke <kbd>Importieren</kbd> um Deine Favoriten zu importieren; das kann eine Weile dauern"
+
+#: ..\..\..\templates\importNetscape.tpl.php:32
+msgid "Instructions"
+msgstr "Anleitung"
+
+#: ..\..\..\templates\importNetscape.tpl.php:35
+msgid "Export your bookmarks from your browser to a file"
+msgstr "Exportiere Deine Browser Bookmarks in eine Datei"
+
+#: ..\..\..\templates\importNetscape.tpl.php:37
+msgid "Internet Explorer: <kbd>File &gt; Import and Export... &gt; Export Favorites"
+msgstr "Internet Explorer: <kbd>Datei &gt; Importieren und Exportieren... &gt; Exportiere Favoriten"
+
+#: ..\..\..\templates\importNetscape.tpl.php:38
+msgid "Mozilla Firefox: <kbd>Bookmarks &gt; Manage Bookmarks... &gt; File &gt; Export..."
+msgstr "Mozilla Firefox: <kbd>Favoriten &gt; Manage Favoriten... &gt; Datei &gt; Exportieren..."
+
+#: ..\..\..\templates\importNetscape.tpl.php:39
+msgid "Netscape: <kbd>Bookmarks &gt; Manage Bookmarks... &gt; Tools &gt; Export..."
+msgstr "Netscape: <kbd>Favoriten &gt; Manage Favoriten... &gt; Tools &gt; Exportieren..."
+
+#: ..\..\..\templates\importNetscape.tpl.php:42
+msgid "Click <kbd>Browse...</kbd> to find the saved bookmark file on your computer. The maximum size the file can be is 1MB"
+msgstr "Klicke <kbd>Browse...</kbd> um die gespeicherte Favoriten Datei auf Deinem Computer zu finden. Dateigröße darf nicht größer sein als 1MB"
+
+#: ..\..\..\templates\login.tpl.php:20
+#: ..\..\..\templates\register.tpl.php:21
+msgid "Password"
+msgstr "Passwort"
+
+#: ..\..\..\templates\login.tpl.php:22
+msgid "Don't ask for my password for 2 weeks"
+msgstr " 2 Wochen lang nicht nach meinem Passwort fragen"
+
+#: ..\..\..\templates\login.tpl.php:30
+msgid "Forgotten your password?"
+msgstr "Passwort vergessen?"
+
+#: ..\..\..\templates\password.tpl.php:5
+#, php-format
+msgid "If you have forgotten your password, %s can generate a new one. Enter the username and e-mail address of your account into the form below and we will e-mail your new password to you."
+msgstr "Du hast Dein Passwort vergessen? Kein Problem - %s kann ein Neues für Dich generieren. Gebe Deine Email Adresse und Mitgliedsnamen ein und Dir wird ein neues Passwort zugesendet."
+
+#: ..\..\..\templates\password.tpl.php:14
+msgid "<abbr title=\"Electronic mail\">E-mail</abbr>"
+msgstr "<abbr title=\"Elektronische Mail\">E-mail</abbr>"
+
+#: ..\..\..\templates\password.tpl.php:19
+msgid "Generate Password"
+msgstr "Neues Passwort erstellen"
+
+#: ..\..\..\templates\profile.tpl.php:23
+msgid "Member Since"
+msgstr "Mitglied seit"
+
+#: ..\..\..\templates\profile.tpl.php:35
+#: ..\..\..\templates\sidebar.block.watchlist.php:8
+msgid "Watching"
+msgstr "Beobachten"
+
+#: ..\..\..\templates\profile.tpl.php:50
+msgid "Watched By"
+msgstr "Beobachtet von"
+
+#: ..\..\..\templates\register.tpl.php:11
+#, php-format
+msgid "Sign up here to create a free %s account. All the information requested below is required"
+msgstr "Hier kannst Du Dich kostenlos für einen %s Account registrieren. Fülle dafür die folgenden Formularfelder vollständig aus."
+
+#: ..\..\..\templates\rss.tpl.php:9
+#, php-format
+msgid "Recent bookmarks posted to %s"
+msgstr "Neue Favoriten in %s hinzugefügt"
+
+#: ..\..\..\templates\rss.tpl.php:17
+#: ..\..\..\templates\rss.tpl.php:19
+msgid "No bookmarks found"
+msgstr "Keine Favoriten gefunden"
+
+#: ..\..\..\templates\sidebar.block.recent.php:15
+msgid "Recent Tags"
+msgstr "Neueste Tags"
+
+#: ..\..\..\templates\sidebar.block.related.php:15
+msgid "Related Tags"
+msgstr "Verwandte Tags"
+
+#: ..\..\..\templates\sidebar.block.watchstatus.php:10
+msgid "Remove from Watchlist"
+msgstr "Aus Beobachtungsliste entfernen"
+
+#: ..\..\..\templates\sidebar.block.watchstatus.php:12
+msgid "Add to Watchlist"
+msgstr "Zur Beobachtungsliste hinzufügen"
+
+#: ..\..\..\templates\sidebar.block.watchstatus.php:17
+msgid "Actions"
+msgstr "Aktionen"
+
+#: ..\..\..\templates\tags.tpl.php:8
+msgid "Alphabet"
+msgstr "Alphabet"
+
+#: ..\..\..\templates\tags.tpl.php:9
+msgid "Popularity"
+msgstr "Popularität"
+
+#: ..\..\..\templates\toolbar.inc.php:11
+msgid "Bookmarks"
+msgstr "Favoriten"
+
+#: ..\..\..\templates\toolbar.inc.php:16
+msgid "Log Out"
+msgstr "Logout"
+
diff --git a/locales/dk_DK/LC_MESSAGES/messages.mo b/locales/dk_DK/LC_MESSAGES/messages.mo
new file mode 100644
index 0000000..a46c715
--- /dev/null
+++ b/locales/dk_DK/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/locales/dk_DK/LC_MESSAGES/messages.po b/locales/dk_DK/LC_MESSAGES/messages.po
new file mode 100644
index 0000000..3d06851
--- /dev/null
+++ b/locales/dk_DK/LC_MESSAGES/messages.po
@@ -0,0 +1,808 @@
+# Scuttle dk-DK Translation
+# Copyright (C) 2006 Scuttle project
+# This file is distributed under the same license as the Scuttle package.
+# Nicki Brøchner <nicki.brochner@gmail.com>
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Scuttle\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2005-04-29 11:17+0200\n"
+"PO-Revision-Date: 2006-04-16 22:04-0800\n"
+"Last-Translator: Marcus Campbell <marcus.campbell@gmail.com>\n"
+"Language-Team: dk-DK <Nicki.brochner@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-Language: Danish\n"
+"X-Poedit-Country: DENMARK\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: ..\..\..\about.php:25
+#: ..\..\..\templates\toolbar.inc.php:24
+msgid "About"
+msgstr "Om programmet"
+
+#: ..\..\..\ajaxDelete.php:29
+msgid "You are not allowed to delete this bookmark"
+msgstr "Du har ikke tilladelse til at slette dette bogmærke"
+
+#: ..\..\..\ajaxDelete.php:33
+msgid "Failed to delete bookmark"
+msgstr "Kunne ikke slette bogmærket"
+
+#: ..\..\..\alltags.php:50
+msgid "All Tags"
+msgstr "Alle mærker"
+
+#: ..\..\..\alltags.php:59
+#: ..\..\..\populartags.php:63
+#: ..\..\..\profile.php:46
+#: ..\..\..\rss.php:55
+#: ..\..\..\search.php:61
+#: ..\..\..\watch.php:35
+#: ..\..\..\watched.php:62
+#, php-format
+msgid "User with username %s not was not found"
+msgstr "Bruger med brugernavn %s kunne ikke findes"
+
+#: ..\..\..\bookmarks.php:71
+#, php-format
+msgid "User with username %s was not found"
+msgstr "Bruger med brugernavn %s kunne ikke findes"
+
+#: ..\..\..\bookmarks.php:94
+#: ..\..\..\edit.php:44
+msgid "Your bookmark must have a title and an address"
+msgstr "Dit bogmærke skal have både en titel og en adresse"
+
+#: ..\..\..\bookmarks.php:114
+#: ..\..\..\edit.php:58
+msgid "Bookmark saved"
+msgstr "Bogmærke gemt"
+
+#: ..\..\..\bookmarks.php:122
+#: ..\..\..\import.php:99
+#: ..\..\..\importNetscape.php:74
+msgid "There was an error saving your bookmark. Please try again or contact the administrator."
+msgstr "Der opstod en fejl, ved forsøg på at gemme dit bogmærke. Prøv venligst igen eller kontakt Administrator"
+
+#: ..\..\..\bookmarks.php:160
+#: ..\..\..\templates\toolbar.inc.php:13
+msgid "Add a Bookmark"
+msgstr "Tilføj et bogmærke"
+
+#: ..\..\..\bookmarks.php:163
+msgid "Add Bookmark"
+msgstr "Tilføj bogmærke"
+
+#: ..\..\..\bookmarks.php:166
+msgid "You must be logged in before you can add bookmarks."
+msgstr "Du skal være logget ind før du kan tilføje bogmærker"
+
+#: ..\..\..\bookmarks.php:213
+msgid "My Bookmarks"
+msgstr "Mine bogmærker"
+
+#: ..\..\..\edit.php:29
+msgid "Edit Bookmark"
+msgstr "Rediger bogmærker"
+
+#: ..\..\..\edit.php:34
+#, php-format
+msgid "Bookmark with id %s not was not found"
+msgstr "Bogmærke med id %s kunne ikke findes"
+
+#: ..\..\..\edit.php:39
+msgid "You are not allowed to edit this bookmark"
+msgstr "Du har ikke tilladelse til at redigere dette bogmærke"
+
+#: ..\..\..\edit.php:55
+msgid "Error while saving your bookmark"
+msgstr "Der opstod en fejl, ved forsøg på at gemme dit bogmærke."
+
+#: ..\..\..\edit.php:78
+msgid "Failed to delete the bookmark"
+msgstr "Kunne ikke slette bogmærket"
+
+#: ..\..\..\edit.php:88
+#: ..\..\..\templates\editprofile.tpl.php:52
+msgid "Save Changes"
+msgstr "Gem ændringer"
+
+#: ..\..\..\functions.inc.php:92
+msgid "message_die() was called multiple times."
+msgstr "message_die() blev kaldt flere gange"
+
+#: ..\..\..\functions.inc.php:104
+msgid "SQL Error"
+msgstr "SQL fejl"
+
+#: ..\..\..\functions.inc.php:110
+msgid "Line"
+msgstr "Line"
+
+#: ..\..\..\functions.inc.php:110
+#: ..\..\..\templates\importDelicious.tpl.php:8
+#: ..\..\..\templates\importNetscape.tpl.php:9
+msgid "File"
+msgstr "Filer"
+
+#: ..\..\..\functions.inc.php:116
+msgid "Information"
+msgstr "Information"
+
+#: ..\..\..\functions.inc.php:121
+msgid "Critical Information"
+msgstr "Kritisk information"
+
+#: ..\..\..\functions.inc.php:126
+msgid "An error occured"
+msgstr "En fejl opstod"
+
+#: ..\..\..\functions.inc.php:129
+msgid "General Error"
+msgstr "General fejl"
+
+#: ..\..\..\functions.inc.php:137
+msgid "An critical error occured"
+msgstr "En kritisk fejl opstod"
+
+#: ..\..\..\functions.inc.php:140
+msgid "Critical Error"
+msgstr "Kritisk fejl"
+
+#: ..\..\..\functions.inc.php:149
+msgid "DEBUG MODE"
+msgstr "DEBUG MODE"
+
+#: ..\..\..\history.php:65
+msgid "History"
+msgstr "Historie"
+
+#: ..\..\..\history.php:66
+#, php-format
+msgid "History for %s"
+msgstr "Historie for %s"
+
+#: ..\..\..\history.php:81
+msgid "Address was not found"
+msgstr "Adressen kunne ikke findes"
+
+#: ..\..\..\import.php:41
+msgid "Could not open XML input"
+msgstr "Kunne ikke åbne XML input"
+
+#: ..\..\..\import.php:45
+#, php-format
+msgid "XML error: %s at line %d"
+msgstr "XLM fejl: %s i line %d"
+
+#: ..\..\..\import.php:54
+msgid "Import Bookmarks from del.icio.us"
+msgstr "Importere bogmærker fra del.icio.us"
+
+#: ..\..\..\import.php:86
+#: ..\..\..\importNetscape.php:64
+msgid "You have already submitted this bookmark."
+msgstr "Du har allerede tilføjet dette bogmærke"
+
+#: ..\..\..\import.php:97
+#: ..\..\..\importNetscape.php:72
+msgid "Bookmark imported."
+msgstr "Bogmærke importeret"
+
+#: ..\..\..\importNetscape.php:81
+msgid "Import Bookmarks from Browser File"
+msgstr "Importere bogmærker fra browser"
+
+#: ..\..\..\index.php:32
+msgid "You have now logged out"
+msgstr "Du er nu logget ud"
+
+#: ..\..\..\index.php:39
+#, php-format
+msgid "%s: Recent bookmarks"
+msgstr "%s: Seneste bogmærker"
+
+#: ..\..\..\index.php:72
+msgid "Store, share and tag your favourite links"
+msgstr "Gem, del og mærk dine favorit links"
+
+#: ..\..\..\index.php:73
+msgid "Recent Bookmarks"
+msgstr "Seneste bogmærker"
+
+#: ..\..\..\jsScuttle.php:22
+msgid "Are you sure?"
+msgstr "Er du sikker?"
+
+#: ..\..\..\jsScuttle.php:22
+msgid "Yes"
+msgstr "Ja"
+
+#: ..\..\..\jsScuttle.php:22
+msgid "No"
+msgstr "Nej"
+
+#: ..\..\..\jsScuttle.php:68
+msgid "Available"
+msgstr "Tilgængelig"
+
+#: ..\..\..\jsScuttle.php:71
+msgid "Not Available"
+msgstr "Ikke tilgængelig"
+
+#: ..\..\..\login.php:38
+msgid "The details you have entered are incorrect. Please try again."
+msgstr "Detaljerne du har indtastet er forkerte. Prøv venligst igen."
+
+#: ..\..\..\login.php:48
+#: ..\..\..\templates\login.tpl.php:26
+#: ..\..\..\templates\toolbar.inc.php:28
+msgid "Log In"
+msgstr "Log ind"
+
+#: ..\..\..\password.php:31
+msgid "You must enter your username."
+msgstr "Du skal indtaste dit brugernavn"
+
+#: ..\..\..\password.php:35
+msgid "You must enter your <abbr title=\"electronic mail\">e-mail</abbr> address."
+msgstr "Du skal indtaste din <abbr title=\"Elektronisk post\">E-mail</abbr> adresse."
+
+#: ..\..\..\password.php:42
+msgid "No matches found for that username."
+msgstr "Søgning gav igen resultat på det brugernavn."
+
+#: ..\..\..\password.php:45
+msgid "No matches found for that combination of username and <abbr title=\"electronic mail\">e-mail</abbr> address."
+msgstr "Søgning gav igen resultat på den kombination af brugernavn og <abbr title=\"elektronisk post\">e-mail</abbr> adresse."
+
+#: ..\..\..\password.php:53
+msgid "There was an error while generating your new password. Please try again."
+msgstr "Der opstod en fejl under genereringen af dit nye kodeord. Prøv venligst igen."
+
+#: ..\..\..\password.php:57
+msgid "Your new password is:"
+msgstr "Dit nye kodeord er:"
+
+#: ..\..\..\password.php:57
+msgid "To keep your bookmarks secure, you should change this password in your profile the next time you log in."
+msgstr "FFor at bevare dine bogmærker sikrere, bør du skifte dette kodeord i din profil næste gang du logger ind."
+
+#: ..\..\..\password.php:60
+#, php-format
+msgid "%s Account Information"
+msgstr "%s Konto oplysninger"
+
+#: ..\..\..\password.php:62
+#, php-format
+msgid "New password generated and sent to %s"
+msgstr "Nyt kodeord er blevet genereret og sendt til %s"
+
+#: ..\..\..\password.php:69
+msgid "Forgotten Password"
+msgstr "Glemt kodeord"
+
+#: ..\..\..\populartags.php:54
+#: ..\..\..\templates\dynamictags.inc.php:101
+#: ..\..\..\templates\sidebar.block.common.php:9
+#: ..\..\..\templates\sidebar.block.popular.php:15
+#: ..\..\..\templates\sidebar.block.recent.php:25
+msgid "Popular Tags"
+msgstr "Populære mærkater"
+
+#: ..\..\..\profile.php:54
+#: ..\..\..\watched.php:114
+msgid "Username was not specified"
+msgstr "Brugernavn var ikke specificerede"
+
+#: ..\..\..\profile.php:60
+msgid "My Profile"
+msgstr "Min profil"
+
+#: ..\..\..\profile.php:62
+#: ..\..\..\templates\sidebar.block.profile.php:12
+msgid "Profile"
+msgstr "Profil"
+
+#: ..\..\..\profile.php:80
+msgid "Password and confirmation do not match."
+msgstr "Kodeord og bekræftelse matcher ikke."
+
+#: ..\..\..\profile.php:84
+msgid "Password must be at least 6 characters long."
+msgstr "Kodeordet skal mindst være på 6 karakterer."
+
+#: ..\..\..\profile.php:88
+msgid "E-mail address is not valid."
+msgstr "E-mail adressen er ikke gyldig."
+
+#: ..\..\..\profile.php:92
+msgid "An error occurred while saving your changes."
+msgstr "En fejl opstod ved forsøg på at gemme dine ændringer."
+
+#: ..\..\..\profile.php:94
+msgid "Changes saved."
+msgstr "Ændringer gemt."
+
+#: ..\..\..\register.php:33
+msgid "You <em>must</em> enter a username, password and e-mail address."
+msgstr "Du <em>skal</em> indtaste et brugernavn, kodeord og e-mail adresse."
+
+#: ..\..\..\register.php:37
+msgid "This username already exists, please make another choice."
+msgstr "Brugernavnet eksistere allerede, vælg venligst et andet."
+
+#: ..\..\..\register.php:41
+msgid "E-mail address is not valid. Please try again."
+msgstr "E-mail addressen er ikke gyldig. Prøv venligst igen."
+
+#: ..\..\..\register.php:50
+msgid "You have successfully registered. Enjoy!"
+msgstr "Du er nu succesfuldt registeret. God fornøjelse!"
+
+#: ..\..\..\register.php:52
+msgid "Registration failed. Please try again."
+msgstr "Registreringen fejlede. Prøv venligst igen."
+
+#: ..\..\..\register.php:57
+#: ..\..\..\templates\register.tpl.php:32
+#: ..\..\..\templates\toolbar.inc.php:27
+msgid "Register"
+msgstr "Registrere"
+
+#: ..\..\..\search.inc.php:29
+#: ..\..\..\search.inc.php:57
+msgid "Search"
+msgstr "Søg"
+
+#: ..\..\..\search.inc.php:35
+msgid "this user's bookmarks"
+msgstr "denne brugers bogmærker"
+
+#: ..\..\..\search.inc.php:40
+msgid "my bookmarks"
+msgstr "mine bogmærker"
+
+#: ..\..\..\search.inc.php:41
+msgid "my watchlist"
+msgstr "Min Overvågningsliste"
+
+#: ..\..\..\search.inc.php:45
+msgid "all bookmarks"
+msgstr "alle bogmærkerne"
+
+#: ..\..\..\search.inc.php:48
+msgid "for"
+msgstr "for"
+
+#: ..\..\..\search.php:91
+#: ..\..\..\search.php:128
+msgid "Search Bookmarks"
+msgstr "Søge i bogmærker"
+
+#: ..\..\..\search.php:97
+msgid "Search Results"
+msgstr "Søge resultat"
+
+#: ..\..\..\tags.php:38
+#: ..\..\..\templates\editbookmark.tpl.php:44
+#: ..\..\..\templates\sidebar.block.profile.php:13
+msgid "Tags"
+msgstr "Mærkater"
+
+#: ..\..\..\watch.php:79
+#, php-format
+msgid "%s Bookmarks"
+msgstr "%s Bogmærker"
+
+#: ..\..\..\watch.php:84
+msgid "User removed from your watchlist"
+msgstr "Bruger fjernet fra din overvågningsliste"
+
+#: ..\..\..\watch.php:86
+msgid "User added to your watchlist"
+msgstr "Bruger tilføjet til din overvågningsliste "
+
+#: ..\..\..\watched.php:105
+msgid "My Watchlist"
+msgstr "Min Overvågningsliste "
+
+#: ..\..\..\watched.php:107
+#: ..\..\..\templates\sidebar.block.profile.php:14
+#: ..\..\..\templates\toolbar.inc.php:12
+msgid "Watchlist"
+msgstr "Overvågningsliste"
+
+#: ..\..\..\templates\about.tpl.php:6
+msgid "<strong>Store</strong> all your favourite links in one place, accessible from anywhere."
+msgstr "<strong>Gem</strong> alle dine favorit links et sted, tilgængelig fra hvor som helst"
+
+#: ..\..\..\templates\about.tpl.php:7
+msgid "<strong>Share</strong> your bookmarks with everyone, with friends on your watchlist or just keep them private."
+msgstr "Del dine bogmærker med alle, med vennerne på din overvågningsliste eller behold dem private."
+
+#: ..\..\..\templates\about.tpl.php:8
+msgid "<strong>Tag</strong> your bookmarks with as many labels as you want, instead of wrestling with folders."
+msgstr "<strong>Marker</strong> dine bogmærker med så mange mærkater som du ønsker, i stedet for at kæmpe med mapper."
+
+#: ..\..\..\templates\about.tpl.php:9
+#, php-format
+msgid "<strong><a href=\"register.php\">Register now</a></strong> to start using %s!"
+msgstr "<strong><a href=\"register.php\">Register nu</a></strong> for at starte med at bruge %s!"
+
+#: ..\..\..\templates\about.tpl.php:12
+msgid "Geek Stuff"
+msgstr "Nørd Ting"
+
+#: ..\..\..\templates\about.tpl.php:14
+#, php-format
+msgid "%s is based on <a href=\"http://sourceforge.net/projects/scuttle/\">an open-source project</a> licensed under the <a href=\"http://www.gnu.org/copyleft/gpl.html\"><acronym title=\"GNU's Not Unix\">GNU</acronym> General Public License</a>. This means you can host it on your own web server for free, whether it is on the Internet, a private network or just your own computer."
+msgstr "%s er baseret på <a href=\"http://sourceforge.net/projects/scuttle/\">et åbent-kode projekt</a> licenseret under <a href=\"http://www.gnu.org/copyleft/gpl.html\"><acronym title=\"GNU's Not Unix\">GNU</acronym> General Public License</a>. Dette betyder at du kan hoste systemet på din egen server gratis, lige meget om det er på Internet, et privat netværk eller bare på din egen computer."
+
+#: ..\..\..\templates\about.tpl.php:15
+#, php-format
+msgid "%1$s supports most of the <a href=\"http://del.icio.us/doc/api\">del.icio.us <abbr title=\"Application Programming Interface\">API</abbr></a>. Almost all of the neat tools made for that system can be modified to work with %1$s instead. If you find a tool that won't let you change the API address, ask the creator to add this setting. You never know, they might just do it."
+msgstr "%1$s understøtter de fleste <a href=\"http://del.icio.us/doc/api\">del.icio.us <abbr title=\"Forbindelsesflade imellem forskellige programmer \">API</abbr></a>. Næsten alle de værktøjer udviklet til det system kan modificeres til at fungere med %1$s i stedet for. Hvis du finder et værktøj som ikke tillader at du fortager ændringer i API adresse, kunne du jo spørge udviklerne. Man ved aldrig det kunne jo være de ville."
+
+#: ..\..\..\templates\bookmarks.tpl.php:17
+#: ..\..\..\templates\tags.tpl.php:7
+msgid "Sort by:"
+msgstr "Sortere efter:"
+
+#: ..\..\..\templates\bookmarks.tpl.php:18
+msgid "Date"
+msgstr "Dato"
+
+#: ..\..\..\templates\bookmarks.tpl.php:19
+#: ..\..\..\templates\editbookmark.tpl.php:34
+msgid "Title"
+msgstr "Titel"
+
+#: ..\..\..\templates\bookmarks.tpl.php:23
+msgid "URL"
+msgstr "URL"
+
+#: ..\..\..\templates\bookmarks.tpl.php:60
+msgid "Edit"
+msgstr "Redigere"
+
+#: ..\..\..\templates\bookmarks.tpl.php:60
+msgid "Delete"
+msgstr "Slet"
+
+#: ..\..\..\templates\bookmarks.tpl.php:66
+msgid "by"
+msgstr "af"
+
+#: ..\..\..\templates\bookmarks.tpl.php:78
+#, php-format
+msgid " and %s1 other%s"
+msgstr "og %s1 andre%s"
+
+#: ..\..\..\templates\bookmarks.tpl.php:81
+#, php-format
+msgid " and %2$s%1$s others%3$s"
+msgstr " og %2$s%1$s andre%3$s"
+
+#: ..\..\..\templates\bookmarks.tpl.php:90
+msgid "Copy"
+msgstr "Kopi"
+
+#: ..\..\..\templates\bookmarks.tpl.php:136
+#: ..\..\..\templates\bookmarks.tpl.php:142
+msgid "First"
+msgstr "Første"
+
+#: ..\..\..\templates\bookmarks.tpl.php:137
+#: ..\..\..\templates\bookmarks.tpl.php:143
+msgid "Previous"
+msgstr "Forrige"
+
+#: ..\..\..\templates\bookmarks.tpl.php:150
+#: ..\..\..\templates\bookmarks.tpl.php:153
+msgid "Next"
+msgstr "Næste"
+
+#: ..\..\..\templates\bookmarks.tpl.php:151
+#: ..\..\..\templates\bookmarks.tpl.php:154
+msgid "Last"
+msgstr "Sidste"
+
+#: ..\..\..\templates\bookmarks.tpl.php:156
+#, php-format
+msgid "Page %d of %d"
+msgstr "Side %d af %d"
+
+#: ..\..\..\templates\bookmarks.tpl.php:160
+msgid "No bookmarks available"
+msgstr "Igen bogmærker tilgængelig"
+
+#: ..\..\..\templates\dynamictags.inc.php:108
+#: ..\..\..\templates\sidebar.block.common.php:15
+#: ..\..\..\templates\sidebar.block.popular.php:21
+#: ..\..\..\templates\sidebar.block.recent.php:20
+#: ..\..\..\templates\tags.tpl.php:16
+msgid "bookmark"
+msgid_plural "bookmarks"
+msgstr[0] "bogmærke"
+msgstr[1] "bogmærker"
+
+#: ..\..\..\templates\editbookmark.tpl.php:29
+msgid "Address"
+msgstr "Adresse"
+
+#: ..\..\..\templates\editbookmark.tpl.php:31
+#: ..\..\..\templates\editbookmark.tpl.php:36
+#: ..\..\..\templates\editprofile.tpl.php:31
+msgid "Required"
+msgstr "Påkrævet"
+
+#: ..\..\..\templates\editbookmark.tpl.php:39
+#: ..\..\..\templates\editprofile.tpl.php:47
+#: ..\..\..\templates\profile.tpl.php:28
+msgid "Description"
+msgstr "Beskrivelse"
+
+#: ..\..\..\templates\editbookmark.tpl.php:46
+msgid "Comma-separated"
+msgstr "Komma adskillelse"
+
+#: ..\..\..\templates\editbookmark.tpl.php:49
+#: ..\..\..\templates\importDelicious.tpl.php:15
+#: ..\..\..\templates\importNetscape.tpl.php:16
+msgid "Privacy"
+msgstr "Privat"
+
+#: ..\..\..\templates\editbookmark.tpl.php:52
+#: ..\..\..\templates\importDelicious.tpl.php:18
+#: ..\..\..\templates\importNetscape.tpl.php:19
+msgid "Public"
+msgstr "Offentligt"
+
+#: ..\..\..\templates\editbookmark.tpl.php:53
+#: ..\..\..\templates\importDelicious.tpl.php:19
+#: ..\..\..\templates\importNetscape.tpl.php:20
+msgid "Shared with Watch List"
+msgstr "Del med Overvågningslisten"
+
+#: ..\..\..\templates\editbookmark.tpl.php:54
+#: ..\..\..\templates\importDelicious.tpl.php:20
+#: ..\..\..\templates\importNetscape.tpl.php:21
+msgid "Private"
+msgstr "Private"
+
+#: ..\..\..\templates\editbookmark.tpl.php:66
+msgid "Delete Bookmark"
+msgstr "Slet bogmærker"
+
+#: ..\..\..\templates\editbookmark.tpl.php:93
+msgid "Bookmarklet"
+msgstr "Bogmærkelet"
+
+#: ..\..\..\templates\editbookmark.tpl.php:94
+#, php-format
+msgid "Drag one of the following bookmarklets to your browser's bookmarks and click it whenever you want to add the page you are on to %s"
+msgstr "Træk en af de følgende bogmærkeletter til din browsers bogmærker, og tryk på den hver gang du ønsker at tilføje den side du er på til %s"
+
+#: ..\..\..\templates\editbookmark.tpl.php:106
+#, php-format
+msgid "Post to %s"
+msgstr "Send til %s"
+
+#: ..\..\..\templates\editbookmark.tpl.php:107
+#, php-format
+msgid "Post to %s (Pop-up)"
+msgstr "Send til %s (Pop-up)"
+
+#: ..\..\..\templates\editbookmark.tpl.php:111
+#: ..\..\..\templates\importDelicious.tpl.php:26
+#: ..\..\..\templates\importNetscape.tpl.php:27
+msgid "Import"
+msgstr "Importere"
+
+#: ..\..\..\templates\editbookmark.tpl.php:113
+msgid "Import bookmarks from bookmark file"
+msgstr "Importere bogmærker fra bogmærke fil"
+
+#: ..\..\..\templates\editbookmark.tpl.php:113
+msgid "Internet Explorer, Mozilla Firefox and Netscape"
+msgstr "Internet Explorer, Mozilla Firefox og Netscape"
+
+#: ..\..\..\templates\editbookmark.tpl.php:114
+msgid "Import bookmarks from del.icio.us"
+msgstr "Importere bogmærker fra del.icio.us"
+
+#: ..\..\..\templates\editprofile.tpl.php:10
+msgid "Account Details"
+msgstr "Konto oplysninger"
+
+#: ..\..\..\templates\editprofile.tpl.php:14
+#: ..\..\..\templates\login.tpl.php:15
+#: ..\..\..\templates\password.tpl.php:10
+#: ..\..\..\templates\profile.tpl.php:7
+#: ..\..\..\templates\register.tpl.php:16
+msgid "Username"
+msgstr "Brugernavn"
+
+#: ..\..\..\templates\editprofile.tpl.php:19
+msgid "New Password"
+msgstr "Nyt kodeord"
+
+#: ..\..\..\templates\editprofile.tpl.php:24
+msgid "Confirm Password"
+msgstr "bekræft kodeord"
+
+#: ..\..\..\templates\editprofile.tpl.php:29
+#: ..\..\..\templates\register.tpl.php:26
+msgid "E-mail"
+msgstr "E-mail"
+
+#: ..\..\..\templates\editprofile.tpl.php:35
+msgid "Personal Details"
+msgstr "Personlige detaljer"
+
+#: ..\..\..\templates\editprofile.tpl.php:39
+#: ..\..\..\templates\profile.tpl.php:12
+msgid "Name"
+msgstr "Navn"
+
+#: ..\..\..\templates\editprofile.tpl.php:43
+#: ..\..\..\templates\profile.tpl.php:18
+msgid "Homepage"
+msgstr "Hjemmeside"
+
+#: ..\..\..\templates\error.404.tpl.php:5
+msgid "Not Found"
+msgstr "Ikke fundet"
+
+#: ..\..\..\templates\error.404.tpl.php:6
+msgid "The requested URL was not found on this server"
+msgstr "Den forespurgte adresse kunne ikke findes på denne server"
+
+#: ..\..\..\templates\error.500.tpl.php:5
+msgid "General server error"
+msgstr "General server fejl"
+
+#: ..\..\..\templates\error.500.tpl.php:6
+msgid "The requested URL could not be processed"
+msgstr "Den forespurgte adresse kunne ikke afvikles"
+
+#: ..\..\..\templates\importDelicious.tpl.php:33
+msgid "Log in to the <a href=\"http://del.icio.us/api/posts/all\">export page at del.icio.us</a>"
+msgstr "Log ind på <a href=\"http://del.icio.us/api/posts/all\">del.icio.us' eksport side</a>"
+
+#: ..\..\..\templates\importDelicious.tpl.php:34
+msgid "Save the resulting <abbr title=\"Extensible Markup Language\">XML</abbr> file to your computer"
+msgstr "Gem <abbr title=\"Extensible Markup Language\">XML</abbr> fillen på din computer"
+
+#: ..\..\..\templates\importDelicious.tpl.php:35
+msgid "Click <kbd>Browse...</kbd> to find this file on your computer. The maximum size the file can be is 1MB"
+msgstr "Tryk <kbd>Gennemse...</kbd> for at finde denne fil på din computer. Filstørrelsen må maksimum være på 1MB"
+
+#: ..\..\..\templates\importDelicious.tpl.php:36
+#: ..\..\..\templates\importNetscape.tpl.php:43
+msgid "Select the default privacy setting for your imported bookmarks"
+msgstr "Vælg den ønskede standart privatindstilling for dine importerede bogmærker"
+
+#: ..\..\..\templates\importDelicious.tpl.php:37
+#: ..\..\..\templates\importNetscape.tpl.php:44
+msgid "Click <kbd>Import</kbd> to start importing the bookmarks; it may take a minute"
+msgstr "Tryk Import for at starte med at importere dine bogmærker; dette kan tage et par minutter."
+
+#: ..\..\..\templates\importNetscape.tpl.php:32
+msgid "Instructions"
+msgstr "Instruktioner"
+
+#: ..\..\..\templates\importNetscape.tpl.php:35
+msgid "Export your bookmarks from your browser to a file"
+msgstr "Eksportere dine bogmærker fra din browser til en fil"
+
+#: ..\..\..\templates\importNetscape.tpl.php:37
+msgid "Internet Explorer: <kbd>File &gt; Import and Export... &gt; Export Favorites"
+msgstr "Internet Explorer: <kbd>Filer &gt; Importer og eksporter... &gt; Eksporter foretrukne emner"
+
+#: ..\..\..\templates\importNetscape.tpl.php:38
+msgid "Mozilla Firefox: <kbd>Bookmarks &gt; Manage Bookmarks... &gt; File &gt; Export..."
+msgstr "Mozilla Firefox: <kbd>Bogmærker &gt; Arranger bogmærker... &gt; Filer &gt; Eksporter..."
+
+#: ..\..\..\templates\importNetscape.tpl.php:39
+msgid "Netscape: <kbd>Bookmarks &gt; Manage Bookmarks... &gt; Tools &gt; Export..."
+msgstr "Netscape: <kbd>Bogmærker &gt; Arranger bogmærker... &gt; Værktøjer &gt; Eksporter..."
+
+#: ..\..\..\templates\importNetscape.tpl.php:42
+msgid "Click <kbd>Browse...</kbd> to find the saved bookmark file on your computer. The maximum size the file can be is 1MB"
+msgstr "Tryk <kbd>Gennemse...</kbd> for at finde den gemte bogmærke fil på din computer. Filstørrelsen må maksimum være på 1MB"
+
+#: ..\..\..\templates\login.tpl.php:20
+#: ..\..\..\templates\register.tpl.php:21
+msgid "Password"
+msgstr "Kodeord"
+
+#: ..\..\..\templates\login.tpl.php:22
+msgid "Don't ask for my password for 2 weeks"
+msgstr "Søg ikke efter mit kodeord i 2 uger"
+
+#: ..\..\..\templates\login.tpl.php:30
+msgid "Forgotten your password?"
+msgstr "Glemt dit kodeord?"
+
+#: ..\..\..\templates\password.tpl.php:5
+#, php-format
+msgid "If you have forgotten your password, %s can generate a new one. Enter the username and e-mail address of your account into the form below and we will e-mail your new password to you."
+msgstr "Hvis du har glemte dit kodeord, kan %s generere et nyt et. Skriv brugernavnet og e-mail adressen på din konto i formularen nedenfor og vi vil sende dit nye kodeord til dig via e-mail."
+
+#: ..\..\..\templates\password.tpl.php:14
+msgid "<abbr title=\"Electronic mail\">E-mail</abbr>"
+msgstr "<abbr title=\"Elektronisk post\">E-mail</abbr>"
+
+#: ..\..\..\templates\password.tpl.php:19
+msgid "Generate Password"
+msgstr "Generere kodeord"
+
+#: ..\..\..\templates\profile.tpl.php:23
+msgid "Member Since"
+msgstr "Medlem siden"
+
+#: ..\..\..\templates\profile.tpl.php:35
+#: ..\..\..\templates\sidebar.block.watchlist.php:8
+msgid "Watching"
+msgstr "Overvåger"
+
+#: ..\..\..\templates\profile.tpl.php:50
+msgid "Watched By"
+msgstr "Overvågede af"
+
+#: ..\..\..\templates\register.tpl.php:11
+#, php-format
+msgid "Sign up here to create a free %s account. All the information requested below is required"
+msgstr "Tilmeld dig her for at oprette en gratis %s konto. Alle forspurgte informationerne neden for er påkrævet."
+
+#: ..\..\..\templates\rss.tpl.php:9
+#, php-format
+msgid "Recent bookmarks posted to %s"
+msgstr "Seneste bogmærker sendt til %s"
+
+#: ..\..\..\templates\rss.tpl.php:17
+#: ..\..\..\templates\rss.tpl.php:19
+msgid "No bookmarks found"
+msgstr "Igen bogmærker fundet"
+
+#: ..\..\..\templates\sidebar.block.recent.php:15
+msgid "Recent Tags"
+msgstr "Nylig mærker"
+
+#: ..\..\..\templates\sidebar.block.related.php:15
+msgid "Related Tags"
+msgstr "Lignede mærker"
+
+#: ..\..\..\templates\sidebar.block.watchstatus.php:10
+msgid "Remove from Watchlist"
+msgstr "Fjern fra Overvågningslisten"
+
+#: ..\..\..\templates\sidebar.block.watchstatus.php:12
+msgid "Add to Watchlist"
+msgstr "Tilføj til Overvågningslisten"
+
+#: ..\..\..\templates\sidebar.block.watchstatus.php:17
+msgid "Actions"
+msgstr "Aktion"
+
+#: ..\..\..\templates\tags.tpl.php:8
+msgid "Alphabet"
+msgstr "Alfabet"
+
+#: ..\..\..\templates\tags.tpl.php:9
+msgid "Popularity"
+msgstr "Popularitet"
+
+#: ..\..\..\templates\toolbar.inc.php:11
+msgid "Bookmarks"
+msgstr "Bogmærker"
+
+#: ..\..\..\templates\toolbar.inc.php:16
+msgid "Log Out"
+msgstr "Log ud"
+
diff --git a/locales/en_GB/LC_MESSAGES/messages.mo b/locales/en_GB/LC_MESSAGES/messages.mo
new file mode 100644
index 0000000..1173088
--- /dev/null
+++ b/locales/en_GB/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/locales/en_GB/LC_MESSAGES/messages.po b/locales/en_GB/LC_MESSAGES/messages.po
new file mode 100644
index 0000000..46ea298
--- /dev/null
+++ b/locales/en_GB/LC_MESSAGES/messages.po
@@ -0,0 +1,808 @@
+# Scuttle en-GB Translation
+# Copyright (C) 2005 - 2006 Scuttle project
+# This file is distributed under the same license as the Scuttle package.
+# Marcus Campbell <marcus.campbell@gmail.com>
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Scuttle\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2005-04-29 11:17+0200\n"
+"PO-Revision-Date: 2006-03-18 21:41-0800\n"
+"Last-Translator: Marcus Campbell <marcus.campbell@gmail.com>\n"
+"Language-Team: en-GB <marcus.campbell@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-Language: English\n"
+"X-Poedit-Country: UNITED KINGDOM\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: ..\..\..\about.php:25
+#: ..\..\..\templates\toolbar.inc.php:24
+msgid "About"
+msgstr ""
+
+#: ..\..\..\ajaxDelete.php:29
+msgid "You are not allowed to delete this bookmark"
+msgstr ""
+
+#: ..\..\..\ajaxDelete.php:33
+msgid "Failed to delete bookmark"
+msgstr ""
+
+#: ..\..\..\alltags.php:50
+msgid "All Tags"
+msgstr ""
+
+#: ..\..\..\alltags.php:59
+#: ..\..\..\populartags.php:63
+#: ..\..\..\profile.php:46
+#: ..\..\..\rss.php:55
+#: ..\..\..\search.php:61
+#: ..\..\..\watch.php:35
+#: ..\..\..\watched.php:62
+#, php-format
+msgid "User with username %s not was not found"
+msgstr ""
+
+#: ..\..\..\bookmarks.php:71
+#, php-format
+msgid "User with username %s was not found"
+msgstr ""
+
+#: ..\..\..\bookmarks.php:94
+#: ..\..\..\edit.php:44
+msgid "Your bookmark must have a title and an address"
+msgstr ""
+
+#: ..\..\..\bookmarks.php:114
+#: ..\..\..\edit.php:58
+msgid "Bookmark saved"
+msgstr ""
+
+#: ..\..\..\bookmarks.php:122
+#: ..\..\..\import.php:99
+#: ..\..\..\importNetscape.php:74
+msgid "There was an error saving your bookmark. Please try again or contact the administrator."
+msgstr ""
+
+#: ..\..\..\bookmarks.php:160
+#: ..\..\..\templates\toolbar.inc.php:13
+msgid "Add a Bookmark"
+msgstr ""
+
+#: ..\..\..\bookmarks.php:163
+msgid "Add Bookmark"
+msgstr ""
+
+#: ..\..\..\bookmarks.php:166
+msgid "You must be logged in before you can add bookmarks."
+msgstr ""
+
+#: ..\..\..\bookmarks.php:213
+msgid "My Bookmarks"
+msgstr ""
+
+#: ..\..\..\edit.php:29
+msgid "Edit Bookmark"
+msgstr ""
+
+#: ..\..\..\edit.php:34
+#, php-format
+msgid "Bookmark with id %s not was not found"
+msgstr ""
+
+#: ..\..\..\edit.php:39
+msgid "You are not allowed to edit this bookmark"
+msgstr ""
+
+#: ..\..\..\edit.php:55
+msgid "Error while saving your bookmark"
+msgstr ""
+
+#: ..\..\..\edit.php:78
+msgid "Failed to delete the bookmark"
+msgstr ""
+
+#: ..\..\..\edit.php:88
+#: ..\..\..\templates\editprofile.tpl.php:52
+msgid "Save Changes"
+msgstr ""
+
+#: ..\..\..\functions.inc.php:92
+msgid "message_die() was called multiple times."
+msgstr ""
+
+#: ..\..\..\functions.inc.php:104
+msgid "SQL Error"
+msgstr ""
+
+#: ..\..\..\functions.inc.php:110
+msgid "Line"
+msgstr ""
+
+#: ..\..\..\functions.inc.php:110
+#: ..\..\..\templates\importDelicious.tpl.php:8
+#: ..\..\..\templates\importNetscape.tpl.php:9
+msgid "File"
+msgstr ""
+
+#: ..\..\..\functions.inc.php:116
+msgid "Information"
+msgstr ""
+
+#: ..\..\..\functions.inc.php:121
+msgid "Critical Information"
+msgstr ""
+
+#: ..\..\..\functions.inc.php:126
+msgid "An error occured"
+msgstr ""
+
+#: ..\..\..\functions.inc.php:129
+msgid "General Error"
+msgstr ""
+
+#: ..\..\..\functions.inc.php:137
+msgid "An critical error occured"
+msgstr ""
+
+#: ..\..\..\functions.inc.php:140
+msgid "Critical Error"
+msgstr ""
+
+#: ..\..\..\functions.inc.php:149
+msgid "DEBUG MODE"
+msgstr ""
+
+#: ..\..\..\history.php:65
+msgid "History"
+msgstr ""
+
+#: ..\..\..\history.php:66
+#, php-format
+msgid "History for %s"
+msgstr ""
+
+#: ..\..\..\history.php:81
+msgid "Address was not found"
+msgstr ""
+
+#: ..\..\..\import.php:41
+msgid "Could not open XML input"
+msgstr ""
+
+#: ..\..\..\import.php:45
+#, php-format
+msgid "XML error: %s at line %d"
+msgstr ""
+
+#: ..\..\..\import.php:54
+msgid "Import Bookmarks from del.icio.us"
+msgstr ""
+
+#: ..\..\..\import.php:86
+#: ..\..\..\importNetscape.php:64
+msgid "You have already submitted this bookmark."
+msgstr ""
+
+#: ..\..\..\import.php:97
+#: ..\..\..\importNetscape.php:72
+msgid "Bookmark imported."
+msgstr ""
+
+#: ..\..\..\importNetscape.php:81
+msgid "Import Bookmarks from Browser File"
+msgstr ""
+
+#: ..\..\..\index.php:32
+msgid "You have now logged out"
+msgstr ""
+
+#: ..\..\..\index.php:39
+#, php-format
+msgid "%s: Recent bookmarks"
+msgstr ""
+
+#: ..\..\..\index.php:72
+msgid "Store, share and tag your favourite links"
+msgstr ""
+
+#: ..\..\..\index.php:73
+msgid "Recent Bookmarks"
+msgstr ""
+
+#: ..\..\..\jsScuttle.php:22
+msgid "Are you sure?"
+msgstr ""
+
+#: ..\..\..\jsScuttle.php:22
+msgid "Yes"
+msgstr ""
+
+#: ..\..\..\jsScuttle.php:22
+msgid "No"
+msgstr ""
+
+#: ..\..\..\jsScuttle.php:68
+msgid "Available"
+msgstr ""
+
+#: ..\..\..\jsScuttle.php:71
+msgid "Not Available"
+msgstr ""
+
+#: ..\..\..\login.php:38
+msgid "The details you have entered are incorrect. Please try again."
+msgstr ""
+
+#: ..\..\..\login.php:48
+#: ..\..\..\templates\login.tpl.php:26
+#: ..\..\..\templates\toolbar.inc.php:28
+msgid "Log In"
+msgstr ""
+
+#: ..\..\..\password.php:31
+msgid "You must enter your username."
+msgstr ""
+
+#: ..\..\..\password.php:35
+msgid "You must enter your <abbr title=\"electronic mail\">e-mail</abbr> address."
+msgstr ""
+
+#: ..\..\..\password.php:42
+msgid "No matches found for that username."
+msgstr ""
+
+#: ..\..\..\password.php:45
+msgid "No matches found for that combination of username and <abbr title=\"electronic mail\">e-mail</abbr> address."
+msgstr ""
+
+#: ..\..\..\password.php:53
+msgid "There was an error while generating your new password. Please try again."
+msgstr ""
+
+#: ..\..\..\password.php:57
+msgid "Your new password is:"
+msgstr ""
+
+#: ..\..\..\password.php:57
+msgid "To keep your bookmarks secure, you should change this password in your profile the next time you log in."
+msgstr ""
+
+#: ..\..\..\password.php:60
+#, php-format
+msgid "%s Account Information"
+msgstr ""
+
+#: ..\..\..\password.php:62
+#, php-format
+msgid "New password generated and sent to %s"
+msgstr ""
+
+#: ..\..\..\password.php:69
+msgid "Forgotten Password"
+msgstr ""
+
+#: ..\..\..\populartags.php:54
+#: ..\..\..\templates\dynamictags.inc.php:101
+#: ..\..\..\templates\sidebar.block.common.php:9
+#: ..\..\..\templates\sidebar.block.popular.php:15
+#: ..\..\..\templates\sidebar.block.recent.php:25
+msgid "Popular Tags"
+msgstr ""
+
+#: ..\..\..\profile.php:54
+#: ..\..\..\watched.php:114
+msgid "Username was not specified"
+msgstr ""
+
+#: ..\..\..\profile.php:60
+msgid "My Profile"
+msgstr ""
+
+#: ..\..\..\profile.php:62
+#: ..\..\..\templates\sidebar.block.profile.php:12
+msgid "Profile"
+msgstr ""
+
+#: ..\..\..\profile.php:80
+msgid "Password and confirmation do not match."
+msgstr ""
+
+#: ..\..\..\profile.php:84
+msgid "Password must be at least 6 characters long."
+msgstr ""
+
+#: ..\..\..\profile.php:88
+msgid "E-mail address is not valid."
+msgstr ""
+
+#: ..\..\..\profile.php:92
+msgid "An error occurred while saving your changes."
+msgstr ""
+
+#: ..\..\..\profile.php:94
+msgid "Changes saved."
+msgstr ""
+
+#: ..\..\..\register.php:33
+msgid "You <em>must</em> enter a username, password and e-mail address."
+msgstr ""
+
+#: ..\..\..\register.php:37
+msgid "This username already exists, please make another choice."
+msgstr ""
+
+#: ..\..\..\register.php:41
+msgid "E-mail address is not valid. Please try again."
+msgstr ""
+
+#: ..\..\..\register.php:50
+msgid "You have successfully registered. Enjoy!"
+msgstr ""
+
+#: ..\..\..\register.php:52
+msgid "Registration failed. Please try again."
+msgstr ""
+
+#: ..\..\..\register.php:57
+#: ..\..\..\templates\register.tpl.php:32
+#: ..\..\..\templates\toolbar.inc.php:27
+msgid "Register"
+msgstr ""
+
+#: ..\..\..\search.inc.php:29
+#: ..\..\..\search.inc.php:57
+msgid "Search"
+msgstr ""
+
+#: ..\..\..\search.inc.php:35
+msgid "this user's bookmarks"
+msgstr ""
+
+#: ..\..\..\search.inc.php:40
+msgid "my bookmarks"
+msgstr ""
+
+#: ..\..\..\search.inc.php:41
+msgid "my watchlist"
+msgstr ""
+
+#: ..\..\..\search.inc.php:45
+msgid "all bookmarks"
+msgstr ""
+
+#: ..\..\..\search.inc.php:48
+msgid "for"
+msgstr ""
+
+#: ..\..\..\search.php:91
+#: ..\..\..\search.php:128
+msgid "Search Bookmarks"
+msgstr ""
+
+#: ..\..\..\search.php:97
+msgid "Search Results"
+msgstr ""
+
+#: ..\..\..\tags.php:38
+#: ..\..\..\templates\editbookmark.tpl.php:44
+#: ..\..\..\templates\sidebar.block.profile.php:13
+msgid "Tags"
+msgstr ""
+
+#: ..\..\..\watch.php:79
+#, php-format
+msgid "%s Bookmarks"
+msgstr ""
+
+#: ..\..\..\watch.php:84
+msgid "User removed from your watchlist"
+msgstr ""
+
+#: ..\..\..\watch.php:86
+msgid "User added to your watchlist"
+msgstr ""
+
+#: ..\..\..\watched.php:105
+msgid "My Watchlist"
+msgstr ""
+
+#: ..\..\..\watched.php:107
+#: ..\..\..\templates\sidebar.block.profile.php:14
+#: ..\..\..\templates\toolbar.inc.php:12
+msgid "Watchlist"
+msgstr ""
+
+#: ..\..\..\templates\about.tpl.php:6
+msgid "<strong>Store</strong> all your favourite links in one place, accessible from anywhere."
+msgstr ""
+
+#: ..\..\..\templates\about.tpl.php:7
+msgid "<strong>Share</strong> your bookmarks with everyone, with friends on your watchlist or just keep them private."
+msgstr ""
+
+#: ..\..\..\templates\about.tpl.php:8
+msgid "<strong>Tag</strong> your bookmarks with as many labels as you want, instead of wrestling with folders."
+msgstr ""
+
+#: ..\..\..\templates\about.tpl.php:9
+#, php-format
+msgid "<strong><a href=\"register.php\">Register now</a></strong> to start using %s!"
+msgstr ""
+
+#: ..\..\..\templates\about.tpl.php:12
+msgid "Geek Stuff"
+msgstr ""
+
+#: ..\..\..\templates\about.tpl.php:14
+#, php-format
+msgid "%s is based on <a href=\"http://sourceforge.net/projects/scuttle/\">an open-source project</a> licensed under the <a href=\"http://www.gnu.org/copyleft/gpl.html\"><acronym title=\"GNU's Not Unix\">GNU</acronym> General Public License</a>. This means you can host it on your own web server for free, whether it is on the Internet, a private network or just your own computer."
+msgstr ""
+
+#: ..\..\..\templates\about.tpl.php:15
+#, php-format
+msgid "%1$s supports most of the <a href=\"http://del.icio.us/doc/api\">del.icio.us <abbr title=\"Application Programming Interface\">API</abbr></a>. Almost all of the neat tools made for that system can be modified to work with %1$s instead. If you find a tool that won't let you change the API address, ask the creator to add this setting. You never know, they might just do it."
+msgstr ""
+
+#: ..\..\..\templates\bookmarks.tpl.php:17
+#: ..\..\..\templates\tags.tpl.php:7
+msgid "Sort by:"
+msgstr ""
+
+#: ..\..\..\templates\bookmarks.tpl.php:18
+msgid "Date"
+msgstr ""
+
+#: ..\..\..\templates\bookmarks.tpl.php:19
+#: ..\..\..\templates\editbookmark.tpl.php:34
+msgid "Title"
+msgstr ""
+
+#: ..\..\..\templates\bookmarks.tpl.php:23
+msgid "URL"
+msgstr ""
+
+#: ..\..\..\templates\bookmarks.tpl.php:60
+msgid "Edit"
+msgstr ""
+
+#: ..\..\..\templates\bookmarks.tpl.php:60
+msgid "Delete"
+msgstr ""
+
+#: ..\..\..\templates\bookmarks.tpl.php:66
+msgid "by"
+msgstr ""
+
+#: ..\..\..\templates\bookmarks.tpl.php:78
+#, php-format
+msgid " and %s1 other%s"
+msgstr ""
+
+#: ..\..\..\templates\bookmarks.tpl.php:81
+#, php-format
+msgid " and %2$s%1$s others%3$s"
+msgstr ""
+
+#: ..\..\..\templates\bookmarks.tpl.php:90
+msgid "Copy"
+msgstr ""
+
+#: ..\..\..\templates\bookmarks.tpl.php:136
+#: ..\..\..\templates\bookmarks.tpl.php:142
+msgid "First"
+msgstr ""
+
+#: ..\..\..\templates\bookmarks.tpl.php:137
+#: ..\..\..\templates\bookmarks.tpl.php:143
+msgid "Previous"
+msgstr ""
+
+#: ..\..\..\templates\bookmarks.tpl.php:150
+#: ..\..\..\templates\bookmarks.tpl.php:153
+msgid "Next"
+msgstr ""
+
+#: ..\..\..\templates\bookmarks.tpl.php:151
+#: ..\..\..\templates\bookmarks.tpl.php:154
+msgid "Last"
+msgstr ""
+
+#: ..\..\..\templates\bookmarks.tpl.php:156
+#, php-format
+msgid "Page %d of %d"
+msgstr ""
+
+#: ..\..\..\templates\bookmarks.tpl.php:160
+msgid "No bookmarks available"
+msgstr ""
+
+#: ..\..\..\templates\dynamictags.inc.php:108
+#: ..\..\..\templates\sidebar.block.common.php:15
+#: ..\..\..\templates\sidebar.block.popular.php:21
+#: ..\..\..\templates\sidebar.block.recent.php:20
+#: ..\..\..\templates\tags.tpl.php:16
+msgid "bookmark"
+msgid_plural "bookmarks"
+msgstr[0] ""
+msgstr[1] ""
+
+#: ..\..\..\templates\editbookmark.tpl.php:29
+msgid "Address"
+msgstr ""
+
+#: ..\..\..\templates\editbookmark.tpl.php:31
+#: ..\..\..\templates\editbookmark.tpl.php:36
+#: ..\..\..\templates\editprofile.tpl.php:31
+msgid "Required"
+msgstr ""
+
+#: ..\..\..\templates\editbookmark.tpl.php:39
+#: ..\..\..\templates\editprofile.tpl.php:47
+#: ..\..\..\templates\profile.tpl.php:28
+msgid "Description"
+msgstr ""
+
+#: ..\..\..\templates\editbookmark.tpl.php:46
+msgid "Comma-separated"
+msgstr ""
+
+#: ..\..\..\templates\editbookmark.tpl.php:49
+#: ..\..\..\templates\importDelicious.tpl.php:15
+#: ..\..\..\templates\importNetscape.tpl.php:16
+msgid "Privacy"
+msgstr ""
+
+#: ..\..\..\templates\editbookmark.tpl.php:52
+#: ..\..\..\templates\importDelicious.tpl.php:18
+#: ..\..\..\templates\importNetscape.tpl.php:19
+msgid "Public"
+msgstr ""
+
+#: ..\..\..\templates\editbookmark.tpl.php:53
+#: ..\..\..\templates\importDelicious.tpl.php:19
+#: ..\..\..\templates\importNetscape.tpl.php:20
+msgid "Shared with Watch List"
+msgstr ""
+
+#: ..\..\..\templates\editbookmark.tpl.php:54
+#: ..\..\..\templates\importDelicious.tpl.php:20
+#: ..\..\..\templates\importNetscape.tpl.php:21
+msgid "Private"
+msgstr ""
+
+#: ..\..\..\templates\editbookmark.tpl.php:66
+msgid "Delete Bookmark"
+msgstr ""
+
+#: ..\..\..\templates\editbookmark.tpl.php:93
+msgid "Bookmarklet"
+msgstr ""
+
+#: ..\..\..\templates\editbookmark.tpl.php:94
+#, php-format
+msgid "Drag one of the following bookmarklets to your browser's bookmarks and click it whenever you want to add the page you are on to %s"
+msgstr ""
+
+#: ..\..\..\templates\editbookmark.tpl.php:106
+#, php-format
+msgid "Post to %s"
+msgstr ""
+
+#: ..\..\..\templates\editbookmark.tpl.php:107
+#, php-format
+msgid "Post to %s (Pop-up)"
+msgstr ""
+
+#: ..\..\..\templates\editbookmark.tpl.php:111
+#: ..\..\..\templates\importDelicious.tpl.php:26
+#: ..\..\..\templates\importNetscape.tpl.php:27
+msgid "Import"
+msgstr ""
+
+#: ..\..\..\templates\editbookmark.tpl.php:113
+msgid "Import bookmarks from bookmark file"
+msgstr ""
+
+#: ..\..\..\templates\editbookmark.tpl.php:113
+msgid "Internet Explorer, Mozilla Firefox and Netscape"
+msgstr ""
+
+#: ..\..\..\templates\editbookmark.tpl.php:114
+msgid "Import bookmarks from del.icio.us"
+msgstr ""
+
+#: ..\..\..\templates\editprofile.tpl.php:10
+msgid "Account Details"
+msgstr ""
+
+#: ..\..\..\templates\editprofile.tpl.php:14
+#: ..\..\..\templates\login.tpl.php:15
+#: ..\..\..\templates\password.tpl.php:10
+#: ..\..\..\templates\profile.tpl.php:7
+#: ..\..\..\templates\register.tpl.php:16
+msgid "Username"
+msgstr ""
+
+#: ..\..\..\templates\editprofile.tpl.php:19
+msgid "New Password"
+msgstr ""
+
+#: ..\..\..\templates\editprofile.tpl.php:24
+msgid "Confirm Password"
+msgstr ""
+
+#: ..\..\..\templates\editprofile.tpl.php:29
+#: ..\..\..\templates\register.tpl.php:26
+msgid "E-mail"
+msgstr ""
+
+#: ..\..\..\templates\editprofile.tpl.php:35
+msgid "Personal Details"
+msgstr ""
+
+#: ..\..\..\templates\editprofile.tpl.php:39
+#: ..\..\..\templates\profile.tpl.php:12
+msgid "Name"
+msgstr ""
+
+#: ..\..\..\templates\editprofile.tpl.php:43
+#: ..\..\..\templates\profile.tpl.php:18
+msgid "Homepage"
+msgstr ""
+
+#: ..\..\..\templates\error.404.tpl.php:5
+msgid "Not Found"
+msgstr ""
+
+#: ..\..\..\templates\error.404.tpl.php:6
+msgid "The requested URL was not found on this server"
+msgstr ""
+
+#: ..\..\..\templates\error.500.tpl.php:5
+msgid "General server error"
+msgstr ""
+
+#: ..\..\..\templates\error.500.tpl.php:6
+msgid "The requested URL could not be processed"
+msgstr ""
+
+#: ..\..\..\templates\importDelicious.tpl.php:33
+msgid "Log in to the <a href=\"http://del.icio.us/api/posts/all\">export page at del.icio.us</a>"
+msgstr ""
+
+#: ..\..\..\templates\importDelicious.tpl.php:34
+msgid "Save the resulting <abbr title=\"Extensible Markup Language\">XML</abbr> file to your computer"
+msgstr ""
+
+#: ..\..\..\templates\importDelicious.tpl.php:35
+msgid "Click <kbd>Browse...</kbd> to find this file on your computer. The maximum size the file can be is 1MB"
+msgstr ""
+
+#: ..\..\..\templates\importDelicious.tpl.php:36
+#: ..\..\..\templates\importNetscape.tpl.php:43
+msgid "Select the default privacy setting for your imported bookmarks"
+msgstr ""
+
+#: ..\..\..\templates\importDelicious.tpl.php:37
+#: ..\..\..\templates\importNetscape.tpl.php:44
+msgid "Click <kbd>Import</kbd> to start importing the bookmarks; it may take a minute"
+msgstr ""
+
+#: ..\..\..\templates\importNetscape.tpl.php:32
+msgid "Instructions"
+msgstr ""
+
+#: ..\..\..\templates\importNetscape.tpl.php:35
+msgid "Export your bookmarks from your browser to a file"
+msgstr ""
+
+#: ..\..\..\templates\importNetscape.tpl.php:37
+msgid "Internet Explorer: <kbd>File &gt; Import and Export... &gt; Export Favorites"
+msgstr ""
+
+#: ..\..\..\templates\importNetscape.tpl.php:38
+msgid "Mozilla Firefox: <kbd>Bookmarks &gt; Manage Bookmarks... &gt; File &gt; Export..."
+msgstr ""
+
+#: ..\..\..\templates\importNetscape.tpl.php:39
+msgid "Netscape: <kbd>Bookmarks &gt; Manage Bookmarks... &gt; Tools &gt; Export..."
+msgstr ""
+
+#: ..\..\..\templates\importNetscape.tpl.php:42
+msgid "Click <kbd>Browse...</kbd> to find the saved bookmark file on your computer. The maximum size the file can be is 1MB"
+msgstr ""
+
+#: ..\..\..\templates\login.tpl.php:20
+#: ..\..\..\templates\register.tpl.php:21
+msgid "Password"
+msgstr ""
+
+#: ..\..\..\templates\login.tpl.php:22
+msgid "Don't ask for my password for 2 weeks"
+msgstr ""
+
+#: ..\..\..\templates\login.tpl.php:30
+msgid "Forgotten your password?"
+msgstr ""
+
+#: ..\..\..\templates\password.tpl.php:5
+#, php-format
+msgid "If you have forgotten your password, %s can generate a new one. Enter the username and e-mail address of your account into the form below and we will e-mail your new password to you."
+msgstr ""
+
+#: ..\..\..\templates\password.tpl.php:14
+msgid "<abbr title=\"Electronic mail\">E-mail</abbr>"
+msgstr ""
+
+#: ..\..\..\templates\password.tpl.php:19
+msgid "Generate Password"
+msgstr ""
+
+#: ..\..\..\templates\profile.tpl.php:23
+msgid "Member Since"
+msgstr ""
+
+#: ..\..\..\templates\profile.tpl.php:35
+#: ..\..\..\templates\sidebar.block.watchlist.php:8
+msgid "Watching"
+msgstr ""
+
+#: ..\..\..\templates\profile.tpl.php:50
+msgid "Watched By"
+msgstr ""
+
+#: ..\..\..\templates\register.tpl.php:11
+#, php-format
+msgid "Sign up here to create a free %s account. All the information requested below is required"
+msgstr ""
+
+#: ..\..\..\templates\rss.tpl.php:9
+#, php-format
+msgid "Recent bookmarks posted to %s"
+msgstr ""
+
+#: ..\..\..\templates\rss.tpl.php:17
+#: ..\..\..\templates\rss.tpl.php:19
+msgid "No bookmarks found"
+msgstr ""
+
+#: ..\..\..\templates\sidebar.block.recent.php:15
+msgid "Recent Tags"
+msgstr ""
+
+#: ..\..\..\templates\sidebar.block.related.php:15
+msgid "Related Tags"
+msgstr ""
+
+#: ..\..\..\templates\sidebar.block.watchstatus.php:10
+msgid "Remove from Watchlist"
+msgstr ""
+
+#: ..\..\..\templates\sidebar.block.watchstatus.php:12
+msgid "Add to Watchlist"
+msgstr ""
+
+#: ..\..\..\templates\sidebar.block.watchstatus.php:17
+msgid "Actions"
+msgstr ""
+
+#: ..\..\..\templates\tags.tpl.php:8
+msgid "Alphabet"
+msgstr ""
+
+#: ..\..\..\templates\tags.tpl.php:9
+msgid "Popularity"
+msgstr ""
+
+#: ..\..\..\templates\toolbar.inc.php:11
+msgid "Bookmarks"
+msgstr ""
+
+#: ..\..\..\templates\toolbar.inc.php:16
+msgid "Log Out"
+msgstr ""
+
diff --git a/locales/es_ES/LC_MESSAGES/messages.mo b/locales/es_ES/LC_MESSAGES/messages.mo
new file mode 100644
index 0000000..7812d22
--- /dev/null
+++ b/locales/es_ES/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/locales/es_ES/LC_MESSAGES/messages.po b/locales/es_ES/LC_MESSAGES/messages.po
new file mode 100644
index 0000000..73567fb
--- /dev/null
+++ b/locales/es_ES/LC_MESSAGES/messages.po
@@ -0,0 +1,826 @@
+# Scuttle es-ES Translation
+# Copyright (C) 2005 - 2006 Scuttle project
+# This file is distributed under the same license as the Scuttle package.
+# Francisco Portero <fportero@serbinario.com>
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Scuttle\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2005-12-16 06:31+0200\n"
+"PO-Revision-Date: 2006-03-26 14:28-0800\n"
+"Last-Translator: Marcus Campbell <marcus.campbell@gmail.com>\n"
+"Language-Team: es-ES <fportero@serbinario.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: ..\..\..\about.php:25
+#: ..\..\..\templates\toolbar.inc.php:24
+msgid "About"
+msgstr "Acerca de"
+
+#: ..\..\..\ajaxDelete.php:29
+msgid "You are not allowed to delete this bookmark"
+msgstr "No puede borrar estos enlaces"
+
+#: ..\..\..\ajaxDelete.php:33
+msgid "Failed to delete bookmark"
+msgstr "Error al borrar los enlaces"
+
+#: ..\..\..\alltags.php:50
+msgid "All Tags"
+msgstr "Todas"
+
+#: ..\..\..\alltags.php:59
+#: ..\..\..\populartags.php:63
+#: ..\..\..\profile.php:46
+#: ..\..\..\rss.php:55
+#: ..\..\..\search.php:61
+#: ..\..\..\watch.php:35
+#: ..\..\..\watched.php:62
+#, php-format
+msgid "User with username %s not was not found"
+msgstr "No se encontro el usuario %s"
+
+#: ..\..\..\bookmarks.php:71
+#, fuzzy, php-format
+msgid "User with username %s was not found"
+msgstr "No se encontro el usuario %s"
+
+#: ..\..\..\bookmarks.php:94
+#: ..\..\..\edit.php:44
+msgid "Your bookmark must have a title and an address"
+msgstr "Su enlace debe tener un t&iacute;tulo y una direcci&oacute;n"
+
+#: ..\..\..\bookmarks.php:114
+#: ..\..\..\edit.php:58
+msgid "Bookmark saved"
+msgstr "Enlace salvado"
+
+#: ..\..\..\bookmarks.php:122
+#: ..\..\..\import.php:99
+#: ..\..\..\importNetscape.php:74
+msgid "There was an error saving your bookmark. Please try again or contact the administrator."
+msgstr "Hay un error al salvar su enlace. Por favor intentelo de nuevo o contacte con el administrador."
+
+#: ..\..\..\bookmarks.php:160
+#: ..\..\..\templates\toolbar.inc.php:13
+msgid "Add a Bookmark"
+msgstr "Agregar"
+
+#: ..\..\..\bookmarks.php:163
+msgid "Add Bookmark"
+msgstr "Agregar Enlace"
+
+#: ..\..\..\bookmarks.php:166
+msgid "You must be logged in before you can add bookmarks."
+msgstr "Debe introducir su usuario y contrase&ntilde;a para poder agregar enlaces"
+
+#: ..\..\..\bookmarks.php:213
+msgid "My Bookmarks"
+msgstr "Mis Enlaces"
+
+#: ..\..\..\edit.php:29
+msgid "Edit Bookmark"
+msgstr "Editar enlace"
+
+#: ..\..\..\edit.php:34
+#, php-format
+msgid "Bookmark with id %s not was not found"
+msgstr "El enlace con id %s no funciona"
+
+#: ..\..\..\edit.php:39
+msgid "You are not allowed to edit this bookmark"
+msgstr "Usted no tiene permisos para editar este enlace"
+
+#: ..\..\..\edit.php:55
+msgid "Error while saving your bookmark"
+msgstr "Se ha producido un error al salvar su enlace"
+
+#: ..\..\..\edit.php:78
+msgid "Failed to delete the bookmark"
+msgstr "Fallo al borrar el enlace"
+
+#: ..\..\..\edit.php:88
+#: ..\..\..\templates\editprofile.tpl.php:52
+msgid "Save Changes"
+msgstr "Guardar Cambios"
+
+#: ..\..\..\functions.inc.php:92
+msgid "message_die() was called multiple times."
+msgstr "message_die() requerido en varios ocasiones."
+
+#: ..\..\..\functions.inc.php:104
+msgid "SQL Error"
+msgstr "Error de SQL"
+
+#: ..\..\..\functions.inc.php:110
+msgid "Line"
+msgstr "L&iacute;nea"
+
+#: ..\..\..\functions.inc.php:110
+#: ..\..\..\templates\importDelicious.tpl.php:8
+#: ..\..\..\templates\importNetscape.tpl.php:9
+msgid "File"
+msgstr "Archivo"
+
+#: ..\..\..\functions.inc.php:116
+msgid "Information"
+msgstr "Informaci&oacute;n"
+
+#: ..\..\..\functions.inc.php:121
+msgid "Critical Information"
+msgstr "Informaci&oacute;n Critica"
+
+#: ..\..\..\functions.inc.php:126
+msgid "An error occured"
+msgstr "Ha habido un error"
+
+#: ..\..\..\functions.inc.php:129
+msgid "General Error"
+msgstr "Error General"
+
+#: ..\..\..\functions.inc.php:137
+msgid "An critical error occured"
+msgstr "Ha habido un error critico"
+
+#: ..\..\..\functions.inc.php:140
+msgid "Critical Error"
+msgstr "Error Critico"
+
+#: ..\..\..\functions.inc.php:149
+msgid "DEBUG MODE"
+msgstr "MODO DEPURACION"
+
+#: ..\..\..\history.php:65
+msgid "History"
+msgstr "Historial"
+
+#: ..\..\..\history.php:66
+#, php-format
+msgid "History for %s"
+msgstr "Historial de %s"
+
+#: ..\..\..\history.php:81
+msgid "Address was not found"
+msgstr "La direcci&oacute;n no existe"
+
+#: ..\..\..\import.php:41
+msgid "Could not open XML input"
+msgstr "No se pude abrir la entrada XML"
+
+#: ..\..\..\import.php:45
+#, php-format
+msgid "XML error: %s at line %d"
+msgstr "Errores: %s en la linea %d del XML"
+
+#: ..\..\..\import.php:54
+msgid "Import Bookmarks from del.icio.us"
+msgstr "Importar enlaces de del.icio.us"
+
+#: ..\..\..\import.php:86
+#: ..\..\..\importNetscape.php:64
+msgid "You have already submitted this bookmark."
+msgstr "Usted ya ha agregado este enlace"
+
+#: ..\..\..\import.php:97
+#: ..\..\..\importNetscape.php:72
+msgid "Bookmark imported."
+msgstr "Enlaces importados."
+
+#: ..\..\..\importNetscape.php:81
+msgid "Import Bookmarks from Browser File"
+msgstr "Importar enlaces de un Navegador"
+
+#: ..\..\..\index.php:32
+msgid "You have now logged out"
+msgstr "Usted esta ahora desconectado"
+
+#: ..\..\..\index.php:39
+#, php-format
+msgid "%s: Recent bookmarks"
+msgstr "%s: Enlaces recientes"
+
+#: ..\..\..\index.php:72
+msgid "Store, share and tag your favourite links"
+msgstr "Almacene, navege y etiquete sus enlaces favoritos"
+
+#: ..\..\..\index.php:73
+msgid "Recent Bookmarks"
+msgstr "Enlaces Recientes"
+
+#: ..\..\..\jsScuttle.php:22
+msgid "Are you sure?"
+msgstr "Esta usted seguro?"
+
+#: ..\..\..\jsScuttle.php:22
+msgid "Yes"
+msgstr "Si"
+
+#: ..\..\..\jsScuttle.php:22
+msgid "No"
+msgstr "No"
+
+#: ..\..\..\jsScuttle.php:68
+msgid "Available"
+msgstr "Disponible"
+
+#: ..\..\..\jsScuttle.php:71
+#, fuzzy
+msgid "Not Available"
+msgstr "No hay enlaces disponibles"
+
+#: ..\..\..\login.php:38
+msgid "The details you have entered are incorrect. Please try again."
+msgstr "Los datos introducidos son incorrectos. Por favor intentelo de nuevo."
+
+#: ..\..\..\login.php:48
+#: ..\..\..\templates\login.tpl.php:26
+#: ..\..\..\templates\toolbar.inc.php:28
+msgid "Log In"
+msgstr "Acceder"
+
+#: ..\..\..\password.php:31
+msgid "You must enter your username."
+msgstr "Introduzca su nombre de usuario"
+
+#: ..\..\..\password.php:35
+#, fuzzy
+msgid "You must enter your <abbr title=\"electronic mail\">e-mail</abbr> address."
+msgstr "Debe <em>especificar</em> usuario, clave, nombre y <abbr title=\"electronic mail\">correo electr&oacute;nico</abbr>."
+
+#: ..\..\..\password.php:42
+msgid "No matches found for that username."
+msgstr "No se encuentra ning&uacute;n usuario con ese nombre"
+
+#: ..\..\..\password.php:45
+#, fuzzy
+msgid "No matches found for that combination of username and <abbr title=\"electronic mail\">e-mail</abbr> address."
+msgstr "Debe <em>especificar</em> usuario, clave, nombre y <abbr title=\"electronic mail\">correolectr&oacute;nico</abbr>."
+
+#: ..\..\..\password.php:53
+#, fuzzy
+msgid "There was an error while generating your new password. Please try again."
+msgstr "Hay un error al salvar su enlace. Por favor intentelo de nuevo o contacte con el administrador."
+
+#: ..\..\..\password.php:57
+#, fuzzy
+msgid "Your new password is:"
+msgstr "Confirmar la nueva clave"
+
+#: ..\..\..\password.php:57
+msgid "To keep your bookmarks secure, you should change this password in your profile the next time you log in."
+msgstr "Para que sean seguros sus enlaces, debe cambiar la clave de su usuario en el siguiente acceso"
+
+#: ..\..\..\password.php:60
+#, fuzzy, php-format
+msgid "%s Account Information"
+msgstr "Informaci&oacute;n"
+
+#: ..\..\..\password.php:62
+#, php-format
+msgid "New password generated and sent to %s"
+msgstr "Se ha creado una nueva clave y se ha enviado a %s"
+
+#: ..\..\..\password.php:69
+#, fuzzy
+msgid "Forgotten Password"
+msgstr "Nueva clave"
+
+#: ..\..\..\populartags.php:54
+#: ..\..\..\templates\dynamictags.inc.php:101
+#: ..\..\..\templates\sidebar.block.common.php:9
+#: ..\..\..\templates\sidebar.block.popular.php:15
+#: ..\..\..\templates\sidebar.block.recent.php:25
+msgid "Popular Tags"
+msgstr "M&aacute;s visitadas"
+
+#: ..\..\..\profile.php:54
+#: ..\..\..\watched.php:114
+msgid "Username was not specified"
+msgstr "Usuario no introducido"
+
+#: ..\..\..\profile.php:60
+#, fuzzy
+msgid "My Profile"
+msgstr "Mi P&eacute;rfil"
+
+#: ..\..\..\profile.php:62
+#: ..\..\..\templates\sidebar.block.profile.php:12
+msgid "Profile"
+msgstr "P&eacute;rfil"
+
+#: ..\..\..\profile.php:80
+msgid "Password and confirmation do not match."
+msgstr "La clave y su confirmaci&oacute;n no es correcta."
+
+#: ..\..\..\profile.php:84
+msgid "Password must be at least 6 characters long."
+msgstr "La clave debe tener al menos 6 acracteres."
+
+#: ..\..\..\profile.php:88
+msgid "E-mail address is not valid."
+msgstr "Correo incorrecto."
+
+#: ..\..\..\profile.php:92
+msgid "An error occurred while saving your changes."
+msgstr "Ha habido un error al guardar los cambios."
+
+#: ..\..\..\profile.php:94
+msgid "Changes saved."
+msgstr "Cambios guardados."
+
+#: ..\..\..\register.php:33
+#, fuzzy
+msgid "You <em>must</em> enter a username, password and e-mail address."
+msgstr "Debe <em>especificar</em> usuario, clave, nombre y <abbr title=\"electronic mail\">correo electr&oacute;nico</abbr>."
+
+#: ..\..\..\register.php:37
+msgid "This username already exists, please make another choice."
+msgstr "Este usuario ya existe, por favor introduzca otro."
+
+#: ..\..\..\register.php:41
+#, fuzzy
+msgid "E-mail address is not valid. Please try again."
+msgstr "Correo incorrecto."
+
+#: ..\..\..\register.php:50
+msgid "You have successfully registered. Enjoy!"
+msgstr "El registro ha sido correcto. Puede continuar!"
+
+#: ..\..\..\register.php:52
+msgid "Registration failed. Please try again."
+msgstr "Registro erroneo. Por favor intentelo de nuevo."
+
+#: ..\..\..\register.php:57
+#: ..\..\..\templates\register.tpl.php:32
+#: ..\..\..\templates\toolbar.inc.php:27
+msgid "Register"
+msgstr "Registrarse"
+
+#: ..\..\..\search.inc.php:29
+#: ..\..\..\search.inc.php:57
+msgid "Search"
+msgstr "Buscar"
+
+#: ..\..\..\search.inc.php:35
+#, fuzzy
+msgid "this user's bookmarks"
+msgstr "enlaces de %s"
+
+#: ..\..\..\search.inc.php:40
+msgid "my bookmarks"
+msgstr "mis enlaces"
+
+#: ..\..\..\search.inc.php:41
+#, fuzzy
+msgid "my watchlist"
+msgstr "mis consultados"
+
+#: ..\..\..\search.inc.php:45
+msgid "all bookmarks"
+msgstr "todos"
+
+#: ..\..\..\search.inc.php:48
+msgid "for"
+msgstr "por"
+
+#: ..\..\..\search.php:91
+#: ..\..\..\search.php:128
+msgid "Search Bookmarks"
+msgstr "Buscar Enlaces"
+
+#: ..\..\..\search.php:97
+msgid "Search Results"
+msgstr "Buscar Resultados"
+
+#: ..\..\..\tags.php:38
+#: ..\..\..\templates\editbookmark.tpl.php:44
+#: ..\..\..\templates\sidebar.block.profile.php:13
+msgid "Tags"
+msgstr "Etiquetas"
+
+#: ..\..\..\watch.php:79
+#, php-format
+msgid "%s Bookmarks"
+msgstr "Enlace de %s"
+
+#: ..\..\..\watch.php:84
+msgid "User removed from your watchlist"
+msgstr "Usuario borrado de consultados"
+
+#: ..\..\..\watch.php:86
+msgid "User added to your watchlist"
+msgstr "Usuario agregado a consultados"
+
+#: ..\..\..\watched.php:105
+#, fuzzy
+msgid "My Watchlist"
+msgstr "Mis Consultados"
+
+#: ..\..\..\watched.php:107
+#: ..\..\..\templates\sidebar.block.profile.php:14
+#: ..\..\..\templates\toolbar.inc.php:12
+#, fuzzy
+msgid "Watchlist"
+msgstr "Consultados"
+
+#: ..\..\..\templates\about.tpl.php:6
+msgid "<strong>Store</strong> all your favourite links in one place, accessible from anywhere."
+msgstr "<strong>Guarde</strong> todos sus enlaces favoritos en un lugar y acceda desde donde quiera."
+
+#: ..\..\..\templates\about.tpl.php:7
+msgid "<strong>Share</strong> your bookmarks with everyone, with friends on your watchlist or just keep them private."
+msgstr "<strong>Comparte</strong> tus enlaces, solo con los amigos de la lista de consultados o mant&eacute;ngalos privados.."
+
+#: ..\..\..\templates\about.tpl.php:8
+msgid "<strong>Tag</strong> your bookmarks with as many labels as you want, instead of wrestling with folders."
+msgstr "<strong>Etiquete</strong> sus enlaces con tantas etiquetas como usted desea, en lugar de pellearse con las carpetas."
+
+#: ..\..\..\templates\about.tpl.php:9
+#, php-format
+msgid "<strong><a href=\"register.php\">Register now</a></strong> to start using %s!"
+msgstr "<strong><a href=\"register.php\">Registrese ahora</a></strong> para usar %s!"
+
+#: ..\..\..\templates\about.tpl.php:12
+msgid "Geek Stuff"
+msgstr "Adelante"
+
+#: ..\..\..\templates\about.tpl.php:14
+#, php-format
+msgid "%s is based on <a href=\"http://sourceforge.net/projects/scuttle/\">an open-source project</a> licensed under the <a href=\"http://www.gnu.org/copyleft/gpl.html\"><acronym title=\"GNU's Not Unix\">GNU</acronym> General Public License</a>. This means you can host it on your own web server for free, whether it is on the Internet, a private network or just your own computer."
+msgstr "%s esta basado en <a href=\"http://sourceforge.net/projects/scuttle/\">un proyecto de codigo abierto</a> licenciado bajo <a href=\"http://www.gnu.org/copyleft/gpl.html\"><acronym title=\"GNU's Not Unix\">GNU</acronym> General Public License</a>. Esto quiere decir que usted puede instalarlo en su propio web server para uso libre, en una red privada o en su propia computadora."
+
+#: ..\..\..\templates\about.tpl.php:15
+#, php-format
+msgid "%1$s supports most of the <a href=\"http://del.icio.us/doc/api\">del.icio.us <abbr title=\"Application Programming Interface\">API</abbr></a>. Almost all of the neat tools made for that system can be modified to work with %1$s instead. If you find a tool that won't let you change the API address, ask the creator to add this setting. You never know, they might just do it."
+msgstr "%1$s esta basado en la <a href=\"http://del.icio.us/doc/api\"><abbr title=\"Application Programming Interface\">API</abbr></a> de <a href=\"http://del.icio.us/doc/api\">del.icio.us <abbr title=\"Application Programming Interface\">API</abbr></a>. La mayor&iacute;a de las herramientas utilizadas para construir este sistema se pueden modificar para trabajar con %1$s. Si usted encuentra una herramienta en la que no puede modificar la direccion de la API, pregunte al creador si puede cambiar esta configuraci&oacute;n. Nunca se sabe, puede que ya se haya cambiado esa configuraci&oacute;n."
+
+#: ..\..\..\templates\bookmarks.tpl.php:17
+#: ..\..\..\templates\tags.tpl.php:7
+msgid "Sort by:"
+msgstr "Por:"
+
+#: ..\..\..\templates\bookmarks.tpl.php:18
+msgid "Date"
+msgstr "Fecha"
+
+#: ..\..\..\templates\bookmarks.tpl.php:19
+#: ..\..\..\templates\editbookmark.tpl.php:34
+msgid "Title"
+msgstr "T&iacute;tulo"
+
+#: ..\..\..\templates\bookmarks.tpl.php:23
+msgid "URL"
+msgstr "URL"
+
+#: ..\..\..\templates\bookmarks.tpl.php:60
+msgid "Edit"
+msgstr "Editar"
+
+#: ..\..\..\templates\bookmarks.tpl.php:60
+msgid "Delete"
+msgstr "Borrar"
+
+#: ..\..\..\templates\bookmarks.tpl.php:66
+msgid "by"
+msgstr "por"
+
+#: ..\..\..\templates\bookmarks.tpl.php:78
+#, fuzzy, php-format
+msgid " and %s1 other%s"
+msgstr " y %s mas"
+
+#: ..\..\..\templates\bookmarks.tpl.php:81
+#, fuzzy, php-format
+msgid " and %2$s%1$s others%3$s"
+msgstr " y %s mas"
+
+#: ..\..\..\templates\bookmarks.tpl.php:90
+msgid "Copy"
+msgstr "Copiar"
+
+#: ..\..\..\templates\bookmarks.tpl.php:136
+#: ..\..\..\templates\bookmarks.tpl.php:142
+msgid "First"
+msgstr "Primera"
+
+#: ..\..\..\templates\bookmarks.tpl.php:137
+#: ..\..\..\templates\bookmarks.tpl.php:143
+msgid "Previous"
+msgstr "Anterior"
+
+#: ..\..\..\templates\bookmarks.tpl.php:150
+#: ..\..\..\templates\bookmarks.tpl.php:153
+msgid "Next"
+msgstr "Siguiente"
+
+#: ..\..\..\templates\bookmarks.tpl.php:151
+#: ..\..\..\templates\bookmarks.tpl.php:154
+msgid "Last"
+msgstr "&Uacute;ltima"
+
+#: ..\..\..\templates\bookmarks.tpl.php:156
+#, php-format
+msgid "Page %d of %d"
+msgstr "P&aacute;gina %d de %d"
+
+#: ..\..\..\templates\bookmarks.tpl.php:160
+msgid "No bookmarks available"
+msgstr "No hay enlaces disponibles"
+
+#: ..\..\..\templates\dynamictags.inc.php:108
+#: ..\..\..\templates\sidebar.block.common.php:15
+#: ..\..\..\templates\sidebar.block.popular.php:21
+#: ..\..\..\templates\sidebar.block.recent.php:20
+#: ..\..\..\templates\tags.tpl.php:16
+#, fuzzy
+msgid "bookmark"
+msgid_plural "bookmarks"
+msgstr[0] "enlace"
+msgstr[1] "enlaces"
+
+#: ..\..\..\templates\editbookmark.tpl.php:29
+msgid "Address"
+msgstr "Direcci&oacute;n"
+
+#: ..\..\..\templates\editbookmark.tpl.php:31
+#: ..\..\..\templates\editbookmark.tpl.php:36
+#: ..\..\..\templates\editprofile.tpl.php:31
+msgid "Required"
+msgstr "Requerido"
+
+#: ..\..\..\templates\editbookmark.tpl.php:39
+#: ..\..\..\templates\editprofile.tpl.php:47
+#: ..\..\..\templates\profile.tpl.php:28
+msgid "Description"
+msgstr "Descripci&oacute;n"
+
+#: ..\..\..\templates\editbookmark.tpl.php:46
+msgid "Comma-separated"
+msgstr "Con comas"
+
+#: ..\..\..\templates\editbookmark.tpl.php:49
+#: ..\..\..\templates\importDelicious.tpl.php:15
+#: ..\..\..\templates\importNetscape.tpl.php:16
+msgid "Privacy"
+msgstr "Permisos"
+
+#: ..\..\..\templates\editbookmark.tpl.php:52
+#: ..\..\..\templates\importDelicious.tpl.php:18
+#: ..\..\..\templates\importNetscape.tpl.php:19
+msgid "Public"
+msgstr "P&uacute;blico"
+
+#: ..\..\..\templates\editbookmark.tpl.php:53
+#: ..\..\..\templates\importDelicious.tpl.php:19
+#: ..\..\..\templates\importNetscape.tpl.php:20
+msgid "Shared with Watch List"
+msgstr "Compartido en Consultados"
+
+#: ..\..\..\templates\editbookmark.tpl.php:54
+#: ..\..\..\templates\importDelicious.tpl.php:20
+#: ..\..\..\templates\importNetscape.tpl.php:21
+msgid "Private"
+msgstr "Privado"
+
+#: ..\..\..\templates\editbookmark.tpl.php:66
+msgid "Delete Bookmark"
+msgstr "Borrar enlace"
+
+#: ..\..\..\templates\editbookmark.tpl.php:93
+msgid "Bookmarklet"
+msgstr "Marcadores"
+
+#: ..\..\..\templates\editbookmark.tpl.php:94
+#, php-format
+msgid "Drag one of the following bookmarklets to your browser's bookmarks and click it whenever you want to add the page you are on to %s"
+msgstr "Arrastre los enlaces a los marcadores de su navegador y pulselos siempre que usted desee agregar la pagina que esta viendo a %s"
+
+#: ..\..\..\templates\editbookmark.tpl.php:106
+#, php-format
+msgid "Post to %s"
+msgstr "Agregar a %s"
+
+#: ..\..\..\templates\editbookmark.tpl.php:107
+#, php-format
+msgid "Post to %s (Pop-up)"
+msgstr "Agregar a %s (Pop-up)"
+
+#: ..\..\..\templates\editbookmark.tpl.php:111
+#: ..\..\..\templates\importDelicious.tpl.php:26
+#: ..\..\..\templates\importNetscape.tpl.php:27
+msgid "Import"
+msgstr "Importar"
+
+#: ..\..\..\templates\editbookmark.tpl.php:113
+msgid "Import bookmarks from bookmark file"
+msgstr "Improtar enlaces de un archivo"
+
+#: ..\..\..\templates\editbookmark.tpl.php:113
+msgid "Internet Explorer, Mozilla Firefox and Netscape"
+msgstr "Internet Explorer, Mozilla Firefox y Netscape"
+
+#: ..\..\..\templates\editbookmark.tpl.php:114
+msgid "Import bookmarks from del.icio.us"
+msgstr "Importar los enlaces de del.icio.us"
+
+#: ..\..\..\templates\editprofile.tpl.php:10
+msgid "Account Details"
+msgstr "Detalles de usuario"
+
+#: ..\..\..\templates\editprofile.tpl.php:14
+#: ..\..\..\templates\login.tpl.php:15
+#: ..\..\..\templates\password.tpl.php:10
+#: ..\..\..\templates\profile.tpl.php:7
+#: ..\..\..\templates\register.tpl.php:16
+msgid "Username"
+msgstr "Usuario"
+
+#: ..\..\..\templates\editprofile.tpl.php:19
+msgid "New Password"
+msgstr "Nueva clave"
+
+#: ..\..\..\templates\editprofile.tpl.php:24
+#, fuzzy
+msgid "Confirm Password"
+msgstr "Confirmar la clave"
+
+#: ..\..\..\templates\editprofile.tpl.php:29
+#: ..\..\..\templates\register.tpl.php:26
+msgid "E-mail"
+msgstr "Correo"
+
+#: ..\..\..\templates\editprofile.tpl.php:35
+msgid "Personal Details"
+msgstr "Datos del usuario"
+
+#: ..\..\..\templates\editprofile.tpl.php:39
+#: ..\..\..\templates\profile.tpl.php:12
+msgid "Name"
+msgstr "Nombre"
+
+#: ..\..\..\templates\editprofile.tpl.php:43
+#: ..\..\..\templates\profile.tpl.php:18
+msgid "Homepage"
+msgstr "P&aacute;gina web"
+
+#: ..\..\..\templates\error.404.tpl.php:5
+msgid "Not Found"
+msgstr "No funciona"
+
+#: ..\..\..\templates\error.404.tpl.php:6
+msgid "The requested URL was not found on this server"
+msgstr "No se encontr&oacute; la URL solicitada"
+
+#: ..\..\..\templates\error.500.tpl.php:5
+msgid "General server error"
+msgstr "Error general del servidor"
+
+#: ..\..\..\templates\error.500.tpl.php:6
+msgid "The requested URL could not be processed"
+msgstr "La URL solicitada no puede ser encontrada"
+
+#: ..\..\..\templates\importDelicious.tpl.php:33
+msgid "Log in to the <a href=\"http://del.icio.us/api/posts/all\">export page at del.icio.us</a>"
+msgstr "Registrese para <a href=\"http://del.icio.us/api/posts/all\">exportar la pagina a del.icio.us</a>"
+
+#: ..\..\..\templates\importDelicious.tpl.php:34
+msgid "Save the resulting <abbr title=\"Extensible Markup Language\">XML</abbr> file to your computer"
+msgstr "Guardar los resultados en un archivo <abbr title=\"Extensible Markup Language\">XML</abbr> de su ordenador"
+
+#: ..\..\..\templates\importDelicious.tpl.php:35
+msgid "Click <kbd>Browse...</kbd> to find this file on your computer. The maximum size the file can be is 1MB"
+msgstr "Pulse <kbd>Examinar...</kbd> para buscar el archivo en su ordenador. El tamaño maximo no puede ser superior a 1MB"
+
+#: ..\..\..\templates\importDelicious.tpl.php:36
+#: ..\..\..\templates\importNetscape.tpl.php:43
+msgid "Select the default privacy setting for your imported bookmarks"
+msgstr "Elija los permisos para los enlaces importados"
+
+#: ..\..\..\templates\importDelicious.tpl.php:37
+#: ..\..\..\templates\importNetscape.tpl.php:44
+msgid "Click <kbd>Import</kbd> to start importing the bookmarks; it may take a minute"
+msgstr "Pulse <kbd>Importar</kbd> para comenzar a importar los enlaces, esto puede tartar algunos minutos"
+
+#: ..\..\..\templates\importNetscape.tpl.php:32
+msgid "Instructions"
+msgstr "Instrucciones"
+
+#: ..\..\..\templates\importNetscape.tpl.php:35
+msgid "Export your bookmarks from your browser to a file"
+msgstr "Expote sus enlaces a su navegador a un archivo"
+
+#: ..\..\..\templates\importNetscape.tpl.php:37
+msgid "Internet Explorer: <kbd>File &gt; Import and Export... &gt; Export Favorites"
+msgstr "Internet Explorer: <kbd>Archivo &gt; Importar y Exportar... &gt; Exportar Favoritos"
+
+#: ..\..\..\templates\importNetscape.tpl.php:38
+msgid "Mozilla Firefox: <kbd>Bookmarks &gt; Manage Bookmarks... &gt; File &gt; Export..."
+msgstr "Mozilla Firefox: <kbd>Enlaces &gt; Manejar Enlaces... &gt; Archivo &gt; Exportar..."
+
+#: ..\..\..\templates\importNetscape.tpl.php:39
+msgid "Netscape: <kbd>Bookmarks &gt; Manage Bookmarks... &gt; Tools &gt; Export..."
+msgstr "Netscape: <kbd>Enlaces &gt; Manejar Enlaces... &gt; Utilidades &gt; Exportar..."
+
+#: ..\..\..\templates\importNetscape.tpl.php:42
+msgid "Click <kbd>Browse...</kbd> to find the saved bookmark file on your computer. The maximum size the file can be is 1MB"
+msgstr "Pulse <kbd>Examinar...</kbd> para buscar los enlaces guardados en un archivo de us ordenador. El tamaño maximo no puede ser superior a 1MB"
+
+#: ..\..\..\templates\login.tpl.php:20
+#: ..\..\..\templates\register.tpl.php:21
+msgid "Password"
+msgstr "Clave"
+
+#: ..\..\..\templates\login.tpl.php:22
+msgid "Don't ask for my password for 2 weeks"
+msgstr "Recordar mi clave 2 semanas"
+
+#: ..\..\..\templates\login.tpl.php:30
+msgid "Forgotten your password?"
+msgstr "Olvido su clave?"
+
+#: ..\..\..\templates\password.tpl.php:5
+#, php-format
+msgid "If you have forgotten your password, %s can generate a new one. Enter the username and e-mail address of your account into the form below and we will e-mail your new password to you."
+msgstr "Si olvido su clave, %s puede crearle una nueva. Introduzca su direccion de correo electr&oacute;nico de su perfil en el formulario siguiente y se le enviara una nueva clave"
+
+#: ..\..\..\templates\password.tpl.php:14
+msgid "<abbr title=\"Electronic mail\">E-mail</abbr>"
+msgstr "<abbr title=\"Electronic mail\">Correo</abbr>"
+
+#: ..\..\..\templates\password.tpl.php:19
+#, fuzzy
+msgid "Generate Password"
+msgstr "Nueva clave"
+
+#: ..\..\..\templates\profile.tpl.php:23
+msgid "Member Since"
+msgstr "Miembro desde"
+
+#: ..\..\..\templates\profile.tpl.php:35
+#: ..\..\..\templates\sidebar.block.watchlist.php:8
+#, fuzzy
+msgid "Watching"
+msgstr "Consultados"
+
+#: ..\..\..\templates\profile.tpl.php:50
+msgid "Watched By"
+msgstr "Consultado de"
+
+#: ..\..\..\templates\register.tpl.php:11
+#, php-format
+msgid "Sign up here to create a free %s account. All the information requested below is required"
+msgstr "Inserte los datos para crear una cuenta gratis en %s. Es cesaria toda la informacion requerida"
+
+#: ..\..\..\templates\rss.tpl.php:9
+#, fuzzy, php-format
+msgid "Recent bookmarks posted to %s"
+msgstr "Enlaces recientes agregados a %s"
+
+#: ..\..\..\templates\rss.tpl.php:17
+#: ..\..\..\templates\rss.tpl.php:19
+msgid "No bookmarks found"
+msgstr "No se han encontrado enlaces"
+
+#: ..\..\..\templates\sidebar.block.recent.php:15
+msgid "Recent Tags"
+msgstr "Recientes"
+
+#: ..\..\..\templates\sidebar.block.related.php:15
+msgid "Related Tags"
+msgstr "Etiquetas mencionadas"
+
+#: ..\..\..\templates\sidebar.block.watchstatus.php:10
+msgid "Remove from Watchlist"
+msgstr "Borrar de Consultados"
+
+#: ..\..\..\templates\sidebar.block.watchstatus.php:12
+msgid "Add to Watchlist"
+msgstr "Agregar a Consultados"
+
+#: ..\..\..\templates\sidebar.block.watchstatus.php:17
+#, fuzzy
+msgid "Actions"
+msgstr "Instrucciones"
+
+#: ..\..\..\templates\tags.tpl.php:8
+msgid "Alphabet"
+msgstr "Alfab&eacute;tico"
+
+#: ..\..\..\templates\tags.tpl.php:9
+#, fuzzy
+msgid "Popularity"
+msgstr "Mas visitadas"
+
+#: ..\..\..\templates\toolbar.inc.php:11
+#, fuzzy
+msgid "Bookmarks"
+msgstr "Enlaces"
+
+#: ..\..\..\templates\toolbar.inc.php:16
+msgid "Log Out"
+msgstr "Salir"
+
diff --git a/locales/fr_FR/LC_MESSAGES/messages.mo b/locales/fr_FR/LC_MESSAGES/messages.mo
new file mode 100644
index 0000000..d91e845
--- /dev/null
+++ b/locales/fr_FR/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/locales/fr_FR/LC_MESSAGES/messages.po b/locales/fr_FR/LC_MESSAGES/messages.po
new file mode 100644
index 0000000..96572aa
--- /dev/null
+++ b/locales/fr_FR/LC_MESSAGES/messages.po
@@ -0,0 +1,835 @@
+# Scuttle fr-FR Translation
+# Copyright (C) 2005 - 2006 Scuttle project
+# This file is distributed under the same license as the Scuttle package.
+# <toony.sf@chezouam.net>
+# nitram <nitram@no-log.org>
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Scuttle\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2005-11-10 16:58+0100\n"
+"PO-Revision-Date: 2006-03-26 14:29-0800\n"
+"Last-Translator: Marcus Campbell <marcus.campbell@gmail.com>\n"
+"Language-Team: fr-FR <toony.sf@chezouam.net>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-Language: French\n"
+"X-Poedit-Country: FRANCE\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: ..\..\..\about.php:25
+#: ..\..\..\templates\toolbar.inc.php:24
+msgid "About"
+msgstr "À propos"
+
+#: ..\..\..\ajaxDelete.php:29
+msgid "You are not allowed to delete this bookmark"
+msgstr "Vous ne pouvez pas supprimer ce signet."
+
+#: ..\..\..\ajaxDelete.php:33
+#, fuzzy
+msgid "Failed to delete bookmark"
+msgstr "Erreur de suppression du signet"
+
+#: ..\..\..\alltags.php:50
+msgid "All Tags"
+msgstr "Tous les labels"
+
+#: ..\..\..\alltags.php:59
+#: ..\..\..\populartags.php:63
+#: ..\..\..\profile.php:46
+#: ..\..\..\rss.php:55
+#: ..\..\..\search.php:61
+#: ..\..\..\watch.php:35
+#: ..\..\..\watched.php:62
+#, php-format
+msgid "User with username %s not was not found"
+msgstr "L'utilisateur %s n'a pas été trouvé."
+
+#: ..\..\..\bookmarks.php:71
+#, fuzzy, php-format
+msgid "User with username %s was not found"
+msgstr "L'utilisateur %s n'a pas été trouvé."
+
+#: ..\..\..\bookmarks.php:94
+#: ..\..\..\edit.php:44
+msgid "Your bookmark must have a title and an address"
+msgstr "Votre signet doit avoir un titre et une adresse."
+
+#: ..\..\..\bookmarks.php:114
+#: ..\..\..\edit.php:58
+msgid "Bookmark saved"
+msgstr "Signet enregistré."
+
+#: ..\..\..\bookmarks.php:122
+#: ..\..\..\import.php:99
+#: ..\..\..\importNetscape.php:74
+msgid "There was an error saving your bookmark. Please try again or contact the administrator."
+msgstr "Il y a eu une erreur en enregistrant ce signet. Veuillez rééssayer ou contacter votre administrateur."
+
+#: ..\..\..\bookmarks.php:160
+#: ..\..\..\templates\toolbar.inc.php:13
+msgid "Add a Bookmark"
+msgstr "Ajouter un signet"
+
+#: ..\..\..\bookmarks.php:163
+msgid "Add Bookmark"
+msgstr "Ajouter signet"
+
+#: ..\..\..\bookmarks.php:166
+msgid "You must be logged in before you can add bookmarks."
+msgstr "Vous devez être authentifié avant de pouvoir ajouter des signets."
+
+#: ..\..\..\bookmarks.php:213
+#, fuzzy
+msgid "My Bookmarks"
+msgstr "Mes signets"
+
+#: ..\..\..\edit.php:29
+msgid "Edit Bookmark"
+msgstr "Editer le signet"
+
+#: ..\..\..\edit.php:34
+#, fuzzy, php-format
+msgid "Bookmark with id %s not was not found"
+msgstr "Signet non trouvé"
+
+#: ..\..\..\edit.php:39
+msgid "You are not allowed to edit this bookmark"
+msgstr "Vous n'êtes pas autorisé à éditer ce signet."
+
+#: ..\..\..\edit.php:55
+msgid "Error while saving your bookmark"
+msgstr "Erreur pendant l'enregistrement de votre signet."
+
+#: ..\..\..\edit.php:78
+#, fuzzy
+msgid "Failed to delete the bookmark"
+msgstr "Vous ne pouvez pas supprimer ce signet."
+
+#: ..\..\..\edit.php:88
+#: ..\..\..\templates\editprofile.tpl.php:52
+msgid "Save Changes"
+msgstr "Enregister les modifications"
+
+#: ..\..\..\functions.inc.php:92
+msgid "message_die() was called multiple times."
+msgstr "message_die() was called multiple times. ?"
+
+#: ..\..\..\functions.inc.php:104
+msgid "SQL Error"
+msgstr "Erreur SQL"
+
+#: ..\..\..\functions.inc.php:110
+msgid "Line"
+msgstr "Ligne"
+
+#: ..\..\..\functions.inc.php:110
+#: ..\..\..\templates\importDelicious.tpl.php:8
+#: ..\..\..\templates\importNetscape.tpl.php:9
+msgid "File"
+msgstr "Fichier"
+
+#: ..\..\..\functions.inc.php:116
+#, fuzzy
+msgid "Information"
+msgstr "Instructions"
+
+#: ..\..\..\functions.inc.php:121
+msgid "Critical Information"
+msgstr "Information critique."
+
+#: ..\..\..\functions.inc.php:126
+msgid "An error occured"
+msgstr "Une erreur s'est produite."
+
+#: ..\..\..\functions.inc.php:129
+msgid "General Error"
+msgstr "Erreur générale."
+
+#: ..\..\..\functions.inc.php:137
+msgid "An critical error occured"
+msgstr "Une erreur critique s'est produite."
+
+#: ..\..\..\functions.inc.php:140
+msgid "Critical Error"
+msgstr "Erreur critique."
+
+#: ..\..\..\functions.inc.php:149
+msgid "DEBUG MODE"
+msgstr "Mode de débogage."
+
+#: ..\..\..\history.php:65
+msgid "History"
+msgstr "Historique"
+
+#: ..\..\..\history.php:66
+#, php-format
+msgid "History for %s"
+msgstr "Historique de %s"
+
+#: ..\..\..\history.php:81
+msgid "Address was not found"
+msgstr "L'adresse n'a pas été trouvée."
+
+#: ..\..\..\import.php:41
+msgid "Could not open XML input"
+msgstr "Impossible d'ouvrir le flux XML."
+
+#: ..\..\..\import.php:45
+#, php-format
+msgid "XML error: %s at line %d"
+msgstr "Erreur XML: %s à la ligne %d"
+
+#: ..\..\..\import.php:54
+msgid "Import Bookmarks from del.icio.us"
+msgstr "Importer les signet depuis del.icio.us"
+
+#: ..\..\..\import.php:86
+#: ..\..\..\importNetscape.php:64
+#, fuzzy
+msgid "You have already submitted this bookmark."
+msgstr "Vous avez déjà enregistré ce signet"
+
+#: ..\..\..\import.php:97
+#: ..\..\..\importNetscape.php:72
+#, fuzzy
+msgid "Bookmark imported."
+msgstr "Signets importés."
+
+#: ..\..\..\importNetscape.php:81
+#, fuzzy
+msgid "Import Bookmarks from Browser File"
+msgstr "Importer les signets depuis un fichier"
+
+#: ..\..\..\index.php:32
+msgid "You have now logged out"
+msgstr "Vous êtes maintenant déconnecté."
+
+#: ..\..\..\index.php:39
+#, php-format
+msgid "%s: Recent bookmarks"
+msgstr "%s: Signets récents"
+
+#: ..\..\..\index.php:72
+msgid "Store, share and tag your favourite links"
+msgstr "Conservez, partagez et taggez vos liens favoris"
+
+#: ..\..\..\index.php:73
+msgid "Recent Bookmarks"
+msgstr "Signets récents"
+
+#: ..\..\..\jsScuttle.php:22
+msgid "Are you sure?"
+msgstr "Etes-vous sûr ?"
+
+#: ..\..\..\jsScuttle.php:22
+msgid "Yes"
+msgstr "Oui"
+
+#: ..\..\..\jsScuttle.php:22
+msgid "No"
+msgstr "Non"
+
+#: ..\..\..\jsScuttle.php:68
+msgid "Available"
+msgstr "Disponible"
+
+#: ..\..\..\jsScuttle.php:71
+msgid "Not Available"
+msgstr "Non Disponible"
+
+#: ..\..\..\login.php:38
+#, fuzzy
+msgid "The details you have entered are incorrect. Please try again."
+msgstr "Les informations que vous avez entrées sont incorrectes. Veuillez recommencer."
+
+#: ..\..\..\login.php:48
+#: ..\..\..\templates\login.tpl.php:26
+#: ..\..\..\templates\toolbar.inc.php:28
+msgid "Log In"
+msgstr "Se connecter"
+
+#: ..\..\..\password.php:31
+msgid "You must enter your username."
+msgstr "Vous devez entrer votre nom d'utilisateur."
+
+#: ..\..\..\password.php:35
+msgid "You must enter your <abbr title=\"electronic mail\">e-mail</abbr> address."
+msgstr "Vous <em>devez</em> saisir une <abbr title=\"adresse électronique\">E-mail</abbr>."
+
+#: ..\..\..\password.php:42
+msgid "No matches found for that username."
+msgstr "Rien de trouvé pour ce nom d'utilisateur."
+
+#: ..\..\..\password.php:45
+#, fuzzy
+msgid "No matches found for that combination of username and <abbr title=\"electronic mail\">e-mail</abbr> address."
+msgstr "Nous n'avons rien trouvé pour cette combinaison de nom d'utilisateur et d'<abbr title=\"adresse mail\">e-mail</abbr>."
+
+#: ..\..\..\password.php:53
+msgid "There was an error while generating your new password. Please try again."
+msgstr "Il y a eu une erreur en enregistrant ce signet. Veuillez rééssayer ou contacter votre administrateur."
+
+#: ..\..\..\password.php:57
+msgid "Your new password is:"
+msgstr "Votre nouveau mot de passe est:"
+
+#: ..\..\..\password.php:57
+msgid "To keep your bookmarks secure, you should change this password in your profile the next time you log in."
+msgstr "Pour garder vos signets sûrs, vous devriez changer ce mot de passe dans votre profil lors de votre prochaine authentification."
+
+#: ..\..\..\password.php:60
+#, php-format
+msgid "%s Account Information"
+msgstr "Informations du compte de %s"
+
+#: ..\..\..\password.php:62
+#, php-format
+msgid "New password generated and sent to %s"
+msgstr "Nouveau mot de passe généré et envoyé à l'adresse %s"
+
+#: ..\..\..\password.php:69
+msgid "Forgotten Password"
+msgstr "Mot de passe oublié"
+
+#: ..\..\..\populartags.php:54
+#: ..\..\..\templates\dynamictags.inc.php:101
+#: ..\..\..\templates\sidebar.block.common.php:9
+#: ..\..\..\templates\sidebar.block.popular.php:15
+#: ..\..\..\templates\sidebar.block.recent.php:25
+msgid "Popular Tags"
+msgstr "Labels populaires"
+
+#: ..\..\..\profile.php:54
+#: ..\..\..\watched.php:114
+msgid "Username was not specified"
+msgstr "Le nom d'utilisateur n'a pas été spécifié."
+
+#: ..\..\..\profile.php:60
+msgid "My Profile"
+msgstr "Mon Profil"
+
+#: ..\..\..\profile.php:62
+#: ..\..\..\templates\sidebar.block.profile.php:12
+msgid "Profile"
+msgstr "Profil"
+
+#: ..\..\..\profile.php:80
+msgid "Password and confirmation do not match."
+msgstr "Le mot de passe et sa vérification ne correspondent pas."
+
+#: ..\..\..\profile.php:84
+msgid "Password must be at least 6 characters long."
+msgstr "Le mot de passe doit avoir au moins 6 caractères."
+
+#: ..\..\..\profile.php:88
+msgid "E-mail address is not valid."
+msgstr "Adresse de courrier électronique invalide."
+
+#: ..\..\..\profile.php:92
+msgid "An error occurred while saving your changes."
+msgstr "Une erreur s'est produite pendant l'enregistrement de vos modifications."
+
+#: ..\..\..\profile.php:94
+#, fuzzy
+msgid "Changes saved."
+msgstr "Modifications enregistrées."
+
+#: ..\..\..\register.php:33
+#, fuzzy
+msgid "You <em>must</em> enter a username, password and e-mail address."
+msgstr "Vous <em>devez</em> saisir un nom d'utilisateur, un mot de passe, un nom et un <abbr title=\"adresse électronique\">E-mail</abbr>"
+
+#: ..\..\..\register.php:37
+msgid "This username already exists, please make another choice."
+msgstr "Ce nom d'utilisateur existe déjà, veuillez en choisir un autre."
+
+#: ..\..\..\register.php:41
+msgid "E-mail address is not valid. Please try again."
+msgstr "Adresse de courrier électronique invalide. Veuilez réessayer."
+
+#: ..\..\..\register.php:50
+#, fuzzy
+msgid "You have successfully registered. Enjoy!"
+msgstr "Votre inscription a bien été prise en compte !"
+
+#: ..\..\..\register.php:52
+msgid "Registration failed. Please try again."
+msgstr "Enregistrement raté. Veuillez rééssayer."
+
+#: ..\..\..\register.php:57
+#: ..\..\..\templates\register.tpl.php:32
+#: ..\..\..\templates\toolbar.inc.php:27
+msgid "Register"
+msgstr "S'enregistrer"
+
+#: ..\..\..\search.inc.php:29
+#: ..\..\..\search.inc.php:57
+msgid "Search"
+msgstr "Chercher"
+
+#: ..\..\..\search.inc.php:35
+msgid "this user's bookmarks"
+msgstr "les signets de cet utilisateur"
+
+#: ..\..\..\search.inc.php:40
+msgid "my bookmarks"
+msgstr "mes signets"
+
+#: ..\..\..\search.inc.php:41
+msgid "my watchlist"
+msgstr "ma liste des consultés"
+
+#: ..\..\..\search.inc.php:45
+msgid "all bookmarks"
+msgstr "tous les signets"
+
+#: ..\..\..\search.inc.php:48
+msgid "for"
+msgstr "pour"
+
+#: ..\..\..\search.php:91
+#: ..\..\..\search.php:128
+msgid "Search Bookmarks"
+msgstr "Recherche de signets"
+
+#: ..\..\..\search.php:97
+msgid "Search Results"
+msgstr "Résulats de recherche"
+
+#: ..\..\..\tags.php:38
+#: ..\..\..\templates\editbookmark.tpl.php:44
+#: ..\..\..\templates\sidebar.block.profile.php:13
+msgid "Tags"
+msgstr "Labels"
+
+#: ..\..\..\watch.php:79
+#, php-format
+msgid "%s Bookmarks"
+msgstr "Signets de %s"
+
+#: ..\..\..\watch.php:84
+msgid "User removed from your watchlist"
+msgstr "Utilisateur enlevé de votre liste des consultés"
+
+#: ..\..\..\watch.php:86
+msgid "User added to your watchlist"
+msgstr "Utilisateur ajouté à la liste des consultés."
+
+#: ..\..\..\watched.php:105
+#, fuzzy
+msgid "My Watchlist"
+msgstr "Liste des signets vus"
+
+#: ..\..\..\watched.php:107
+#: ..\..\..\templates\sidebar.block.profile.php:14
+#: ..\..\..\templates\toolbar.inc.php:12
+#, fuzzy
+msgid "Watchlist"
+msgstr "Liste des signets vus"
+
+#: ..\..\..\templates\about.tpl.php:6
+msgid "<strong>Store</strong> all your favourite links in one place, accessible from anywhere."
+msgstr "<strong>Gardez</strong> tous vos signets au même endroit, accessible partout. "
+
+#: ..\..\..\templates\about.tpl.php:7
+#, fuzzy
+msgid "<strong>Share</strong> your bookmarks with everyone, with friends on your watchlist or just keep them private."
+msgstr "<strong>Partagez</strong> vos signets avec tout le monde, les utilisateurs autorisés ou uniquement pour vous."
+
+#: ..\..\..\templates\about.tpl.php:8
+msgid "<strong>Tag</strong> your bookmarks with as many labels as you want, instead of wrestling with folders."
+msgstr "<strong>Taggez</strong> vos signets avec autant de labels que vous le souhaitez au lieu de les hierarchiser avec des dossiers."
+
+#: ..\..\..\templates\about.tpl.php:9
+#, fuzzy, php-format
+msgid "<strong><a href=\"register.php\">Register now</a></strong> to start using %s!"
+msgstr "<a href=\"register.php\">Enregistrez-vous</a> maintenant pour poster vos propres signets !"
+
+#: ..\..\..\templates\about.tpl.php:12
+msgid "Geek Stuff"
+msgstr "(Geek Stuff)"
+
+#: ..\..\..\templates\about.tpl.php:14
+#, php-format
+msgid "%s is based on <a href=\"http://sourceforge.net/projects/scuttle/\">an open-source project</a> licensed under the <a href=\"http://www.gnu.org/copyleft/gpl.html\"><acronym title=\"GNU's Not Unix\">GNU</acronym> General Public License</a>. This means you can host it on your own web server for free, whether it is on the Internet, a private network or just your own computer."
+msgstr "%s est basé sur <a href=\"http://sourceforge.net/projects/scuttle/\">un projet open-source</a>, sous la license <a href=\"http://www.gnu.org/copyleft/gpl.html\"><acronym title=\"GNU's Not Unix\">GNU</acronym> General Public License</a>. Vous pouvez donc héberger Scuttle sur votre propre serveur gratuitement, qu'il soit relié à Internet, dans un réseau privé ou juste sur votre ordinateur personnel."
+
+#: ..\..\..\templates\about.tpl.php:15
+#, php-format
+msgid "%1$s supports most of the <a href=\"http://del.icio.us/doc/api\">del.icio.us <abbr title=\"Application Programming Interface\">API</abbr></a>. Almost all of the neat tools made for that system can be modified to work with %1$s instead. If you find a tool that won't let you change the API address, ask the creator to add this setting. You never know, they might just do it."
+msgstr "%1$s supporte la plupart de l'<a href=\"http://del.icio.us/doc/api\">del.icio.us <abbr title=\"Application Programming Interface\">API</abbr></a>."
+
+#: ..\..\..\templates\bookmarks.tpl.php:17
+#: ..\..\..\templates\tags.tpl.php:7
+msgid "Sort by:"
+msgstr "Classer par :"
+
+#: ..\..\..\templates\bookmarks.tpl.php:18
+msgid "Date"
+msgstr "Date"
+
+#: ..\..\..\templates\bookmarks.tpl.php:19
+#: ..\..\..\templates\editbookmark.tpl.php:34
+msgid "Title"
+msgstr "Titre"
+
+#: ..\..\..\templates\bookmarks.tpl.php:23
+msgid "URL"
+msgstr "URL"
+
+#: ..\..\..\templates\bookmarks.tpl.php:60
+msgid "Edit"
+msgstr "Editer"
+
+#: ..\..\..\templates\bookmarks.tpl.php:60
+msgid "Delete"
+msgstr "Supprimer"
+
+#: ..\..\..\templates\bookmarks.tpl.php:66
+msgid "by"
+msgstr "par"
+
+#: ..\..\..\templates\bookmarks.tpl.php:78
+#, fuzzy, php-format
+msgid " and %s1 other%s"
+msgstr " et les autres %s"
+
+#: ..\..\..\templates\bookmarks.tpl.php:81
+#, fuzzy, php-format
+msgid " and %2$s%1$s others%3$s"
+msgstr " et les autres %s"
+
+#: ..\..\..\templates\bookmarks.tpl.php:90
+msgid "Copy"
+msgstr "Copier"
+
+#: ..\..\..\templates\bookmarks.tpl.php:136
+#: ..\..\..\templates\bookmarks.tpl.php:142
+msgid "First"
+msgstr "Première"
+
+#: ..\..\..\templates\bookmarks.tpl.php:137
+#: ..\..\..\templates\bookmarks.tpl.php:143
+msgid "Previous"
+msgstr "Précédent"
+
+#: ..\..\..\templates\bookmarks.tpl.php:150
+#: ..\..\..\templates\bookmarks.tpl.php:153
+msgid "Next"
+msgstr "Suivant"
+
+#: ..\..\..\templates\bookmarks.tpl.php:151
+#: ..\..\..\templates\bookmarks.tpl.php:154
+msgid "Last"
+msgstr "Dernière"
+
+#: ..\..\..\templates\bookmarks.tpl.php:156
+#, php-format
+msgid "Page %d of %d"
+msgstr "Page %d de %d"
+
+#: ..\..\..\templates\bookmarks.tpl.php:160
+msgid "No bookmarks available"
+msgstr "Pas de signets disponibles."
+
+#: ..\..\..\templates\dynamictags.inc.php:108
+#: ..\..\..\templates\sidebar.block.common.php:15
+#: ..\..\..\templates\sidebar.block.popular.php:21
+#: ..\..\..\templates\sidebar.block.recent.php:20
+#: ..\..\..\templates\tags.tpl.php:16
+#, fuzzy
+msgid "bookmark"
+msgid_plural "bookmarks"
+msgstr[0] "Signet"
+msgstr[1] "Signets"
+
+#: ..\..\..\templates\editbookmark.tpl.php:29
+msgid "Address"
+msgstr "Adresse"
+
+#: ..\..\..\templates\editbookmark.tpl.php:31
+#: ..\..\..\templates\editbookmark.tpl.php:36
+#: ..\..\..\templates\editprofile.tpl.php:31
+msgid "Required"
+msgstr "Requis"
+
+#: ..\..\..\templates\editbookmark.tpl.php:39
+#: ..\..\..\templates\editprofile.tpl.php:47
+#: ..\..\..\templates\profile.tpl.php:28
+msgid "Description"
+msgstr "Description"
+
+#: ..\..\..\templates\editbookmark.tpl.php:46
+msgid "Comma-separated"
+msgstr "Séparés par des virgules"
+
+#: ..\..\..\templates\editbookmark.tpl.php:49
+#: ..\..\..\templates\importDelicious.tpl.php:15
+#: ..\..\..\templates\importNetscape.tpl.php:16
+msgid "Privacy"
+msgstr "Vision"
+
+#: ..\..\..\templates\editbookmark.tpl.php:52
+#: ..\..\..\templates\importDelicious.tpl.php:18
+#: ..\..\..\templates\importNetscape.tpl.php:19
+msgid "Public"
+msgstr "Publique"
+
+#: ..\..\..\templates\editbookmark.tpl.php:53
+#: ..\..\..\templates\importDelicious.tpl.php:19
+#: ..\..\..\templates\importNetscape.tpl.php:20
+msgid "Shared with Watch List"
+msgstr "Partagé avec liste d'accès"
+
+#: ..\..\..\templates\editbookmark.tpl.php:54
+#: ..\..\..\templates\importDelicious.tpl.php:20
+#: ..\..\..\templates\importNetscape.tpl.php:21
+msgid "Private"
+msgstr "Privée"
+
+#: ..\..\..\templates\editbookmark.tpl.php:66
+msgid "Delete Bookmark"
+msgstr "Supprimer le signet"
+
+#: ..\..\..\templates\editbookmark.tpl.php:93
+msgid "Bookmarklet"
+msgstr "Bookmarklet"
+
+#: ..\..\..\templates\editbookmark.tpl.php:94
+#, php-format
+msgid "Drag one of the following bookmarklets to your browser's bookmarks and click it whenever you want to add the page you are on to %s"
+msgstr "Déplacez l'un des 'bookmarklet' suivants dans les marques-pages de votre navigateur et cliquez dessus chaque fois que vous souhaitez ajouter un signet pour la page courante dans %s "
+
+#: ..\..\..\templates\editbookmark.tpl.php:106
+#, php-format
+msgid "Post to %s"
+msgstr "Ajouter à %s"
+
+#: ..\..\..\templates\editbookmark.tpl.php:107
+#, php-format
+msgid "Post to %s (Pop-up)"
+msgstr "Ajouter à %s (Pop-up)"
+
+#: ..\..\..\templates\editbookmark.tpl.php:111
+#: ..\..\..\templates\importDelicious.tpl.php:26
+#: ..\..\..\templates\importNetscape.tpl.php:27
+msgid "Import"
+msgstr "Importer"
+
+#: ..\..\..\templates\editbookmark.tpl.php:113
+msgid "Import bookmarks from bookmark file"
+msgstr "Importer les signets depuis un fichier"
+
+#: ..\..\..\templates\editbookmark.tpl.php:113
+msgid "Internet Explorer, Mozilla Firefox and Netscape"
+msgstr "Internet Explorer, Mozilla Firefox et Netscape"
+
+#: ..\..\..\templates\editbookmark.tpl.php:114
+msgid "Import bookmarks from del.icio.us"
+msgstr "Importer les signets depuis del.icio.us"
+
+#: ..\..\..\templates\editprofile.tpl.php:10
+msgid "Account Details"
+msgstr "Détail du compte"
+
+#: ..\..\..\templates\editprofile.tpl.php:14
+#: ..\..\..\templates\login.tpl.php:15
+#: ..\..\..\templates\password.tpl.php:10
+#: ..\..\..\templates\profile.tpl.php:7
+#: ..\..\..\templates\register.tpl.php:16
+msgid "Username"
+msgstr "Nom d'utilisateur"
+
+#: ..\..\..\templates\editprofile.tpl.php:19
+msgid "New Password"
+msgstr "Nouveau mot de passe"
+
+#: ..\..\..\templates\editprofile.tpl.php:24
+#, fuzzy
+msgid "Confirm Password"
+msgstr "Confirmer le nouveau mot de passe"
+
+#: ..\..\..\templates\editprofile.tpl.php:29
+#: ..\..\..\templates\register.tpl.php:26
+msgid "E-mail"
+msgstr "E-mail"
+
+#: ..\..\..\templates\editprofile.tpl.php:35
+msgid "Personal Details"
+msgstr "Détails personnels"
+
+#: ..\..\..\templates\editprofile.tpl.php:39
+#: ..\..\..\templates\profile.tpl.php:12
+msgid "Name"
+msgstr "Nom"
+
+#: ..\..\..\templates\editprofile.tpl.php:43
+#: ..\..\..\templates\profile.tpl.php:18
+msgid "Homepage"
+msgstr "Page personnelle"
+
+#: ..\..\..\templates\error.404.tpl.php:5
+#, fuzzy
+msgid "Not Found"
+msgstr "Utilisateur inconnu"
+
+#: ..\..\..\templates\error.404.tpl.php:6
+msgid "The requested URL was not found on this server"
+msgstr "L'URL demandée n'a pas été trouvée sur ce serveur."
+
+#: ..\..\..\templates\error.500.tpl.php:5
+msgid "General server error"
+msgstr "Erreur généralisée du serveur."
+
+#: ..\..\..\templates\error.500.tpl.php:6
+msgid "The requested URL could not be processed"
+msgstr "L'URL demandée n'a pas été trouvée."
+
+#: ..\..\..\templates\importDelicious.tpl.php:33
+msgid "Log in to the <a href=\"http://del.icio.us/api/posts/all\">export page at del.icio.us</a>"
+msgstr "Se connecter à la <a href=\"http://del.icio.us/api/posts/all\">page d'export de del.icio.us</a>"
+
+#: ..\..\..\templates\importDelicious.tpl.php:34
+msgid "Save the resulting <abbr title=\"Extensible Markup Language\">XML</abbr> file to your computer"
+msgstr "Enregistrer le fichier <abbr title=\"Extensible Markup Language\">XML</abbr> résultant sur votre ordinateur"
+
+#: ..\..\..\templates\importDelicious.tpl.php:35
+msgid "Click <kbd>Browse...</kbd> to find this file on your computer. The maximum size the file can be is 1MB"
+msgstr "Cliquez sur <kbd>Parcourir...</kbd> pour trouver le fichier sur votre ordinateur. La taille maximale du fichier ne peut excèder 1Mo"
+
+#: ..\..\..\templates\importDelicious.tpl.php:36
+#: ..\..\..\templates\importNetscape.tpl.php:43
+msgid "Select the default privacy setting for your imported bookmarks"
+msgstr "Selectionnez la vision par défaut à appliquer à vos signets importés"
+
+#: ..\..\..\templates\importDelicious.tpl.php:37
+#: ..\..\..\templates\importNetscape.tpl.php:44
+msgid "Click <kbd>Import</kbd> to start importing the bookmarks; it may take a minute"
+msgstr "Cliquez sur <kbd>Importer</kbd> pour débuter l'import des signets; cette opération peut prendre quelques minutes"
+
+#: ..\..\..\templates\importNetscape.tpl.php:32
+msgid "Instructions"
+msgstr "Instructions"
+
+#: ..\..\..\templates\importNetscape.tpl.php:35
+msgid "Export your bookmarks from your browser to a file"
+msgstr "Exporter vos signets dans un fichier depuis votre navigateur"
+
+#: ..\..\..\templates\importNetscape.tpl.php:37
+msgid "Internet Explorer: <kbd>File &gt; Import and Export... &gt; Export Favorites"
+msgstr "Internet Explorer: <kbd>Ficher &gt; Importer et Exporter... &gt; Exporter les favoris"
+
+#: ..\..\..\templates\importNetscape.tpl.php:38
+msgid "Mozilla Firefox: <kbd>Bookmarks &gt; Manage Bookmarks... &gt; File &gt; Export..."
+msgstr "Mozilla Firefox: <kbd>Marques-pages &gt; Gérer les marques-pages... &gt; Fichier &gt; Exporter..."
+
+#: ..\..\..\templates\importNetscape.tpl.php:39
+msgid "Netscape: <kbd>Bookmarks &gt; Manage Bookmarks... &gt; Tools &gt; Export..."
+msgstr "Netscape: <kbd>Marques-pages &gt; Gérer les marques-pages... &gt; Outils &gt; Exporter..."
+
+#: ..\..\..\templates\importNetscape.tpl.php:42
+msgid "Click <kbd>Browse...</kbd> to find the saved bookmark file on your computer. The maximum size the file can be is 1MB"
+msgstr "Cliquez sur <kbd>Parcourir...</kbd> pour trouver le fichier sur votre ordinateur. La taille maximale du fichier ne peut excèder 1Mo"
+
+#: ..\..\..\templates\login.tpl.php:20
+#: ..\..\..\templates\register.tpl.php:21
+msgid "Password"
+msgstr "Mot de passe"
+
+#: ..\..\..\templates\login.tpl.php:22
+msgid "Don't ask for my password for 2 weeks"
+msgstr "Ne pas me demander le mot de passe pendant 2 semaines"
+
+#: ..\..\..\templates\login.tpl.php:30
+msgid "Forgotten your password?"
+msgstr "Avez-vous oublié votre mot de passe ?"
+
+#: ..\..\..\templates\password.tpl.php:5
+#, php-format
+msgid "If you have forgotten your password, %s can generate a new one. Enter the username and e-mail address of your account into the form below and we will e-mail your new password to you."
+msgstr "Si vous avez oublié votre mot de passe, %s peut en générer un nouveau. Entrez le nom d'utilisateur et l'adresse email de votre compte dans le formulaire ci-dessous et nous vous enverrons un nouveau mot de passe."
+
+#: ..\..\..\templates\password.tpl.php:14
+msgid "<abbr title=\"Electronic mail\">E-mail</abbr>"
+msgstr "<abbr title=\"Adresse électronique\">E-mail</abbr>"
+
+#: ..\..\..\templates\password.tpl.php:19
+#, fuzzy
+msgid "Generate Password"
+msgstr "Nouveau mot de passe"
+
+#: ..\..\..\templates\profile.tpl.php:23
+msgid "Member Since"
+msgstr "Membre depuis"
+
+#: ..\..\..\templates\profile.tpl.php:35
+#: ..\..\..\templates\sidebar.block.watchlist.php:8
+#, fuzzy
+msgid "Watching"
+msgstr "Liste des signets vus"
+
+#: ..\..\..\templates\profile.tpl.php:50
+#, fuzzy
+msgid "Watched By"
+msgstr "Consultés"
+
+#: ..\..\..\templates\register.tpl.php:11
+#, fuzzy, php-format
+msgid "Sign up here to create a free %s account. All the information requested below is required"
+msgstr "Enregistrez-vous ici pour vous créer un compte Scuttle gratuit. Toutes les inforamtions demandées ci-dessous sont nécessaires."
+
+#: ..\..\..\templates\rss.tpl.php:9
+#, fuzzy, php-format
+msgid "Recent bookmarks posted to %s"
+msgstr "Signets ajoutés à Scuttle récement"
+
+#: ..\..\..\templates\rss.tpl.php:17
+#: ..\..\..\templates\rss.tpl.php:19
+msgid "No bookmarks found"
+msgstr "Pas de signets trouvés"
+
+#: ..\..\..\templates\sidebar.block.recent.php:15
+#, fuzzy
+msgid "Recent Tags"
+msgstr "Labels en relation"
+
+#: ..\..\..\templates\sidebar.block.related.php:15
+msgid "Related Tags"
+msgstr "Labels en relation"
+
+#: ..\..\..\templates\sidebar.block.watchstatus.php:10
+msgid "Remove from Watchlist"
+msgstr "Enlever de la liste des consultés"
+
+#: ..\..\..\templates\sidebar.block.watchstatus.php:12
+msgid "Add to Watchlist"
+msgstr "Ajouter à la liste des consultés"
+
+#: ..\..\..\templates\sidebar.block.watchstatus.php:17
+#, fuzzy
+msgid "Actions"
+msgstr "Instructions"
+
+#: ..\..\..\templates\tags.tpl.php:8
+#, fuzzy
+msgid "Alphabet"
+msgstr "Alphabet"
+
+#: ..\..\..\templates\tags.tpl.php:9
+#, fuzzy
+msgid "Popularity"
+msgstr "Labels populaires"
+
+#: ..\..\..\templates\toolbar.inc.php:11
+#, fuzzy
+msgid "Bookmarks"
+msgstr "Signets de %s"
+
+#: ..\..\..\templates\toolbar.inc.php:16
+msgid "Log Out"
+msgstr "Quitter"
+
diff --git a/locales/hi_IN/LC_MESSAGES/messages.mo b/locales/hi_IN/LC_MESSAGES/messages.mo
new file mode 100644
index 0000000..77f7c1e
--- /dev/null
+++ b/locales/hi_IN/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/locales/hi_IN/LC_MESSAGES/messages.po b/locales/hi_IN/LC_MESSAGES/messages.po
new file mode 100644
index 0000000..af6b412
--- /dev/null
+++ b/locales/hi_IN/LC_MESSAGES/messages.po
@@ -0,0 +1,812 @@
+# Scuttle hi-IN Translation
+# Copyright (C) 2005 - 2006 Scuttle project
+# This file is distributed under the same license as the Scuttle package.
+# Debashish Chakrabarty <debashish @ gmail.com>
+# Ravishankar Shrivastava <raviratlami@yahoo.com>
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Scuttle\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2005-04-29 11:17+0200\n"
+"PO-Revision-Date: 2006-04-16 21:56-0800\n"
+"Last-Translator: Marcus Campbell <marcus.campbell@gmail.com>\n"
+"Language-Team: hi-IN Debashish Chakrabarty <debashish @ gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-Language: Hindi\n"
+"X-Poedit-Country: India\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: ..\..\..\about.php:25
+#: ..\..\..\templates\toolbar.inc.php:24
+msgid "About"
+msgstr "के बारे में"
+
+#: ..\..\..\ajaxDelete.php:29
+msgid "You are not allowed to delete this bookmark"
+msgstr "आपको इस पृषà¥à¤ -सà¥à¤®à¥ƒà¤¤à¤¿ को मिटाने की अनà¥à¤®à¤¤à¤¿ नहीं है."
+
+#: ..\..\..\ajaxDelete.php:33
+msgid "Failed to delete bookmark"
+msgstr "पृषà¥à¤ -सà¥à¤®à¥ƒà¤¤à¤¿ मिटाने में असफल"
+
+#: ..\..\..\alltags.php:50
+msgid "All Tags"
+msgstr "सभी टैग"
+
+#: ..\..\..\alltags.php:59
+#: ..\..\..\populartags.php:63
+#: ..\..\..\profile.php:46
+#: ..\..\..\rss.php:55
+#: ..\..\..\search.php:61
+#: ..\..\..\watch.php:35
+#: ..\..\..\watched.php:62
+#, php-format
+msgid "User with username %s not was not found"
+msgstr "%s नाम का कोई भी उपयोकà¥à¤¤à¤¾ नहीं मिला"
+
+#: ..\..\..\bookmarks.php:71
+#, fuzzy, php-format
+msgid "User with username %s was not found"
+msgstr "%s नाम का कोई भी उपयोकà¥à¤¤à¤¾ नहीं मिला"
+
+#: ..\..\..\bookmarks.php:94
+#: ..\..\..\edit.php:44
+msgid "Your bookmark must have a title and an address"
+msgstr "आपकी पृषà¥à¤ -सà¥à¤®à¥ƒà¤¤à¤¿ के लिठà¤à¤• शीरà¥à¤·à¤• तथा à¤à¤• पता होना आवशà¥à¤¯à¤• है"
+
+#: ..\..\..\bookmarks.php:114
+#: ..\..\..\edit.php:58
+msgid "Bookmark saved"
+msgstr "पृषà¥à¤ -सà¥à¤®à¥ƒà¤¤à¤¿ सहेजी गई"
+
+#: ..\..\..\bookmarks.php:122
+#: ..\..\..\import.php:99
+#: ..\..\..\importNetscape.php:74
+msgid "There was an error saving your bookmark. Please try again or contact the administrator."
+msgstr "आपकी पृषà¥à¤ -सà¥à¤®à¥ƒà¤¤à¤¿ को सहेजने के दौरान à¤à¤• तà¥à¤°à¥à¤Ÿà¤¿ हà¥à¤ˆ. कृपया फिर से कोशिश करें या पà¥à¤°à¤¶à¤¾à¤¸à¤• से समà¥à¤ªà¤°à¥à¤• साधें."
+
+#: ..\..\..\bookmarks.php:160
+#: ..\..\..\templates\toolbar.inc.php:13
+msgid "Add a Bookmark"
+msgstr "à¤à¤• पृषà¥à¤ -सà¥à¤®à¥ƒà¤¤à¤¿ जोड़ें"
+
+#: ..\..\..\bookmarks.php:163
+msgid "Add Bookmark"
+msgstr "पृषà¥à¤ -सà¥à¤®à¥ƒà¤¤à¤¿ जोड़ें"
+
+#: ..\..\..\bookmarks.php:166
+msgid "You must be logged in before you can add bookmarks."
+msgstr "पृषà¥à¤ -सà¥à¤®à¥ƒà¤¤à¤¿ जोड़ने से पहले आपका लॉगइन होना आवशà¥à¤¯à¤• है."
+
+#: ..\..\..\bookmarks.php:213
+msgid "My Bookmarks"
+msgstr "मेरी पृषà¥à¤ -सà¥à¤®à¥ƒà¤¤à¤¿à¤¯à¤¾à¤"
+
+#: ..\..\..\edit.php:29
+msgid "Edit Bookmark"
+msgstr "पृषà¥à¤ -सà¥à¤®à¥ƒà¤¤à¤¿ संपादन"
+
+#: ..\..\..\edit.php:34
+#, php-format
+msgid "Bookmark with id %s not was not found"
+msgstr "पहचान चिहà¥à¤¨ %s यà¥à¤•à¥à¤¤ पृषà¥à¤ -सà¥à¤®à¥ƒà¤¤à¤¿ नहीं मिला"
+
+#: ..\..\..\edit.php:39
+msgid "You are not allowed to edit this bookmark"
+msgstr "आप इस पृषà¥à¤ -सà¥à¤®à¥ƒà¤¤à¤¿ को संपादित नही कर सकते"
+
+#: ..\..\..\edit.php:55
+msgid "Error while saving your bookmark"
+msgstr "पृषà¥à¤ -सà¥à¤®à¥ƒà¤¤à¤¿ सहेजने के दौरान तà¥à¤°à¥à¤Ÿà¤¿ हà¥à¤ˆ"
+
+#: ..\..\..\edit.php:78
+msgid "Failed to delete the bookmark"
+msgstr "पृषà¥à¤ -सà¥à¤®à¥ƒà¤¤à¤¿ मिटाने में असफल"
+
+#: ..\..\..\edit.php:88
+#: ..\..\..\templates\editprofile.tpl.php:52
+msgid "Save Changes"
+msgstr "परिवरà¥à¤¤à¤¨ सहेजें"
+
+#: ..\..\..\functions.inc.php:92
+msgid "message_die() was called multiple times."
+msgstr "message_die() को कई मरà¥à¤¤à¤¬à¤¾ काल किया गया."
+
+#: ..\..\..\functions.inc.php:104
+msgid "SQL Error"
+msgstr "à¤à¤¸à¤•à¥à¤¯à¥‚à¤à¤² तà¥à¤°à¥à¤Ÿà¤¿"
+
+#: ..\..\..\functions.inc.php:110
+msgid "Line"
+msgstr "पंकà¥à¤¤à¤¿"
+
+#: ..\..\..\functions.inc.php:110
+#: ..\..\..\templates\importDelicious.tpl.php:8
+#: ..\..\..\templates\importNetscape.tpl.php:9
+msgid "File"
+msgstr "फ़ाइल"
+
+#: ..\..\..\functions.inc.php:116
+msgid "Information"
+msgstr "जानकारी"
+
+#: ..\..\..\functions.inc.php:121
+msgid "Critical Information"
+msgstr "जरूरी जानकारी"
+
+#: ..\..\..\functions.inc.php:126
+msgid "An error occured"
+msgstr "à¤à¤• तà¥à¤°à¥à¤Ÿà¤¿ हà¥à¤ˆ"
+
+#: ..\..\..\functions.inc.php:129
+msgid "General Error"
+msgstr "सामानà¥à¤¯ तà¥à¤°à¥à¤Ÿà¤¿"
+
+#: ..\..\..\functions.inc.php:137
+msgid "An critical error occured"
+msgstr "à¤à¤• गंभीर तà¥à¤°à¥à¤Ÿà¤¿ हà¥à¤ˆ"
+
+#: ..\..\..\functions.inc.php:140
+msgid "Critical Error"
+msgstr "गंभीर तà¥à¤°à¥à¤Ÿà¤¿"
+
+#: ..\..\..\functions.inc.php:149
+msgid "DEBUG MODE"
+msgstr "डिबग मोड"
+
+#: ..\..\..\history.php:65
+msgid "History"
+msgstr "इतिहास"
+
+#: ..\..\..\history.php:66
+#, php-format
+msgid "History for %s"
+msgstr "%s का इतिहास"
+
+#: ..\..\..\history.php:81
+msgid "Address was not found"
+msgstr "पता नहीं मिला"
+
+#: ..\..\..\import.php:41
+msgid "Could not open XML input"
+msgstr "à¤à¤•à¥à¤¸à¤à¤®à¤à¤² इनपà¥à¤Ÿ खोल नहीं सकता"
+
+#: ..\..\..\import.php:45
+#, php-format
+msgid "XML error: %s at line %d"
+msgstr "à¤à¤•à¥à¤¸à¤à¤®à¤à¤² तà¥à¤°à¥à¤Ÿà¤¿: %s में पंकà¥à¤¤à¤¿ %d पर"
+
+#: ..\..\..\import.php:54
+msgid "Import Bookmarks from del.icio.us"
+msgstr "del.icio.us से पृषà¥à¤ -सà¥à¤®à¥ƒà¤¤à¤¿ आयात करें"
+
+#: ..\..\..\import.php:86
+#: ..\..\..\importNetscape.php:64
+msgid "You have already submitted this bookmark."
+msgstr "आप इस पृषà¥à¤ -सà¥à¤®à¥ƒà¤¤à¤¿ को पहले ही पेश कर चà¥à¤•à¥‡ हैं"
+
+#: ..\..\..\import.php:97
+#: ..\..\..\importNetscape.php:72
+msgid "Bookmark imported."
+msgstr "पृषà¥à¤ -सà¥à¤®à¥ƒà¤¤à¤¿ आयातित."
+
+#: ..\..\..\importNetscape.php:81
+msgid "Import Bookmarks from Browser File"
+msgstr "बà¥à¤°à¤¾à¤‰à¤œà¤¼à¤° फ़ाइल से पृषà¥à¤ -सà¥à¤®à¥ƒà¤¤à¤¿ को आयात करें"
+
+#: ..\..\..\index.php:32
+msgid "You have now logged out"
+msgstr "अब आप लॉग आउट हैं"
+
+#: ..\..\..\index.php:39
+#, php-format
+msgid "%s: Recent bookmarks"
+msgstr "%s: हालिया पृषà¥à¤ -सà¥à¤®à¥ƒà¤¤à¤¿"
+
+#: ..\..\..\index.php:72
+msgid "Store, share and tag your favourite links"
+msgstr "अपनी मनपसंद पृषà¥à¤ -सà¥à¤®à¥ƒà¤¤à¤¿à¤¯à¤¾à¤ सहेजें, साà¤à¤¾ करें और टैग करें"
+
+#: ..\..\..\index.php:73
+msgid "Recent Bookmarks"
+msgstr "हालिया पृषà¥à¤ -सà¥à¤®à¥ƒà¤¤à¤¿à¤¯à¤¾à¤"
+
+#: ..\..\..\jsScuttle.php:22
+msgid "Are you sure?"
+msgstr "पकà¥à¤•à¥€ बात ना?"
+
+#: ..\..\..\jsScuttle.php:22
+msgid "Yes"
+msgstr "हाà¤"
+
+#: ..\..\..\jsScuttle.php:22
+msgid "No"
+msgstr "नहीं"
+
+#: ..\..\..\jsScuttle.php:68
+msgid "Available"
+msgstr "उपलबà¥à¤§"
+
+#: ..\..\..\jsScuttle.php:71
+msgid "Not Available"
+msgstr "उपलबà¥à¤§ नहीं"
+
+#: ..\..\..\login.php:38
+msgid "The details you have entered are incorrect. Please try again."
+msgstr "आपने जो विवरण भरे हैं वे गलत हैं. कृपया पà¥à¤¨à¤ƒ पà¥à¤°à¤¯à¤¾à¤¸ करें."
+
+#: ..\..\..\login.php:48
+#: ..\..\..\templates\login.tpl.php:26
+#: ..\..\..\templates\toolbar.inc.php:28
+msgid "Log In"
+msgstr "लॉग इन"
+
+#: ..\..\..\password.php:31
+msgid "You must enter your username."
+msgstr "आपका उपयोकà¥à¤¤à¤¾ नाम पà¥à¤°à¤µà¤¿à¤·à¥à¤Ÿ करना ज़रूरी है."
+
+#: ..\..\..\password.php:35
+msgid "You must enter your <abbr title=\"electronic mail\">e-mail</abbr> address."
+msgstr "<abbr title=\"electronic mail\">ईमेल</abbr> पता भरना आवशà¥à¤¯à¤• है."
+
+#: ..\..\..\password.php:42
+msgid "No matches found for that username."
+msgstr "इस से मेल खाता कोई उपयोकà¥à¤¤à¤¾ नाम नहीं मिला."
+
+#: ..\..\..\password.php:45
+msgid "No matches found for that combination of username and <abbr title=\"electronic mail\">e-mail</abbr> address."
+msgstr "इस उपयोकà¥à¤¤à¤¾ तथा <abbr title=\"electronic mail\">ईमेल</abbr> पते से मेल खाता कोई जोड़ नहीं मिला."
+
+#: ..\..\..\password.php:53
+msgid "There was an error while generating your new password. Please try again."
+msgstr "आपका नया कूटशबà¥à¤¦ बनाने समय कोई तà¥à¤°à¥à¤Ÿà¤¿ हà¥à¤ˆ है। कृपया पà¥à¤¨à¤ƒ पà¥à¤°à¤¯à¤¾à¤¸ करें।"
+
+#: ..\..\..\password.php:57
+msgid "Your new password is:"
+msgstr "आपका नया कूटशबà¥à¤¦ हैः"
+
+#: ..\..\..\password.php:57
+msgid "To keep your bookmarks secure, you should change this password in your profile the next time you log in."
+msgstr "अपनी पृषà¥à¤ -सà¥à¤®à¥ƒà¤¤à¤¿à¤¯à¤¾à¤ सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ रखने के लिये, जब आप अगली बार लॉगिन करें तो अपने पà¥à¤°à¥‹à¤«à¤¾à¤ˆà¤² में जाकर अपना कूटशबà¥à¤¦ अवशà¥à¤¯ बदल लें."
+
+#: ..\..\..\password.php:60
+#, php-format
+msgid "%s Account Information"
+msgstr "%s खाते की जानकारी"
+
+#: ..\..\..\password.php:62
+#, php-format
+msgid "New password generated and sent to %s"
+msgstr "नया कूटशबà¥à¤¦ बना कर %s को भेज दिया गया है."
+
+#: ..\..\..\password.php:69
+msgid "Forgotten Password"
+msgstr "भूला कूटशबà¥à¤¦"
+
+#: ..\..\..\populartags.php:54
+#: ..\..\..\templates\dynamictags.inc.php:101
+#: ..\..\..\templates\sidebar.block.common.php:9
+#: ..\..\..\templates\sidebar.block.popular.php:15
+#: ..\..\..\templates\sidebar.block.recent.php:25
+msgid "Popular Tags"
+msgstr "लोकपà¥à¤°à¤¿à¤¯ टैग"
+
+#: ..\..\..\profile.php:54
+#: ..\..\..\watched.php:114
+msgid "Username was not specified"
+msgstr "उपयोकà¥à¤¤à¤¾ नाम निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ नहीं है"
+
+#: ..\..\..\profile.php:60
+msgid "My Profile"
+msgstr "मेरा पà¥à¤°à¥‹à¤«à¤¼à¤¾à¤‡à¤²"
+
+#: ..\..\..\profile.php:62
+#: ..\..\..\templates\sidebar.block.profile.php:12
+msgid "Profile"
+msgstr "पà¥à¤°à¥‹à¤«à¤¼à¤¾à¤‡à¤²"
+
+#: ..\..\..\profile.php:80
+msgid "Password and confirmation do not match."
+msgstr "कूटशबà¥à¤¦ तथा उसका पà¥à¤·à¥à¤Ÿà¤¿à¤•à¤°à¤£ मेल नहीं खाते"
+
+#: ..\..\..\profile.php:84
+msgid "Password must be at least 6 characters long."
+msgstr "कूटशबà¥à¤¦ को कम से कम 6 अकà¥à¤·à¤° लंबा होना चाहिà¤"
+
+#: ..\..\..\profile.php:88
+msgid "E-mail address is not valid."
+msgstr "ईमेल पता वैध नहीं है."
+
+#: ..\..\..\profile.php:92
+msgid "An error occurred while saving your changes."
+msgstr "आपके दà¥à¤µà¤¾à¤°à¤¾ किठगठपरिवरà¥à¤¤à¤¨à¥‹à¤‚ को सहेजने के दौरान तà¥à¤°à¥à¤Ÿà¤¿ हà¥à¤ˆ."
+
+#: ..\..\..\profile.php:94
+msgid "Changes saved."
+msgstr "परिवरà¥à¤¤à¤¨à¥‹à¤‚ को सहेजा गया."
+
+#: ..\..\..\register.php:33
+msgid "You <em>must</em> enter a username, password and e-mail address."
+msgstr "आपको उपयोकà¥à¤¤à¤¾ नाम, कूटशबà¥à¤¦ तथा <abbr title=\"electronic mail\">ईमेल</abbr> पता भरना <em>आवशà¥à¤¯à¤•</em> है"
+
+#: ..\..\..\register.php:37
+msgid "This username already exists, please make another choice."
+msgstr "यह उपयोकà¥à¤¤à¤¾ नाम पहले ही मौजूद है, कृपया कोई दूसरा चà¥à¤¨à¥‡à¤‚."
+
+#: ..\..\..\register.php:41
+msgid "E-mail address is not valid. Please try again."
+msgstr "<abbr title=\"electronic mail\">ईमेल</abbr> पता वैध नहीं है."
+
+#: ..\..\..\register.php:50
+msgid "You have successfully registered. Enjoy!"
+msgstr "आप सफलता पूरà¥à¤µà¤• पंजीकृत हो गठहैं. बधाई!"
+
+#: ..\..\..\register.php:52
+msgid "Registration failed. Please try again."
+msgstr "पंजीकरण असफल. कृपया फिर से कोशिश करें."
+
+#: ..\..\..\register.php:57
+#: ..\..\..\templates\register.tpl.php:32
+#: ..\..\..\templates\toolbar.inc.php:27
+msgid "Register"
+msgstr "पंजीकरण"
+
+#: ..\..\..\search.inc.php:29
+#: ..\..\..\search.inc.php:57
+msgid "Search"
+msgstr "ढूंढें"
+
+#: ..\..\..\search.inc.php:35
+msgid "this user's bookmarks"
+msgstr "इस उपयोकà¥à¤¤à¤¾ की पृषà¥à¤ -सà¥à¤®à¥ƒà¤¤à¤¿à¤¯à¤¾à¤"
+
+#: ..\..\..\search.inc.php:40
+msgid "my bookmarks"
+msgstr "मेरी पृषà¥à¤ -सà¥à¤®à¥ƒà¤¤à¤¿à¤¯à¤¾à¤"
+
+#: ..\..\..\search.inc.php:41
+msgid "my watchlist"
+msgstr "मेरी निगरानी सूची"
+
+#: ..\..\..\search.inc.php:45
+msgid "all bookmarks"
+msgstr "सभी पृषà¥à¤ -सà¥à¤®à¥ƒà¤¤à¤¿à¤¯à¤¾à¤"
+
+#: ..\..\..\search.inc.php:48
+msgid "for"
+msgstr "के लिà¤"
+
+#: ..\..\..\search.php:91
+#: ..\..\..\search.php:128
+msgid "Search Bookmarks"
+msgstr "पृषà¥à¤ -सà¥à¤®à¥ƒà¤¤à¤¿à¤¯à¤¾à¤ ढूंढें"
+
+#: ..\..\..\search.php:97
+msgid "Search Results"
+msgstr "खोज परिणाम"
+
+#: ..\..\..\tags.php:38
+#: ..\..\..\templates\editbookmark.tpl.php:44
+#: ..\..\..\templates\sidebar.block.profile.php:13
+msgid "Tags"
+msgstr "टैग"
+
+#: ..\..\..\watch.php:79
+#, php-format
+msgid "%s Bookmarks"
+msgstr "%s पृषà¥à¤ -सà¥à¤®à¥ƒà¤¤à¤¿à¤¯à¤¾à¤"
+
+#: ..\..\..\watch.php:84
+msgid "User removed from your watchlist"
+msgstr "आपकी निगरानी सूची से उपयोकà¥à¤¤à¤¾ को मिटाया गया"
+
+#: ..\..\..\watch.php:86
+msgid "User added to your watchlist"
+msgstr "उपयोकà¥à¤¤à¤¾ को आपकी निगरानी सूची में जोड़ा"
+
+#: ..\..\..\watched.php:105
+msgid "My Watchlist"
+msgstr "मेरी निगरानी सूची"
+
+#: ..\..\..\watched.php:107
+#: ..\..\..\templates\sidebar.block.profile.php:14
+#: ..\..\..\templates\toolbar.inc.php:12
+#, fuzzy
+msgid "Watchlist"
+msgstr "निगरानी सूची"
+
+#: ..\..\..\templates\about.tpl.php:6
+msgid "<strong>Store</strong> all your favourite links in one place, accessible from anywhere."
+msgstr "अपनी पसंद की कड़ियों को कहीं से भी पहà¥à¤à¤š योगà¥à¤¯ बनाने के लिठà¤à¤• ही सà¥à¤¥à¤² पर<strong>संचित</strong>करें."
+
+#: ..\..\..\templates\about.tpl.php:7
+msgid "<strong>Share</strong> your bookmarks with everyone, with friends on your watchlist or just keep them private."
+msgstr "अपने पृषà¥à¤ -सà¥à¤®à¥ƒà¤¤à¤¿ कड़ियों को सबके साथ, अपने निगरानी सूची के मितà¥à¤°à¥‹à¤‚ के साथ <strong>साà¤à¤¾</strong> करें या निजी इसà¥à¤¤à¥‡à¤®à¤¾à¤² करें"
+
+#: ..\..\..\templates\about.tpl.php:8
+msgid "<strong>Tag</strong> your bookmarks with as many labels as you want, instead of wrestling with folders."
+msgstr "अपनी पृषà¥à¤ -सà¥à¤®à¥ƒà¤¤à¤¿ कड़ियों को किसी फोलà¥à¤¡à¤° में ठूंसने के बजाठचाहे जितने लेबलों के साथ<strong>टैग</strong> कर सकते हैं."
+
+#: ..\..\..\templates\about.tpl.php:9
+#, php-format
+msgid "<strong><a href=\"register.php\">Register now</a></strong> to start using %s!"
+msgstr "<strong><a href=\"register.php\">तà¥à¤°à¤‚त पंजीकृत हों</a></strong> %s का इसà¥à¤¤à¥‡à¤®à¤¾à¤² करने के लिà¤!"
+
+#: ..\..\..\templates\about.tpl.php:12
+msgid "Geek Stuff"
+msgstr "विदà¥à¤µà¤¾à¤¨à¥‹à¤‚ का खजाना"
+
+#: ..\..\..\templates\about.tpl.php:14
+#, php-format
+msgid "%s is based on <a href=\"http://sourceforge.net/projects/scuttle/\">an open-source project</a> licensed under the <a href=\"http://www.gnu.org/copyleft/gpl.html\"><acronym title=\"GNU's Not Unix\">GNU</acronym> General Public License</a>. This means you can host it on your own web server for free, whether it is on the Internet, a private network or just your own computer."
+msgstr "%s à¤à¤• <a href=\"http://sourceforge.net/projects/scuttle/\">मà¥à¤•à¥à¤¤ सà¥à¤°à¥‹à¤¤ परियोजना</a> पर आधारित है तथा इसे<a href=\"http://www.gnu.org/copyleft/gpl.html\"><acronym title=\"GNU's Not Unix\">गà¥à¤¨à¥‚</acronym> जनरल पबà¥à¤²à¤¿à¤• लाइसेंस</a> के तहत जारी किया गया है. इसका अरà¥à¤¥ है कि आप इसे अपने सà¥à¤µà¤¯à¤‚ के वेब सरà¥à¤µà¤° पर चाहे इंटरनेट पर हो या निजी नेटवरà¥à¤• पर या आपके वà¥à¤¯à¤•à¥à¤¤à¤¿à¤—त कमà¥à¤ªà¥à¤¯à¥‚टर पर, होसà¥à¤Ÿ कर सकते हैं."
+
+#: ..\..\..\templates\about.tpl.php:15
+#, php-format
+msgid "%1$s supports most of the <a href=\"http://del.icio.us/doc/api\">del.icio.us <abbr title=\"Application Programming Interface\">API</abbr></a>. Almost all of the neat tools made for that system can be modified to work with %1$s instead. If you find a tool that won't let you change the API address, ask the creator to add this setting. You never know, they might just do it."
+msgstr "%1$s में पà¥à¤°à¤¾à¤¯à¤ƒ सभी <a href=\"http://del.icio.us/doc/api\">del.icio.us <abbr title=\"Application Programming Interface\">à¤à¤ªà¥€à¤†à¤ˆ</abbr></a> का समरà¥à¤¥à¤¨ मिलता है. उस तंतà¥à¤° के लिठबनाठगठपà¥à¤°à¤¾à¤¯à¤ƒ सभी औजारों को %1$s के लिठकारà¥à¤¯ करने लायक परिवरà¥à¤§à¤¿à¤¤ किया जा सकता है. यदि आपको कोई औजार à¤à¤¸à¤¾ मिलता है जो आपको à¤à¤ªà¥€à¤†à¤ˆ पता बदलने नहीं देता है तो उसके सृजक को इस विनà¥à¤¯à¤¾à¤¸ को जोड़ने के लिठकहें. कौन जाने वे à¤à¤¸à¤¾ भी कर लें."
+
+#: ..\..\..\templates\bookmarks.tpl.php:17
+#: ..\..\..\templates\tags.tpl.php:7
+msgid "Sort by:"
+msgstr "इस आधार पर छांटें:"
+
+#: ..\..\..\templates\bookmarks.tpl.php:18
+msgid "Date"
+msgstr "तारीख़"
+
+#: ..\..\..\templates\bookmarks.tpl.php:19
+#: ..\..\..\templates\editbookmark.tpl.php:34
+msgid "Title"
+msgstr "शीरà¥à¤·à¤•"
+
+#: ..\..\..\templates\bookmarks.tpl.php:23
+msgid "URL"
+msgstr "यूआरà¤à¤²"
+
+#: ..\..\..\templates\bookmarks.tpl.php:60
+msgid "Edit"
+msgstr "संपादन"
+
+#: ..\..\..\templates\bookmarks.tpl.php:60
+msgid "Delete"
+msgstr "मिटाà¤à¤"
+
+#: ..\..\..\templates\bookmarks.tpl.php:66
+msgid "by"
+msgstr "दà¥à¤µà¤¾à¤°à¤¾"
+
+#: ..\..\..\templates\bookmarks.tpl.php:78
+#, php-format
+msgid " and %s1 other%s"
+msgstr " तथा %s1 अनà¥à¤¯%s"
+
+#: ..\..\..\templates\bookmarks.tpl.php:81
+#, php-format
+msgid " and %2$s%1$s others%3$s"
+msgstr " तथा %2$s%1$s अनà¥à¤¯%3$s"
+
+#: ..\..\..\templates\bookmarks.tpl.php:90
+msgid "Copy"
+msgstr "नक़ल करें"
+
+#: ..\..\..\templates\bookmarks.tpl.php:136
+#: ..\..\..\templates\bookmarks.tpl.php:142
+msgid "First"
+msgstr "पà¥à¤°à¤¥à¤®"
+
+#: ..\..\..\templates\bookmarks.tpl.php:137
+#: ..\..\..\templates\bookmarks.tpl.php:143
+msgid "Previous"
+msgstr "पिछला"
+
+#: ..\..\..\templates\bookmarks.tpl.php:150
+#: ..\..\..\templates\bookmarks.tpl.php:153
+msgid "Next"
+msgstr "अगला"
+
+#: ..\..\..\templates\bookmarks.tpl.php:151
+#: ..\..\..\templates\bookmarks.tpl.php:154
+msgid "Last"
+msgstr "अंतिम"
+
+#: ..\..\..\templates\bookmarks.tpl.php:156
+#, php-format
+msgid "Page %d of %d"
+msgstr "%d में से पृषà¥à¤  %d"
+
+#: ..\..\..\templates\bookmarks.tpl.php:160
+msgid "No bookmarks available"
+msgstr "कोई पृषà¥à¤ -सà¥à¤®à¥ƒà¤¤à¤¿ उपलबà¥à¤§ नहीं"
+
+#: ..\..\..\templates\dynamictags.inc.php:108
+#: ..\..\..\templates\sidebar.block.common.php:15
+#: ..\..\..\templates\sidebar.block.popular.php:21
+#: ..\..\..\templates\sidebar.block.recent.php:20
+#: ..\..\..\templates\tags.tpl.php:16
+msgid "bookmark"
+msgid_plural "bookmarks"
+msgstr[0] "पृषà¥à¤ -सà¥à¤®à¥ƒà¤¤à¤¿"
+msgstr[1] "पृषà¥à¤ -सà¥à¤®à¥ƒà¤¤à¤¿à¤¯à¤¾à¤"
+
+#: ..\..\..\templates\editbookmark.tpl.php:29
+msgid "Address"
+msgstr "पता"
+
+#: ..\..\..\templates\editbookmark.tpl.php:31
+#: ..\..\..\templates\editbookmark.tpl.php:36
+#: ..\..\..\templates\editprofile.tpl.php:31
+msgid "Required"
+msgstr "आवशà¥à¤¯à¤•"
+
+#: ..\..\..\templates\editbookmark.tpl.php:39
+#: ..\..\..\templates\editprofile.tpl.php:47
+#: ..\..\..\templates\profile.tpl.php:28
+msgid "Description"
+msgstr "वरà¥à¤£à¤¨"
+
+#: ..\..\..\templates\editbookmark.tpl.php:46
+msgid "Comma-separated"
+msgstr "अलà¥à¤ªà¤µà¤¿à¤°à¤¾à¤® से अलग की गई"
+
+#: ..\..\..\templates\editbookmark.tpl.php:49
+#: ..\..\..\templates\importDelicious.tpl.php:15
+#: ..\..\..\templates\importNetscape.tpl.php:16
+msgid "Privacy"
+msgstr "गोपनीयता"
+
+#: ..\..\..\templates\editbookmark.tpl.php:52
+#: ..\..\..\templates\importDelicious.tpl.php:18
+#: ..\..\..\templates\importNetscape.tpl.php:19
+msgid "Public"
+msgstr "सारà¥à¤µà¤œà¤¨à¤¿à¤•"
+
+#: ..\..\..\templates\editbookmark.tpl.php:53
+#: ..\..\..\templates\importDelicious.tpl.php:19
+#: ..\..\..\templates\importNetscape.tpl.php:20
+msgid "Shared with Watch List"
+msgstr "निगरानी सूची के साथ साà¤à¤¾"
+
+#: ..\..\..\templates\editbookmark.tpl.php:54
+#: ..\..\..\templates\importDelicious.tpl.php:20
+#: ..\..\..\templates\importNetscape.tpl.php:21
+msgid "Private"
+msgstr "निजी"
+
+#: ..\..\..\templates\editbookmark.tpl.php:66
+msgid "Delete Bookmark"
+msgstr "पृषà¥à¤ -सà¥à¤®à¥ƒà¤¤à¤¿ मिटाà¤à¤"
+
+#: ..\..\..\templates\editbookmark.tpl.php:93
+msgid "Bookmarklet"
+msgstr "पृषà¥à¤ -सà¥à¤®à¥ƒà¤¤à¤¿ चिहà¥à¤¨à¤•"
+
+#: ..\..\..\templates\editbookmark.tpl.php:94
+#, php-format
+msgid "Drag one of the following bookmarklets to your browser's bookmarks and click it whenever you want to add the page you are on to %s"
+msgstr "निमà¥à¤¨ पृषà¥à¤ -सà¥à¤®à¥ƒà¤¤à¤¿ चिहà¥à¤¨à¤•à¥‹à¤‚ में से किसी à¤à¤• को अपने बà¥à¤°à¤¾à¤‰à¤œà¤¼à¤° के पृषà¥à¤ -सà¥à¤®à¥ƒà¤¤à¤¿ में खींच लाà¤à¤ व जब भी आप %s पर हों व कोई पृषà¥à¤  जोड़ना चाहेठतो उस पर कà¥à¤²à¤¿à¤• करें"
+
+#: ..\..\..\templates\editbookmark.tpl.php:106
+#, php-format
+msgid "Post to %s"
+msgstr "%s को पोसà¥à¤Ÿ करें"
+
+#: ..\..\..\templates\editbookmark.tpl.php:107
+#, php-format
+msgid "Post to %s (Pop-up)"
+msgstr "%s को पोसà¥à¤Ÿ करें (पॉप-अप)"
+
+#: ..\..\..\templates\editbookmark.tpl.php:111
+#: ..\..\..\templates\importDelicious.tpl.php:26
+#: ..\..\..\templates\importNetscape.tpl.php:27
+msgid "Import"
+msgstr "आयात"
+
+#: ..\..\..\templates\editbookmark.tpl.php:113
+msgid "Import bookmarks from bookmark file"
+msgstr "पृषà¥à¤ -सà¥à¤®à¥ƒà¤¤à¤¿ को पृषà¥à¤ -सà¥à¤®à¥ƒà¤¤à¤¿ फ़ाइल से आयात करें"
+
+#: ..\..\..\templates\editbookmark.tpl.php:113
+msgid "Internet Explorer, Mozilla Firefox and Netscape"
+msgstr "इंटरनेट à¤à¤•à¥à¤¸à¤ªà¥à¤²à¥‹à¤°à¤°, मॉज़िलà¥à¤²à¤¾ फ़ॉयरफ़ॉकà¥à¤¸ तथा नेटसà¥à¤•à¥‡à¤ª"
+
+#: ..\..\..\templates\editbookmark.tpl.php:114
+msgid "Import bookmarks from del.icio.us"
+msgstr "del.icio.us से पृषà¥à¤ -सà¥à¤®à¥ƒà¤¤à¤¿ आयात करें"
+
+#: ..\..\..\templates\editprofile.tpl.php:10
+msgid "Account Details"
+msgstr "खाते की जानकारी"
+
+#: ..\..\..\templates\editprofile.tpl.php:14
+#: ..\..\..\templates\login.tpl.php:15
+#: ..\..\..\templates\password.tpl.php:10
+#: ..\..\..\templates\profile.tpl.php:7
+#: ..\..\..\templates\register.tpl.php:16
+msgid "Username"
+msgstr "उपयोकà¥à¤¤à¤¾ नाम"
+
+#: ..\..\..\templates\editprofile.tpl.php:19
+msgid "New Password"
+msgstr "नया कूटशबà¥à¤¦"
+
+#: ..\..\..\templates\editprofile.tpl.php:24
+#, fuzzy
+msgid "Confirm Password"
+msgstr "नया कूटशबà¥à¤¦ सतà¥à¤¯à¤¾à¤ªà¤¿à¤¤ करें"
+
+#: ..\..\..\templates\editprofile.tpl.php:29
+#: ..\..\..\templates\register.tpl.php:26
+msgid "E-mail"
+msgstr "ईमेल"
+
+#: ..\..\..\templates\editprofile.tpl.php:35
+msgid "Personal Details"
+msgstr "वà¥à¤¯à¤•à¥à¤¤à¤¿à¤—त जानकारी"
+
+#: ..\..\..\templates\editprofile.tpl.php:39
+#: ..\..\..\templates\profile.tpl.php:12
+msgid "Name"
+msgstr "नाम"
+
+#: ..\..\..\templates\editprofile.tpl.php:43
+#: ..\..\..\templates\profile.tpl.php:18
+msgid "Homepage"
+msgstr "गृहपृषà¥à¤ "
+
+#: ..\..\..\templates\error.404.tpl.php:5
+msgid "Not Found"
+msgstr "नहीं मिला"
+
+#: ..\..\..\templates\error.404.tpl.php:6
+msgid "The requested URL was not found on this server"
+msgstr "इस सरà¥à¤µà¤° पर निवेदित यूआरà¤à¤² नहीं मिला"
+
+#: ..\..\..\templates\error.500.tpl.php:5
+msgid "General server error"
+msgstr "सामानà¥à¤¯ सरà¥à¤µà¤° तà¥à¤°à¥à¤Ÿà¤¿"
+
+#: ..\..\..\templates\error.500.tpl.php:6
+msgid "The requested URL could not be processed"
+msgstr "निवेदित यूआरà¤à¤² को पà¥à¤°à¥‹à¤¸à¥‡à¤¸ नहीं किया जा सका"
+
+#: ..\..\..\templates\importDelicious.tpl.php:33
+msgid "Log in to the <a href=\"http://del.icio.us/api/posts/all\">export page at del.icio.us</a>"
+msgstr "<a href=\"http://del.icio.us/api/posts/all\">del.icio.us के निरà¥à¤¯à¤¾à¤¤ पृषà¥à¤  पर</a> लॉगइन करें"
+
+#: ..\..\..\templates\importDelicious.tpl.php:34
+msgid "Save the resulting <abbr title=\"Extensible Markup Language\">XML</abbr> file to your computer"
+msgstr "परिणाम <abbr title=\"Extensible Markup Language\">à¤à¤•à¥à¤¸à¤à¤®à¤à¤²</abbr> को अपने कमà¥à¤ªà¥à¤¯à¥‚टर पर सहेजें"
+
+#: ..\..\..\templates\importDelicious.tpl.php:35
+msgid "Click <kbd>Browse...</kbd> to find this file on your computer. The maximum size the file can be is 1MB"
+msgstr "इस फ़ाइल को अपने कमà¥à¤ªà¥à¤¯à¥‚टर पर ढूंढने के लिठ<kbd>बà¥à¤°à¤¾à¤‰à¤œà¤¼...</kbd> पर कà¥à¤²à¤¿à¤• करें. फ़ाइल का अधिकतम आकार 1 मे.बा. तक हो सकता है"
+
+#: ..\..\..\templates\importDelicious.tpl.php:36
+#: ..\..\..\templates\importNetscape.tpl.php:43
+msgid "Select the default privacy setting for your imported bookmarks"
+msgstr "आपके आयातित पृषà¥à¤ -सà¥à¤®à¥ƒà¤¤à¤¿ के डिफ़ॉलà¥à¤Ÿ गोपनीयता विनà¥à¤¯à¤¾à¤¸ चà¥à¤¨à¥‡à¤‚"
+
+#: ..\..\..\templates\importDelicious.tpl.php:37
+#: ..\..\..\templates\importNetscape.tpl.php:44
+msgid "Click <kbd>Import</kbd> to start importing the bookmarks; it may take a minute"
+msgstr "पृषà¥à¤ -सà¥à¤®à¥ƒà¤¤à¤¿ आयात चालू करने के लिठ<kbd>आयात</kbd> पर कà¥à¤²à¤¿à¤• करें, इसमें कà¥à¤› समय लग सकता है"
+
+#: ..\..\..\templates\importNetscape.tpl.php:32
+msgid "Instructions"
+msgstr "निरà¥à¤¦à¥‡à¤¶"
+
+#: ..\..\..\templates\importNetscape.tpl.php:35
+msgid "Export your bookmarks from your browser to a file"
+msgstr "अपने बà¥à¤°à¤¾à¤‰à¤œà¤¼à¤° से अपने पृषà¥à¤ -सà¥à¤®à¥ƒà¤¤à¤¿ को à¤à¤• फ़ाइल में निरà¥à¤¯à¤¾à¤¤ करें"
+
+#: ..\..\..\templates\importNetscape.tpl.php:37
+msgid "Internet Explorer: <kbd>File &gt; Import and Export... &gt; Export Favorites"
+msgstr "इंटरनेट à¤à¤•à¥à¤¸à¤ªà¥à¤²à¥‹à¤°à¤°: <kbd>फ़ाइल &gt; आयात व निरà¥à¤¯à¤¾à¤¤... &gt; पृषà¥à¤ -सà¥à¤®à¥ƒà¤¤à¤¿à¤¯à¤¾à¤ निरà¥à¤¯à¤¾à¤¤ करें"
+
+#: ..\..\..\templates\importNetscape.tpl.php:38
+msgid "Mozilla Firefox: <kbd>Bookmarks &gt; Manage Bookmarks... &gt; File &gt; Export..."
+msgstr "मॉज़िलà¥à¤²à¤¾ फ़ॉयरफ़ॉकà¥à¤¸: <kbd>पृषà¥à¤ -सà¥à¤®à¥ƒà¤¤à¤¿à¤¯à¤¾à¤ &gt; पृषà¥à¤ -सà¥à¤®à¥ƒà¤¤à¤¿ पà¥à¤°à¤¬à¤‚धन... &gt; फ़ाइल &gt; निरà¥à¤¯à¤¾à¤¤..."
+
+#: ..\..\..\templates\importNetscape.tpl.php:39
+msgid "Netscape: <kbd>Bookmarks &gt; Manage Bookmarks... &gt; Tools &gt; Export..."
+msgstr "नेटसà¥à¤•à¥‡à¤ª: <kbd>पृषà¥à¤ -सà¥à¤®à¥ƒà¤¤à¤¿à¤¯à¤¾à¤ &gt; पृषà¥à¤ -सà¥à¤®à¥ƒà¤¤à¤¿ पà¥à¤°à¤¬à¤‚धन... &gt; औजार &gt; निरà¥à¤¯à¤¾à¤¤..."
+
+#: ..\..\..\templates\importNetscape.tpl.php:42
+msgid "Click <kbd>Browse...</kbd> to find the saved bookmark file on your computer. The maximum size the file can be is 1MB"
+msgstr "अपने कमà¥à¤ªà¥à¤¯à¥‚टर में सहेजे गठपृषà¥à¤ -सà¥à¤®à¥ƒà¤¤à¤¿ फ़ाइलों को ढूंढने के लिठ<kbd>बà¥à¤°à¤¾à¤‰à¤œà¤¼...</kbd> पर कà¥à¤²à¤¿à¤• करें. फ़ाइल का अधिकतम आकार 1मे.बा. तक हो सकता है."
+
+#: ..\..\..\templates\login.tpl.php:20
+#: ..\..\..\templates\register.tpl.php:21
+msgid "Password"
+msgstr "कूटशबà¥à¤¦"
+
+#: ..\..\..\templates\login.tpl.php:22
+msgid "Don't ask for my password for 2 weeks"
+msgstr "कूटशबà¥à¤¦ के लिठमà¥à¤à¤¸à¥‡ 2 सपà¥à¤¤à¤¾à¤¹ तक नहीं पूछें"
+
+#: ..\..\..\templates\login.tpl.php:30
+msgid "Forgotten your password?"
+msgstr "अपना कूटशबà¥à¤¦ भूल गये हैं?"
+
+#: ..\..\..\templates\password.tpl.php:5
+#, php-format
+msgid "If you have forgotten your password, %s can generate a new one. Enter the username and e-mail address of your account into the form below and we will e-mail your new password to you."
+msgstr "अगर आप अपना कूटशबà¥à¤¦ भूल गये हों तो %s आपके à¤à¤• नया कूटशबà¥à¤¦ बना सकता है। खाते से संबदà¥à¤§ अपना उपयोकà¥à¤¤à¤¾ नाम और ईमेल पता नीचे पà¥à¤°à¤µà¤¿à¤·à¥à¤Ÿ करें और हम आपको à¤à¤• नया कूटशबà¥à¤¦ ईमेल कर देंगे."
+
+#: ..\..\..\templates\password.tpl.php:14
+msgid "<abbr title=\"Electronic mail\">E-mail</abbr>"
+msgstr "<abbr title=\"इलेकà¥à¤Ÿà¥à¤°à¤¾à¤¨à¤¿à¤• मेल\">ईमेल</abbr>"
+
+#: ..\..\..\templates\password.tpl.php:19
+msgid "Generate Password"
+msgstr "नया कूटशबà¥à¤¦ बनायें"
+
+#: ..\..\..\templates\profile.tpl.php:23
+msgid "Member Since"
+msgstr "सदसà¥à¤¯à¤¤à¤¾ अवधि"
+
+#: ..\..\..\templates\profile.tpl.php:35
+#: ..\..\..\templates\sidebar.block.watchlist.php:8
+msgid "Watching"
+msgstr "निगरानी में"
+
+#: ..\..\..\templates\profile.tpl.php:50
+msgid "Watched By"
+msgstr "दà¥à¤µà¤¾à¤°à¤¾ देखा गया"
+
+#: ..\..\..\templates\register.tpl.php:11
+#, php-format
+msgid "Sign up here to create a free %s account. All the information requested below is required"
+msgstr "मà¥à¤«à¤¼à¥à¤¤ %s खाता बनाने के लिठयहाठसाइन करें. नीचे निवेदित सभी जानकारियाठआवशà¥à¤¯à¤• हैं"
+
+#: ..\..\..\templates\rss.tpl.php:9
+#, php-format
+msgid "Recent bookmarks posted to %s"
+msgstr "%s को पोसà¥à¤Ÿ की गईं हालिया पृषà¥à¤ -सà¥à¤®à¥ƒà¤¤à¤¿à¤¯à¤¾à¤ "
+
+#: ..\..\..\templates\rss.tpl.php:17
+#: ..\..\..\templates\rss.tpl.php:19
+msgid "No bookmarks found"
+msgstr "कोई पृषà¥à¤ -सà¥à¤®à¥ƒà¤¤à¤¿ नहीं मिली"
+
+#: ..\..\..\templates\sidebar.block.recent.php:15
+msgid "Recent Tags"
+msgstr "हालिया टैग"
+
+#: ..\..\..\templates\sidebar.block.related.php:15
+msgid "Related Tags"
+msgstr "समà¥à¤¬à¤‚धित टैग"
+
+#: ..\..\..\templates\sidebar.block.watchstatus.php:10
+msgid "Remove from Watchlist"
+msgstr "निगरानी सूची से मिटाà¤à¤"
+
+#: ..\..\..\templates\sidebar.block.watchstatus.php:12
+msgid "Add to Watchlist"
+msgstr "निगरानी सूची में जोड़ें"
+
+#: ..\..\..\templates\sidebar.block.watchstatus.php:17
+#, fuzzy
+msgid "Actions"
+msgstr "निरà¥à¤¦à¥‡à¤¶"
+
+#: ..\..\..\templates\tags.tpl.php:8
+msgid "Alphabet"
+msgstr "वरà¥à¤£"
+
+#: ..\..\..\templates\tags.tpl.php:9
+msgid "Popularity"
+msgstr "लोकपà¥à¤°à¤¿à¤¯à¤¤à¤¾"
+
+#: ..\..\..\templates\toolbar.inc.php:11
+msgid "Bookmarks"
+msgstr "पृषà¥à¤ -सà¥à¤®à¥ƒà¤¤à¤¿à¤¯à¤¾à¤"
+
+#: ..\..\..\templates\toolbar.inc.php:16
+msgid "Log Out"
+msgstr "लॉग आउट"
+
diff --git a/locales/it_IT/LC_MESSAGES/messages.mo b/locales/it_IT/LC_MESSAGES/messages.mo
new file mode 100644
index 0000000..7662e54
--- /dev/null
+++ b/locales/it_IT/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/locales/it_IT/LC_MESSAGES/messages.po b/locales/it_IT/LC_MESSAGES/messages.po
new file mode 100644
index 0000000..46d86d3
--- /dev/null
+++ b/locales/it_IT/LC_MESSAGES/messages.po
@@ -0,0 +1,853 @@
+# Scuttle it-IT Translation
+# Copyright (C) 2005 - 2006 Scuttle project
+# This file is distributed under the same license as the Scuttle package.
+# <upcome@gmail.com>
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Scuttle\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2005-11-10 16:58+0100\n"
+"PO-Revision-Date: 2006-03-18 21:51-0800\n"
+"Last-Translator: Marcus Campbell <marcus.campbell@gmail.com>\n"
+"Language-Team: it-IT <upcome@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-Language: Italian\n"
+"X-Poedit-Country: ITALY\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: ..\..\..\about.php:25
+#: ..\..\..\templates\toolbar.inc.php:24
+msgid "About"
+msgstr "Informazioni"
+
+#: ..\..\..\ajaxDelete.php:29
+#, fuzzy
+msgid "You are not allowed to delete this bookmark"
+msgstr "Non hai il permesso di eliminare questo preferito"
+
+#: ..\..\..\ajaxDelete.php:33
+#, fuzzy
+msgid "Failed to delete bookmark"
+msgstr "Eliminazione del preferito fallita"
+
+#: ..\..\..\alltags.php:50
+msgid "All Tags"
+msgstr "Tutti i Tags"
+
+#: ..\..\..\alltags.php:59
+#: ..\..\..\populartags.php:63
+#: ..\..\..\profile.php:46
+#: ..\..\..\rss.php:55
+#: ..\..\..\search.php:61
+#: ..\..\..\watch.php:35
+#: ..\..\..\watched.php:62
+#, php-format
+msgid "User with username %s not was not found"
+msgstr "L'utente %s non è stato trovato"
+
+#: ..\..\..\bookmarks.php:71
+#, fuzzy, php-format
+msgid "User with username %s was not found"
+msgstr "L'utente %s non è stato trovato"
+
+#: ..\..\..\bookmarks.php:94
+#: ..\..\..\edit.php:44
+msgid "Your bookmark must have a title and an address"
+msgstr "Il preferito deve avere un titolo ed un indirizzo"
+
+#: ..\..\..\bookmarks.php:114
+#: ..\..\..\edit.php:58
+msgid "Bookmark saved"
+msgstr "Preferito salvato"
+
+#: ..\..\..\bookmarks.php:122
+#: ..\..\..\import.php:99
+#: ..\..\..\importNetscape.php:74
+msgid "There was an error saving your bookmark. Please try again or contact the administrator."
+msgstr "Si è verificato un errore salvando il tuo preferito. Riprova o contatta l'amministratore"
+
+#: ..\..\..\bookmarks.php:160
+#: ..\..\..\templates\toolbar.inc.php:13
+msgid "Add a Bookmark"
+msgstr "Aggiungi un preferito"
+
+#: ..\..\..\bookmarks.php:163
+msgid "Add Bookmark"
+msgstr "Aggiungi preferito"
+
+#: ..\..\..\bookmarks.php:166
+msgid "You must be logged in before you can add bookmarks."
+msgstr "Devi essere loggato per poter aggiungere dei preferiti"
+
+#: ..\..\..\bookmarks.php:213
+#, fuzzy
+msgid "My Bookmarks"
+msgstr "I Miei Preferiti"
+
+#: ..\..\..\edit.php:29
+msgid "Edit Bookmark"
+msgstr "Modifica Preferito"
+
+#: ..\..\..\edit.php:34
+#, fuzzy, php-format
+msgid "Bookmark with id %s not was not found"
+msgstr "Il preferito con id %s non è stato trovato"
+
+#: ..\..\..\edit.php:39
+#, fuzzy
+msgid "You are not allowed to edit this bookmark"
+msgstr "Non hai il permesso per modificare questo preferito"
+
+#: ..\..\..\edit.php:55
+msgid "Error while saving your bookmark"
+msgstr "Errore salvando il preferito"
+
+#: ..\..\..\edit.php:78
+#, fuzzy
+msgid "Failed to delete the bookmark"
+msgstr "Eliminazione preferito fallita"
+
+#: ..\..\..\edit.php:88
+#: ..\..\..\templates\editprofile.tpl.php:52
+msgid "Save Changes"
+msgstr "Salva Modifiche"
+
+#: ..\..\..\functions.inc.php:92
+msgid "message_die() was called multiple times."
+msgstr "message_die() è stato richiamato più volte."
+
+#: ..\..\..\functions.inc.php:104
+msgid "SQL Error"
+msgstr "Errore SQL"
+
+#: ..\..\..\functions.inc.php:110
+msgid "Line"
+msgstr "Linea"
+
+#: ..\..\..\functions.inc.php:110
+#: ..\..\..\templates\importDelicious.tpl.php:8
+#: ..\..\..\templates\importNetscape.tpl.php:9
+msgid "File"
+msgstr "File"
+
+#: ..\..\..\functions.inc.php:116
+#, fuzzy
+msgid "Information"
+msgstr "Informazioni"
+
+#: ..\..\..\functions.inc.php:121
+msgid "Critical Information"
+msgstr "Informazioni Importanti"
+
+#: ..\..\..\functions.inc.php:126
+msgid "An error occured"
+msgstr "Si è verificato un errore"
+
+#: ..\..\..\functions.inc.php:129
+msgid "General Error"
+msgstr "Errore Generale"
+
+#: ..\..\..\functions.inc.php:137
+msgid "An critical error occured"
+msgstr "Si è verificato un errore critico"
+
+#: ..\..\..\functions.inc.php:140
+msgid "Critical Error"
+msgstr "Errore Critico"
+
+#: ..\..\..\functions.inc.php:149
+msgid "DEBUG MODE"
+msgstr "MODO DEBUG"
+
+#: ..\..\..\history.php:65
+msgid "History"
+msgstr ""
+
+#: ..\..\..\history.php:66
+#, php-format
+msgid "History for %s"
+msgstr ""
+
+#: ..\..\..\history.php:81
+msgid "Address was not found"
+msgstr ""
+
+#: ..\..\..\import.php:41
+msgid "Could not open XML input"
+msgstr "Non posso aprire la fonte XML"
+
+#: ..\..\..\import.php:45
+#, php-format
+msgid "XML error: %s at line %d"
+msgstr "Errore XML: %s alla linea %d"
+
+#: ..\..\..\import.php:54
+msgid "Import Bookmarks from del.icio.us"
+msgstr "Importa Preferiti da del.icio.us"
+
+#: ..\..\..\import.php:86
+#: ..\..\..\importNetscape.php:64
+#, fuzzy
+msgid "You have already submitted this bookmark."
+msgstr "Hai già inserito questo preferito"
+
+#: ..\..\..\import.php:97
+#: ..\..\..\importNetscape.php:72
+#, fuzzy
+msgid "Bookmark imported."
+msgstr "Preferito importato"
+
+#: ..\..\..\importNetscape.php:81
+#, fuzzy
+msgid "Import Bookmarks from Browser File"
+msgstr "Importa Preferiti da un File del Browser"
+
+#: ..\..\..\index.php:32
+msgid "You have now logged out"
+msgstr "Sei uscito dal sistema"
+
+#: ..\..\..\index.php:39
+#, php-format
+msgid "%s: Recent bookmarks"
+msgstr "%s: Preferiti recenti"
+
+#: ..\..\..\index.php:72
+msgid "Store, share and tag your favourite links"
+msgstr ""
+
+#: ..\..\..\index.php:73
+msgid "Recent Bookmarks"
+msgstr "Preferiti Recenti"
+
+#: ..\..\..\jsScuttle.php:22
+msgid "Are you sure?"
+msgstr ""
+
+#: ..\..\..\jsScuttle.php:22
+msgid "Yes"
+msgstr ""
+
+#: ..\..\..\jsScuttle.php:22
+msgid "No"
+msgstr ""
+
+#: ..\..\..\jsScuttle.php:68
+msgid "Available"
+msgstr ""
+
+#: ..\..\..\jsScuttle.php:71
+#, fuzzy
+msgid "Not Available"
+msgstr "Nessun preferito disponibile"
+
+#: ..\..\..\login.php:38
+#, fuzzy
+msgid "The details you have entered are incorrect. Please try again."
+msgstr "Le informazioni che hai fornito non sono corrette. Riprova."
+
+#: ..\..\..\login.php:48
+#: ..\..\..\templates\login.tpl.php:26
+#: ..\..\..\templates\toolbar.inc.php:28
+msgid "Log In"
+msgstr "Entra"
+
+#: ..\..\..\password.php:31
+msgid "You must enter your username."
+msgstr ""
+
+#: ..\..\..\password.php:35
+#, fuzzy
+msgid "You must enter your <abbr title=\"electronic mail\">e-mail</abbr> address."
+msgstr "<em>Devi</em> inserire un nome utente, una password, un nome ed un indirizzo <abbr title=\"posta elettronica\">e-mail</abbr>."
+
+#: ..\..\..\password.php:42
+msgid "No matches found for that username."
+msgstr ""
+
+#: ..\..\..\password.php:45
+#, fuzzy
+msgid "No matches found for that combination of username and <abbr title=\"electronic mail\">e-mail</abbr> address."
+msgstr "<em>Devi</em> inserire un nome utente, una password, un nome ed un indirizzo <abbr title=\"posta elettronica\">e-mail</abbr>."
+
+#: ..\..\..\password.php:53
+#, fuzzy
+msgid "There was an error while generating your new password. Please try again."
+msgstr "Si è verificato un errore salvando il tuo preferito. Riprova o contatta l'amministratore"
+
+#: ..\..\..\password.php:57
+#, fuzzy
+msgid "Your new password is:"
+msgstr "Conferma Nuova Password"
+
+#: ..\..\..\password.php:57
+msgid "To keep your bookmarks secure, you should change this password in your profile the next time you log in."
+msgstr ""
+
+#: ..\..\..\password.php:60
+#, fuzzy, php-format
+msgid "%s Account Information"
+msgstr "Informazioni"
+
+#: ..\..\..\password.php:62
+#, php-format
+msgid "New password generated and sent to %s"
+msgstr ""
+
+#: ..\..\..\password.php:69
+#, fuzzy
+msgid "Forgotten Password"
+msgstr "Nuova Password"
+
+#: ..\..\..\populartags.php:54
+#: ..\..\..\templates\dynamictags.inc.php:101
+#: ..\..\..\templates\sidebar.block.common.php:9
+#: ..\..\..\templates\sidebar.block.popular.php:15
+#: ..\..\..\templates\sidebar.block.recent.php:25
+msgid "Popular Tags"
+msgstr "Tags Più Utilizzati"
+
+#: ..\..\..\profile.php:54
+#: ..\..\..\watched.php:114
+msgid "Username was not specified"
+msgstr "Nome utente non specificato"
+
+#: ..\..\..\profile.php:60
+#, fuzzy
+msgid "My Profile"
+msgstr "Profilo"
+
+#: ..\..\..\profile.php:62
+#: ..\..\..\templates\sidebar.block.profile.php:12
+msgid "Profile"
+msgstr "Profilo"
+
+#: ..\..\..\profile.php:80
+#, fuzzy
+msgid "Password and confirmation do not match."
+msgstr "La password e la sua conferma non coincidono."
+
+#: ..\..\..\profile.php:84
+#, fuzzy
+msgid "Password must be at least 6 characters long."
+msgstr "La password deve essere lunga almeno 6 caratteri."
+
+#: ..\..\..\profile.php:88
+#, fuzzy
+msgid "E-mail address is not valid."
+msgstr "Indirizzo e-mail non valido."
+
+#: ..\..\..\profile.php:92
+msgid "An error occurred while saving your changes."
+msgstr "Si è verificato un errore salvando le tue modifiche."
+
+#: ..\..\..\profile.php:94
+#, fuzzy
+msgid "Changes saved."
+msgstr "Modifiche salvate."
+
+#: ..\..\..\register.php:33
+#, fuzzy
+msgid "You <em>must</em> enter a username, password and e-mail address."
+msgstr "<em>Devi</em> inserire un nome utente, una password, un nome ed un indirizzo <abbr title=\"posta elettronica\">e-mail</abbr>."
+
+#: ..\..\..\register.php:37
+msgid "This username already exists, please make another choice."
+msgstr "Questo nome utente esiste già, scegline un altro."
+
+#: ..\..\..\register.php:41
+#, fuzzy
+msgid "E-mail address is not valid. Please try again."
+msgstr "Indirizzo e-mail non valido."
+
+#: ..\..\..\register.php:50
+#, fuzzy
+msgid "You have successfully registered. Enjoy!"
+msgstr "Ti sei registrato con successo. Buon divertimento!"
+
+#: ..\..\..\register.php:52
+msgid "Registration failed. Please try again."
+msgstr "Registrazione fallita. Riprova."
+
+#: ..\..\..\register.php:57
+#: ..\..\..\templates\register.tpl.php:32
+#: ..\..\..\templates\toolbar.inc.php:27
+msgid "Register"
+msgstr "Registrati"
+
+#: ..\..\..\search.inc.php:29
+#: ..\..\..\search.inc.php:57
+msgid "Search"
+msgstr "Cerca"
+
+#: ..\..\..\search.inc.php:35
+#, fuzzy
+msgid "this user's bookmarks"
+msgstr "%s preferiti"
+
+#: ..\..\..\search.inc.php:40
+msgid "my bookmarks"
+msgstr "i miei preferiti"
+
+#: ..\..\..\search.inc.php:41
+#, fuzzy
+msgid "my watchlist"
+msgstr "Metti Sotto Osservazione"
+
+#: ..\..\..\search.inc.php:45
+msgid "all bookmarks"
+msgstr "tutti i preferiti"
+
+#: ..\..\..\search.inc.php:48
+msgid "for"
+msgstr "per"
+
+#: ..\..\..\search.php:91
+#: ..\..\..\search.php:128
+msgid "Search Bookmarks"
+msgstr "Cerca Preferiti"
+
+#: ..\..\..\search.php:97
+#, fuzzy
+msgid "Search Results"
+msgstr "Risultati della Ricerca"
+
+#: ..\..\..\tags.php:38
+#: ..\..\..\templates\editbookmark.tpl.php:44
+#: ..\..\..\templates\sidebar.block.profile.php:13
+msgid "Tags"
+msgstr "Etichette"
+
+#: ..\..\..\watch.php:79
+#, php-format
+msgid "%s Bookmarks"
+msgstr "%s Preferiti"
+
+#: ..\..\..\watch.php:84
+#, fuzzy
+msgid "User removed from your watchlist"
+msgstr "Utente rimosso dalla tua watchlist"
+
+#: ..\..\..\watch.php:86
+#, fuzzy
+msgid "User added to your watchlist"
+msgstr "Utente aggiunto alla tua watchlist"
+
+#: ..\..\..\watched.php:105
+#, fuzzy
+msgid "My Watchlist"
+msgstr "Lista Sotto Osservazione"
+
+#: ..\..\..\watched.php:107
+#: ..\..\..\templates\sidebar.block.profile.php:14
+#: ..\..\..\templates\toolbar.inc.php:12
+#, fuzzy
+msgid "Watchlist"
+msgstr "Lista Sotto Osservazione"
+
+#: ..\..\..\templates\about.tpl.php:6
+msgid "<strong>Store</strong> all your favourite links in one place, accessible from anywhere."
+msgstr "<strong>Archivia</strong> i tuoi Preferiti in un unico luogo, accessibile ovunque tu sia. "
+
+#: ..\..\..\templates\about.tpl.php:7
+#, fuzzy
+msgid "<strong>Share</strong> your bookmarks with everyone, with friends on your watchlist or just keep them private."
+msgstr "<strong>Condividi</strong> i tuoi Preferiti con gli altri o mantinili privati. Potrai restare aggiornato sui Preferiti aggiunti da altri utenti."
+
+#: ..\..\..\templates\about.tpl.php:8
+msgid "<strong>Tag</strong> your bookmarks with as many labels as you want, instead of wrestling with folders."
+msgstr "<strong>Tagga</strong> i tuoi Preferiti con quante etichette vuoi, anziché perdere tempo con le cartelle."
+
+#: ..\..\..\templates\about.tpl.php:9
+#, fuzzy, php-format
+msgid "<strong><a href=\"register.php\">Register now</a></strong> to start using %s!"
+msgstr "<strong><a href=\"register.php\">Registrati ora</a></strong> per iniziare ad utilizzare %s!"
+
+#: ..\..\..\templates\about.tpl.php:12
+msgid "Geek Stuff"
+msgstr "(Geek Stuff)"
+
+#: ..\..\..\templates\about.tpl.php:14
+#, php-format
+msgid "%s is based on <a href=\"http://sourceforge.net/projects/scuttle/\">an open-source project</a> licensed under the <a href=\"http://www.gnu.org/copyleft/gpl.html\"><acronym title=\"GNU's Not Unix\">GNU</acronym> General Public License</a>. This means you can host it on your own web server for free, whether it is on the Internet, a private network or just your own computer."
+msgstr "%s è basato su <a href=\"http://sourceforge.net/projects/scuttle/\">un progetto open-source</a>."
+
+#: ..\..\..\templates\about.tpl.php:15
+#, php-format
+msgid "%1$s supports most of the <a href=\"http://del.icio.us/doc/api\">del.icio.us <abbr title=\"Application Programming Interface\">API</abbr></a>. Almost all of the neat tools made for that system can be modified to work with %1$s instead. If you find a tool that won't let you change the API address, ask the creator to add this setting. You never know, they might just do it."
+msgstr "%1$s supporta la maggioranza delle <a href=\"http://del.icio.us/doc/api\">del.icio.us <abbr title=\"Application Programming Interface\">API</abbr></a>. Praticamente tutti i tools progettati per de.icio.us possono essere modificati per funzionare con %1$s. Se trovi un tool che non lascia variare indirizzo API, chiedi a chiedi a chi lo ha realizzato di aggiungere questo settaggio."
+
+#: ..\..\..\templates\bookmarks.tpl.php:17
+#: ..\..\..\templates\tags.tpl.php:7
+msgid "Sort by:"
+msgstr "Ordinato per:"
+
+#: ..\..\..\templates\bookmarks.tpl.php:18
+msgid "Date"
+msgstr "Data"
+
+#: ..\..\..\templates\bookmarks.tpl.php:19
+#: ..\..\..\templates\editbookmark.tpl.php:34
+msgid "Title"
+msgstr "Titolo"
+
+#: ..\..\..\templates\bookmarks.tpl.php:23
+msgid "URL"
+msgstr "URL"
+
+#: ..\..\..\templates\bookmarks.tpl.php:60
+msgid "Edit"
+msgstr "Modifica"
+
+#: ..\..\..\templates\bookmarks.tpl.php:60
+msgid "Delete"
+msgstr "Elimina"
+
+#: ..\..\..\templates\bookmarks.tpl.php:66
+msgid "by"
+msgstr ""
+
+#: ..\..\..\templates\bookmarks.tpl.php:78
+#, fuzzy, php-format
+msgid " and %s1 other%s"
+msgstr " e %s altri"
+
+#: ..\..\..\templates\bookmarks.tpl.php:81
+#, fuzzy, php-format
+msgid " and %2$s%1$s others%3$s"
+msgstr " e %s altri"
+
+#: ..\..\..\templates\bookmarks.tpl.php:90
+msgid "Copy"
+msgstr "Copia"
+
+#: ..\..\..\templates\bookmarks.tpl.php:136
+#: ..\..\..\templates\bookmarks.tpl.php:142
+msgid "First"
+msgstr ""
+
+#: ..\..\..\templates\bookmarks.tpl.php:137
+#: ..\..\..\templates\bookmarks.tpl.php:143
+msgid "Previous"
+msgstr "Precedente"
+
+#: ..\..\..\templates\bookmarks.tpl.php:150
+#: ..\..\..\templates\bookmarks.tpl.php:153
+msgid "Next"
+msgstr "Seguente"
+
+#: ..\..\..\templates\bookmarks.tpl.php:151
+#: ..\..\..\templates\bookmarks.tpl.php:154
+msgid "Last"
+msgstr ""
+
+#: ..\..\..\templates\bookmarks.tpl.php:156
+#, php-format
+msgid "Page %d of %d"
+msgstr "Pagina %d di %d"
+
+#: ..\..\..\templates\bookmarks.tpl.php:160
+msgid "No bookmarks available"
+msgstr "Nessun preferito disponibile"
+
+#: ..\..\..\templates\dynamictags.inc.php:108
+#: ..\..\..\templates\sidebar.block.common.php:15
+#: ..\..\..\templates\sidebar.block.popular.php:21
+#: ..\..\..\templates\sidebar.block.recent.php:20
+#: ..\..\..\templates\tags.tpl.php:16
+#, fuzzy
+msgid "bookmark"
+msgid_plural "bookmarks"
+msgstr[0] "preferito"
+msgstr[1] "preferiti"
+
+#: ..\..\..\templates\editbookmark.tpl.php:29
+msgid "Address"
+msgstr "Indirizzo"
+
+#: ..\..\..\templates\editbookmark.tpl.php:31
+#: ..\..\..\templates\editbookmark.tpl.php:36
+#: ..\..\..\templates\editprofile.tpl.php:31
+msgid "Required"
+msgstr "Obbligatorio"
+
+#: ..\..\..\templates\editbookmark.tpl.php:39
+#: ..\..\..\templates\editprofile.tpl.php:47
+#: ..\..\..\templates\profile.tpl.php:28
+msgid "Description"
+msgstr "Descrizione"
+
+#: ..\..\..\templates\editbookmark.tpl.php:46
+msgid "Comma-separated"
+msgstr "Saparati da virgola"
+
+#: ..\..\..\templates\editbookmark.tpl.php:49
+#: ..\..\..\templates\importDelicious.tpl.php:15
+#: ..\..\..\templates\importNetscape.tpl.php:16
+msgid "Privacy"
+msgstr "Privacy"
+
+#: ..\..\..\templates\editbookmark.tpl.php:52
+#: ..\..\..\templates\importDelicious.tpl.php:18
+#: ..\..\..\templates\importNetscape.tpl.php:19
+msgid "Public"
+msgstr "Pubblico"
+
+#: ..\..\..\templates\editbookmark.tpl.php:53
+#: ..\..\..\templates\importDelicious.tpl.php:19
+#: ..\..\..\templates\importNetscape.tpl.php:20
+msgid "Shared with Watch List"
+msgstr "Condiviso con chi tieni sotto osservazione"
+
+#: ..\..\..\templates\editbookmark.tpl.php:54
+#: ..\..\..\templates\importDelicious.tpl.php:20
+#: ..\..\..\templates\importNetscape.tpl.php:21
+msgid "Private"
+msgstr "Privato"
+
+#: ..\..\..\templates\editbookmark.tpl.php:66
+msgid "Delete Bookmark"
+msgstr "Elimina Preferito"
+
+#: ..\..\..\templates\editbookmark.tpl.php:93
+msgid "Bookmarklet"
+msgstr "Bookmarklet"
+
+#: ..\..\..\templates\editbookmark.tpl.php:94
+#, php-format
+msgid "Drag one of the following bookmarklets to your browser's bookmarks and click it whenever you want to add the page you are on to %s"
+msgstr "Trascina uno dei seguenti bookmarklets tra i collegamenti del tuo browser e cliccalo ogni volta che vuoi aggiungere la pagina in cui ti trovi al tuo account %s "
+
+#: ..\..\..\templates\editbookmark.tpl.php:106
+#, php-format
+msgid "Post to %s"
+msgstr "Aggiungi a %s"
+
+#: ..\..\..\templates\editbookmark.tpl.php:107
+#, php-format
+msgid "Post to %s (Pop-up)"
+msgstr "Aggiungi a %s (Pop-up)"
+
+#: ..\..\..\templates\editbookmark.tpl.php:111
+#: ..\..\..\templates\importDelicious.tpl.php:26
+#: ..\..\..\templates\importNetscape.tpl.php:27
+msgid "Import"
+msgstr "Importa"
+
+#: ..\..\..\templates\editbookmark.tpl.php:113
+msgid "Import bookmarks from bookmark file"
+msgstr "Importa preferiti da un file"
+
+#: ..\..\..\templates\editbookmark.tpl.php:113
+msgid "Internet Explorer, Mozilla Firefox and Netscape"
+msgstr "Internet Explorer, Mozilla Firefox e Netscape"
+
+#: ..\..\..\templates\editbookmark.tpl.php:114
+msgid "Import bookmarks from del.icio.us"
+msgstr "Importa preferiti da del.icio.us"
+
+#: ..\..\..\templates\editprofile.tpl.php:10
+msgid "Account Details"
+msgstr ""
+
+#: ..\..\..\templates\editprofile.tpl.php:14
+#: ..\..\..\templates\login.tpl.php:15
+#: ..\..\..\templates\password.tpl.php:10
+#: ..\..\..\templates\profile.tpl.php:7
+#: ..\..\..\templates\register.tpl.php:16
+msgid "Username"
+msgstr "Username"
+
+#: ..\..\..\templates\editprofile.tpl.php:19
+msgid "New Password"
+msgstr "Nuova Password"
+
+#: ..\..\..\templates\editprofile.tpl.php:24
+#, fuzzy
+msgid "Confirm Password"
+msgstr "Conferma Nuova Password"
+
+#: ..\..\..\templates\editprofile.tpl.php:29
+#: ..\..\..\templates\register.tpl.php:26
+msgid "E-mail"
+msgstr "E-mail"
+
+#: ..\..\..\templates\editprofile.tpl.php:35
+msgid "Personal Details"
+msgstr ""
+
+#: ..\..\..\templates\editprofile.tpl.php:39
+#: ..\..\..\templates\profile.tpl.php:12
+msgid "Name"
+msgstr "Nome"
+
+#: ..\..\..\templates\editprofile.tpl.php:43
+#: ..\..\..\templates\profile.tpl.php:18
+msgid "Homepage"
+msgstr "Homepage"
+
+#: ..\..\..\templates\error.404.tpl.php:5
+#, fuzzy
+msgid "Not Found"
+msgstr "Non Trovato"
+
+#: ..\..\..\templates\error.404.tpl.php:6
+msgid "The requested URL was not found on this server"
+msgstr "URL non trovata"
+
+#: ..\..\..\templates\error.500.tpl.php:5
+msgid "General server error"
+msgstr "Errore generale del server"
+
+#: ..\..\..\templates\error.500.tpl.php:6
+msgid "The requested URL could not be processed"
+msgstr "URL non eseguibile"
+
+#: ..\..\..\templates\importDelicious.tpl.php:33
+msgid "Log in to the <a href=\"http://del.icio.us/api/posts/all\">export page at del.icio.us</a>"
+msgstr "Fai il Log-in e vai alla <a href=\"http://del.icio.us/api/posts/all\">export page di del.icio.us</a>"
+
+#: ..\..\..\templates\importDelicious.tpl.php:34
+msgid "Save the resulting <abbr title=\"Extensible Markup Language\">XML</abbr> file to your computer"
+msgstr "Salva il file <abbr title=\"Extensible Markup Language\">XML</abbr> nel tuo computer"
+
+#: ..\..\..\templates\importDelicious.tpl.php:35
+msgid "Click <kbd>Browse...</kbd> to find this file on your computer. The maximum size the file can be is 1MB"
+msgstr "Clicca <kbd>Sfoglia...</kbd> per trovare il file nel tuo computer. La dimensione massima accettata è 1MB"
+
+#: ..\..\..\templates\importDelicious.tpl.php:36
+#: ..\..\..\templates\importNetscape.tpl.php:43
+msgid "Select the default privacy setting for your imported bookmarks"
+msgstr "Seleziona il livello di privacy predefinito per i preferiti importati"
+
+#: ..\..\..\templates\importDelicious.tpl.php:37
+#: ..\..\..\templates\importNetscape.tpl.php:44
+msgid "Click <kbd>Import</kbd> to start importing the bookmarks; it may take a minute"
+msgstr "Clicca <kbd>Importa</kbd> per cominciare ad importare i preferiti; questa operazione può richiedere qualche minuto"
+
+#: ..\..\..\templates\importNetscape.tpl.php:32
+msgid "Instructions"
+msgstr "Istruzioni"
+
+#: ..\..\..\templates\importNetscape.tpl.php:35
+msgid "Export your bookmarks from your browser to a file"
+msgstr "Esporta i tuoi preferiti dal tuo browser ad un file"
+
+#: ..\..\..\templates\importNetscape.tpl.php:37
+#, fuzzy
+msgid "Internet Explorer: <kbd>File &gt; Import and Export... &gt; Export Favorites"
+msgstr "Internet Explorer: <kbd>File > Importa ed Esporta... > Esporta Preferiti"
+
+#: ..\..\..\templates\importNetscape.tpl.php:38
+#, fuzzy
+msgid "Mozilla Firefox: <kbd>Bookmarks &gt; Manage Bookmarks... &gt; File &gt; Export..."
+msgstr "Mozilla Firefox: <kbd>Segnalibri > Gestione Segnalibri... > File > Esporta..."
+
+#: ..\..\..\templates\importNetscape.tpl.php:39
+#, fuzzy
+msgid "Netscape: <kbd>Bookmarks &gt; Manage Bookmarks... &gt; Tools &gt; Export..."
+msgstr "Netscape: <kbd>Bookmarks > Gestione Bookmarks... > Strumenti > Esporta..."
+
+#: ..\..\..\templates\importNetscape.tpl.php:42
+msgid "Click <kbd>Browse...</kbd> to find the saved bookmark file on your computer. The maximum size the file can be is 1MB"
+msgstr "Clicca <kbd>Sfoglia...</kbd> per trovare il file salvato sul tuo computer. La dimensione massima consentita è 1MB"
+
+#: ..\..\..\templates\login.tpl.php:20
+#: ..\..\..\templates\register.tpl.php:21
+msgid "Password"
+msgstr "Password"
+
+#: ..\..\..\templates\login.tpl.php:22
+msgid "Don't ask for my password for 2 weeks"
+msgstr "Non chiedermi la password per 2 settimane"
+
+#: ..\..\..\templates\login.tpl.php:30
+msgid "Forgotten your password?"
+msgstr ""
+
+#: ..\..\..\templates\password.tpl.php:5
+#, php-format
+msgid "If you have forgotten your password, %s can generate a new one. Enter the username and e-mail address of your account into the form below and we will e-mail your new password to you."
+msgstr ""
+
+#: ..\..\..\templates\password.tpl.php:14
+msgid "<abbr title=\"Electronic mail\">E-mail</abbr>"
+msgstr "<abbr title=\"Posta elettronica\">E-mail</abbr>"
+
+#: ..\..\..\templates\password.tpl.php:19
+#, fuzzy
+msgid "Generate Password"
+msgstr "Nuova Password"
+
+#: ..\..\..\templates\profile.tpl.php:23
+msgid "Member Since"
+msgstr "Iscritto Dal"
+
+#: ..\..\..\templates\profile.tpl.php:35
+#: ..\..\..\templates\sidebar.block.watchlist.php:8
+#, fuzzy
+msgid "Watching"
+msgstr "Lista Sotto Osservazione"
+
+#: ..\..\..\templates\profile.tpl.php:50
+#, fuzzy
+msgid "Watched By"
+msgstr "Sotto Osservazione Di"
+
+#: ..\..\..\templates\register.tpl.php:11
+#, fuzzy, php-format
+msgid "Sign up here to create a free %s account. All the information requested below is required"
+msgstr "Registrati per creare un account gratuito con %s. Tutte le informazioni richieste sono obbligatorie."
+
+#: ..\..\..\templates\rss.tpl.php:9
+#, fuzzy, php-format
+msgid "Recent bookmarks posted to %s"
+msgstr "Preferiti inseriti di recente"
+
+#: ..\..\..\templates\rss.tpl.php:17
+#: ..\..\..\templates\rss.tpl.php:19
+msgid "No bookmarks found"
+msgstr "Nessun preferito trovato"
+
+#: ..\..\..\templates\sidebar.block.recent.php:15
+#, fuzzy
+msgid "Recent Tags"
+msgstr "Tags Recenti"
+
+#: ..\..\..\templates\sidebar.block.related.php:15
+msgid "Related Tags"
+msgstr "Tags Correlati"
+
+#: ..\..\..\templates\sidebar.block.watchstatus.php:10
+msgid "Remove from Watchlist"
+msgstr "Rimuovi da Sotto Osservazione"
+
+#: ..\..\..\templates\sidebar.block.watchstatus.php:12
+msgid "Add to Watchlist"
+msgstr "Metti Sotto Osservazione"
+
+#: ..\..\..\templates\sidebar.block.watchstatus.php:17
+#, fuzzy
+msgid "Actions"
+msgstr "Istruzioni"
+
+#: ..\..\..\templates\tags.tpl.php:8
+msgid "Alphabet"
+msgstr ""
+
+#: ..\..\..\templates\tags.tpl.php:9
+#, fuzzy
+msgid "Popularity"
+msgstr "Tags Più Utilizzati"
+
+#: ..\..\..\templates\toolbar.inc.php:11
+#, fuzzy
+msgid "Bookmarks"
+msgstr "%s Preferiti"
+
+#: ..\..\..\templates\toolbar.inc.php:16
+msgid "Log Out"
+msgstr "Esci"
+
diff --git a/locales/ja_JP/LC_MESSAGES/messages.mo b/locales/ja_JP/LC_MESSAGES/messages.mo
new file mode 100644
index 0000000..0d7b372
--- /dev/null
+++ b/locales/ja_JP/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/locales/ja_JP/LC_MESSAGES/messages.po b/locales/ja_JP/LC_MESSAGES/messages.po
new file mode 100644
index 0000000..e59c6aa
--- /dev/null
+++ b/locales/ja_JP/LC_MESSAGES/messages.po
@@ -0,0 +1,808 @@
+# Scuttle ja-JP Translation
+# Copyright (C) 2005 - 2006 Scuttle project
+# This file is distributed under the same license as the Scuttle package.
+# Tadashi Jokagi <elf2000@users.sourceforge.net>, 2005-2006.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: scuttle\n"
+"Report-Msgid-Bugs-To: elf2000@users.sourceforge.net\n"
+"POT-Creation-Date: 2005-11-15 19:51+0000\n"
+"PO-Revision-Date: 2006-04-19 07:52+0900\n"
+"Last-Translator: Marcus Campbell <marcus.campbell@gmail.com>\n"
+"Language-Team: Japanese <elf2000@users.sourceforge.net>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Poedit-Language: Japanese\n"
+"X-Poedit-Country: JAPAN\n"
+
+#: ..\..\..\about.php:25
+#: ..\..\..\templates\toolbar.inc.php:24
+msgid "About"
+msgstr "ã“ã®ã‚µã‚¤ãƒˆã«ã¤ã„ã¦"
+
+#: ..\..\..\ajaxDelete.php:29
+msgid "You are not allowed to delete this bookmark"
+msgstr "ã“ã®ãƒ–ックマークã®å‰Šé™¤ã¯è¨±å¯ã•ã‚Œã¦ã„ã¾ã›ã‚“"
+
+#: ..\..\..\ajaxDelete.php:33
+msgid "Failed to delete bookmark"
+msgstr "ブックマークã®å‰Šé™¤ã«å¤±æ•—"
+
+#: ..\..\..\alltags.php:50
+msgid "All Tags"
+msgstr "ã™ã¹ã¦ã®ã‚¿ã‚°"
+
+#: ..\..\..\alltags.php:59
+#: ..\..\..\populartags.php:63
+#: ..\..\..\profile.php:46
+#: ..\..\..\rss.php:55
+#: ..\..\..\search.php:61
+#: ..\..\..\watch.php:35
+#: ..\..\..\watched.php:62
+#, php-format
+msgid "User with username %s not was not found"
+msgstr "ユーザーå「%sã€ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
+
+#: ..\..\..\bookmarks.php:71
+#, php-format
+msgid "User with username %s was not found"
+msgstr "ユーザーå「%sã€ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
+
+#: ..\..\..\bookmarks.php:94
+#: ..\..\..\edit.php:44
+msgid "Your bookmark must have a title and an address"
+msgstr "ブックマークã¯é¡Œåã¨ã‚¢ãƒ‰ãƒ¬ã‚¹ãŒãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“"
+
+#: ..\..\..\bookmarks.php:114
+#: ..\..\..\edit.php:58
+msgid "Bookmark saved"
+msgstr "ブックマークをä¿å­˜ã—ã¾ã—ãŸ"
+
+#: ..\..\..\bookmarks.php:122
+#: ..\..\..\import.php:99
+#: ..\..\..\importNetscape.php:74
+msgid "There was an error saving your bookmark. Please try again or contact the administrator."
+msgstr "ブックマークã®ä¿å­˜ã§ã‚¨ãƒ©ãƒ¼ã§ã™ã€‚å†åº¦è©¦ã™ã‹ã€ç®¡ç†è€…ã«é€£çµ¡ã—ã¦ãã ã•ã„。"
+
+#: ..\..\..\bookmarks.php:160
+#: ..\..\..\templates\toolbar.inc.php:13
+msgid "Add a Bookmark"
+msgstr "ブックマーク追加"
+
+#: ..\..\..\bookmarks.php:163
+msgid "Add Bookmark"
+msgstr "ブックマークを追加ã™ã‚‹"
+
+#: ..\..\..\bookmarks.php:166
+msgid "You must be logged in before you can add bookmarks."
+msgstr "ブックマークを追加ã™ã‚‹å‰ã«ãƒ­ã‚°ã‚¤ãƒ³ã—ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“。"
+
+#: ..\..\..\bookmarks.php:213
+msgid "My Bookmarks"
+msgstr "自分ã®ãƒ–ックマーク"
+
+#: ..\..\..\edit.php:29
+msgid "Edit Bookmark"
+msgstr "ブックマークを編集ã™ã‚‹"
+
+#: ..\..\..\edit.php:34
+#, php-format
+msgid "Bookmark with id %s not was not found"
+msgstr "ID「%sã€ã¨ãƒ–ックマークã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
+
+#: ..\..\..\edit.php:39
+msgid "You are not allowed to edit this bookmark"
+msgstr "ã“ã®ãƒ–ックマークã®ç·¨é›†ã¯è¨±å¯ã•ã‚Œã¦ã„ã¾ã›ã‚“"
+
+#: ..\..\..\edit.php:55
+msgid "Error while saving your bookmark"
+msgstr "ブックマークã®ä¿å­˜ä¸­ã«ã‚¨ãƒ©ãƒ¼"
+
+#: ..\..\..\edit.php:78
+msgid "Failed to delete the bookmark"
+msgstr "ブックマークã®å‰Šé™¤ã«å¤±æ•—"
+
+#: ..\..\..\edit.php:88
+#: ..\..\..\templates\editprofile.tpl.php:52
+msgid "Save Changes"
+msgstr "変更をä¿å­˜ã™ã‚‹"
+
+#: ..\..\..\functions.inc.php:92
+msgid "message_die() was called multiple times."
+msgstr "message_die() ã¯è¤‡æ•°å›žå‘¼ã°ã‚Œã¾ã—ãŸã€‚"
+
+#: ..\..\..\functions.inc.php:104
+msgid "SQL Error"
+msgstr "SQL エラー"
+
+#: ..\..\..\functions.inc.php:110
+msgid "Line"
+msgstr "行"
+
+#: ..\..\..\functions.inc.php:110
+#: ..\..\..\templates\importDelicious.tpl.php:8
+#: ..\..\..\templates\importNetscape.tpl.php:9
+msgid "File"
+msgstr "ファイル"
+
+#: ..\..\..\functions.inc.php:116
+msgid "Information"
+msgstr "情報"
+
+#: ..\..\..\functions.inc.php:121
+msgid "Critical Information"
+msgstr "é‡è¦ãªæƒ…å ±"
+
+#: ..\..\..\functions.inc.php:126
+msgid "An error occured"
+msgstr "エラーãŒç™ºç”Ÿã—ã¾ã—ãŸ"
+
+#: ..\..\..\functions.inc.php:129
+msgid "General Error"
+msgstr "一般エラー"
+
+#: ..\..\..\functions.inc.php:137
+msgid "An critical error occured"
+msgstr "é‡å¤§ãªã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ"
+
+#: ..\..\..\functions.inc.php:140
+msgid "Critical Error"
+msgstr "é‡å¤§ãªã‚¨ãƒ©ãƒ¼"
+
+#: ..\..\..\functions.inc.php:149
+msgid "DEBUG MODE"
+msgstr "デãƒãƒƒã‚°ãƒ¢ãƒ¼ãƒ‰"
+
+#: ..\..\..\history.php:65
+msgid "History"
+msgstr "履歴"
+
+#: ..\..\..\history.php:66
+#, php-format
+msgid "History for %s"
+msgstr "%s ã®å±¥æ­´"
+
+#: ..\..\..\history.php:81
+msgid "Address was not found"
+msgstr "アドレスã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
+
+#: ..\..\..\import.php:41
+msgid "Could not open XML input"
+msgstr "入力 XML ã‚’é–‹ã‘ã¾ã›ã‚“"
+
+#: ..\..\..\import.php:45
+#, php-format
+msgid "XML error: %s at line %d"
+msgstr "XML エラー: %s 㮠%d 行目"
+
+#: ..\..\..\import.php:54
+msgid "Import Bookmarks from del.icio.us"
+msgstr "del.icio.us ã‹ã‚‰ãƒ–ックマークをインãƒãƒ¼ãƒˆã™ã‚‹"
+
+#: ..\..\..\import.php:86
+#: ..\..\..\importNetscape.php:64
+msgid "You have already submitted this bookmark."
+msgstr "ã“ã®ãƒ–ックマークã¯æ—¢ã«é€ä¿¡ã—ã¦ã„ã¾ã™ã€‚"
+
+#: ..\..\..\import.php:97
+#: ..\..\..\importNetscape.php:72
+msgid "Bookmark imported."
+msgstr "ブックマークをインãƒãƒ¼ãƒˆã—ã¾ã—ãŸã€‚"
+
+#: ..\..\..\importNetscape.php:81
+msgid "Import Bookmarks from Browser File"
+msgstr "ブラウザーã®ãƒ•ã‚¡ã‚¤ãƒ«ã‹ã‚‰ãƒ–ックマークをインãƒãƒ¼ãƒˆã™ã‚‹"
+
+#: ..\..\..\index.php:32
+msgid "You have now logged out"
+msgstr "ログアウトã—ã¾ã—ãŸ"
+
+#: ..\..\..\index.php:39
+#, php-format
+msgid "%s: Recent bookmarks"
+msgstr "%s: 最近ã®ãƒ–ックマーク"
+
+#: ..\..\..\index.php:72
+msgid "Store, share and tag your favourite links"
+msgstr "ãŠæ°—ã«å…¥ã‚Šã®ãƒªãƒ³ã‚¯ã®ä¿å­˜ã€å…±æœ‰ã€ã‚¿ã‚°ä»˜ã‘ã‚’ã—ã¾ã™ã€‚"
+
+#: ..\..\..\index.php:73
+msgid "Recent Bookmarks"
+msgstr "最近ã®ãƒ–ックマーク"
+
+#: ..\..\..\jsScuttle.php:22
+msgid "Are you sure?"
+msgstr "本当ã«ã—ã¾ã™ã‹?"
+
+#: ..\..\..\jsScuttle.php:22
+msgid "Yes"
+msgstr "ã¯ã„"
+
+#: ..\..\..\jsScuttle.php:22
+msgid "No"
+msgstr "ã„ã„ãˆ"
+
+#: ..\..\..\jsScuttle.php:68
+msgid "Available"
+msgstr "利用ã§ãã¾ã™"
+
+#: ..\..\..\jsScuttle.php:71
+msgid "Not Available"
+msgstr "利用ã§ãã¾ã›ã‚“"
+
+#: ..\..\..\login.php:38
+msgid "The details you have entered are incorrect. Please try again."
+msgstr "入力ã—ãŸè©³ç´°ã¯æ­£ã—ãã‚ã‚Šã¾ã›ã‚“。å†ã³è©¦ã¿ã¦ãã ã•ã„。"
+
+#: ..\..\..\login.php:48
+#: ..\..\..\templates\login.tpl.php:26
+#: ..\..\..\templates\toolbar.inc.php:28
+msgid "Log In"
+msgstr "ログイン"
+
+#: ..\..\..\password.php:31
+msgid "You must enter your username."
+msgstr "ユーザーåを入力ã—ã¦ãã ã•ã„。"
+
+#: ..\..\..\password.php:35
+msgid "You must enter your <abbr title=\"electronic mail\">e-mail</abbr> address."
+msgstr "<abbr title=\"é›»å­ãƒ¡ãƒ¼ãƒ«\">é›»å­ãƒ¡ãƒ¼ãƒ«</abbr>アドレスを入力ã—ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“。"
+
+#: ..\..\..\password.php:42
+msgid "No matches found for that username."
+msgstr "一致ã™ã‚‹ãƒ¦ãƒ¼ã‚¶ãƒ¼åãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。"
+
+#: ..\..\..\password.php:45
+msgid "No matches found for that combination of username and <abbr title=\"electronic mail\">e-mail</abbr> address."
+msgstr "一致ã™ã‚‹<abbr title=\"é›»å­ãƒ¡ãƒ¼ãƒ«\">é›»å­ãƒ¡ãƒ¼ãƒ«</abbr>アドレスã¨ãƒ¦ãƒ¼ã‚¶ãƒ¼åã®çµ„ã¿åˆã‚ã›ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚"
+
+#: ..\..\..\password.php:53
+msgid "There was an error while generating your new password. Please try again."
+msgstr "æ–°è¦ãƒ‘スワードã®ç”Ÿæˆä¸­ã«ã‚¨ãƒ©ãƒ¼ã§ã™ã€‚å†åº¦è©¦ã—ã¦ãã ã•ã„。"
+
+#: ..\..\..\password.php:57
+msgid "Your new password is:"
+msgstr "æ–°è¦ãƒ‘スワード:"
+
+#: ..\..\..\password.php:57
+msgid "To keep your bookmarks secure, you should change this password in your profile the next time you log in."
+msgstr "ブックマークã®å®‰å…¨æ€§ã‚’維æŒã™ã‚‹ãŸã‚ã«ã€æ¬¡å›žã®ãƒ­ã‚°ã‚¤ãƒ³æ™‚ã«ãƒ—ロフィールã®ã“ã®ãƒ‘スワードを変ãˆã‚‹ã¹ãã§ã™ã€‚"
+
+#: ..\..\..\password.php:60
+#, php-format
+msgid "%s Account Information"
+msgstr "%sアカウント情報"
+
+#: ..\..\..\password.php:62
+#, php-format
+msgid "New password generated and sent to %s"
+msgstr "æ–°è¦ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã‚’生æˆã—ã€%s ã«é€ä¿¡ã—ã¾ã—ãŸ"
+
+#: ..\..\..\password.php:69
+msgid "Forgotten Password"
+msgstr "パスワード忘れ"
+
+#: ..\..\..\populartags.php:54
+#: ..\..\..\templates\dynamictags.inc.php:101
+#: ..\..\..\templates\sidebar.block.common.php:9
+#: ..\..\..\templates\sidebar.block.popular.php:15
+#: ..\..\..\templates\sidebar.block.recent.php:25
+msgid "Popular Tags"
+msgstr "人気ã®ã‚¿ã‚°"
+
+#: ..\..\..\profile.php:54
+#: ..\..\..\watched.php:114
+msgid "Username was not specified"
+msgstr "ユーザーåãŒæŒ‡å®šã•ã‚Œã¦ã„ãªã„"
+
+#: ..\..\..\profile.php:60
+msgid "My Profile"
+msgstr "自分ã®ãƒ—ロフィール"
+
+#: ..\..\..\profile.php:62
+#: ..\..\..\templates\sidebar.block.profile.php:12
+msgid "Profile"
+msgstr "プロフィール"
+
+#: ..\..\..\profile.php:80
+msgid "Password and confirmation do not match."
+msgstr "パスワードã¨ç¢ºèªãŒä¸€è‡´ã—ã¾ã›ã‚“。"
+
+#: ..\..\..\profile.php:84
+msgid "Password must be at least 6 characters long."
+msgstr "パスワードã¯å°‘ãªãã¨ã‚‚ 6 文字以上ã§ã™ã€‚"
+
+#: ..\..\..\profile.php:88
+msgid "E-mail address is not valid."
+msgstr "é›»å­ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹ã¯æœ‰åŠ¹ã§ã¯ã‚ã‚Šã¾ã›ã‚“。"
+
+#: ..\..\..\profile.php:92
+msgid "An error occurred while saving your changes."
+msgstr "変更ã®ä¿å­˜ä¸­ã«ã‚¨ãƒ©ãƒ¼ã§ã™ã€‚"
+
+#: ..\..\..\profile.php:94
+msgid "Changes saved."
+msgstr "変更をä¿å­˜ã—ã¾ã—ãŸã€‚"
+
+#: ..\..\..\register.php:33
+msgid "You <em>must</em> enter a username, password and e-mail address."
+msgstr "ユーザーåã€ãƒ‘スワードã€åå‰ã¨é›»å­ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹ã‚’入力ã—ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“。"
+
+#: ..\..\..\register.php:37
+msgid "This username already exists, please make another choice."
+msgstr "ユーザーåã¯æ—¢ã«å­˜åœ¨ã—ã¾ã™ã€‚ä»–ã‚’é¸ã‚“ã§ãã ã•ã„。"
+
+#: ..\..\..\register.php:41
+msgid "E-mail address is not valid. Please try again."
+msgstr "é›»å­ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹ã¯æœ‰åŠ¹ã§ã¯ã‚ã‚Šã¾ã›ã‚“。å†åº¦è©¦ã—ã¦ãã ã•ã„。"
+
+#: ..\..\..\register.php:50
+msgid "You have successfully registered. Enjoy!"
+msgstr "登録ã«æˆåŠŸã—ã¾ã—ãŸã€‚楽ã—ã‚“ã§ãã ã•ã„!"
+
+#: ..\..\..\register.php:52
+msgid "Registration failed. Please try again."
+msgstr "登録ã«å¤±æ•—ã—ã¾ã—ãŸã€‚å†åº¦è©¦ã—ã¦ãã ã•ã„。"
+
+#: ..\..\..\register.php:57
+#: ..\..\..\templates\register.tpl.php:32
+#: ..\..\..\templates\toolbar.inc.php:27
+msgid "Register"
+msgstr "登録ã™ã‚‹"
+
+#: ..\..\..\search.inc.php:29
+#: ..\..\..\search.inc.php:57
+msgid "Search"
+msgstr "検索"
+
+#: ..\..\..\search.inc.php:35
+msgid "this user's bookmarks"
+msgstr "ã“ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã®ãƒ–ックマーク"
+
+#: ..\..\..\search.inc.php:40
+msgid "my bookmarks"
+msgstr "自分ã®ãƒ–ックマーク"
+
+#: ..\..\..\search.inc.php:41
+msgid "my watchlist"
+msgstr "自分ã®æ³¨ç›®ä¸€è¦§"
+
+#: ..\..\..\search.inc.php:45
+msgid "all bookmarks"
+msgstr "ã™ã¹ã¦ã®ãƒ–ックマーク"
+
+#: ..\..\..\search.inc.php:48
+msgid "for"
+msgstr "キーワード"
+
+#: ..\..\..\search.php:91
+#: ..\..\..\search.php:128
+msgid "Search Bookmarks"
+msgstr "ブックマークを検索ã™ã‚‹"
+
+#: ..\..\..\search.php:97
+msgid "Search Results"
+msgstr "検索çµæžœ"
+
+#: ..\..\..\tags.php:38
+#: ..\..\..\templates\editbookmark.tpl.php:44
+#: ..\..\..\templates\sidebar.block.profile.php:13
+msgid "Tags"
+msgstr "ã‚¿ã‚°"
+
+#: ..\..\..\watch.php:79
+#, php-format
+msgid "%s Bookmarks"
+msgstr "%sブックマーク"
+
+#: ..\..\..\watch.php:84
+msgid "User removed from your watchlist"
+msgstr "注目一覧ã‹ã‚‰ãƒ¦ãƒ¼ã‚¶ãƒ¼ã‚’削除ã—ã¾ã—ãŸ"
+
+#: ..\..\..\watch.php:86
+msgid "User added to your watchlist"
+msgstr "注目一覧ã«ãƒ¦ãƒ¼ã‚¶ãƒ¼ã‚’追加ã—ã¾ã—ãŸ"
+
+#: ..\..\..\watched.php:105
+msgid "My Watchlist"
+msgstr "自分ã®æ³¨ç›®ä¸€è¦§"
+
+#: ..\..\..\watched.php:107
+#: ..\..\..\templates\sidebar.block.profile.php:14
+#: ..\..\..\templates\toolbar.inc.php:12
+msgid "Watchlist"
+msgstr "注目一覧"
+
+#: ..\..\..\templates\about.tpl.php:6
+msgid "<strong>Store</strong> all your favourite links in one place, accessible from anywhere."
+msgstr "ã„ã‹ãªã‚‹å ´æ‰€ã‹ã‚‰ã‚‚アクセスå¯èƒ½ãª 1 ã¤ã®å ´æ‰€ã«ã€å¥½ããªãƒªãƒ³ã‚¯ã‚’ã™ã¹ã¦<strong>æ ¼ç´</strong>ã—ã¾ã™ã€‚"
+
+#: ..\..\..\templates\about.tpl.php:7
+msgid "<strong>Share</strong> your bookmarks with everyone, with friends on your watchlist or just keep them private."
+msgstr ""
+
+#: ..\..\..\templates\about.tpl.php:8
+msgid "<strong>Tag</strong> your bookmarks with as many labels as you want, instead of wrestling with folders."
+msgstr "フォルダーã¨æ ¼é—˜ã™ã‚‹ä»£ã‚ã‚Šã«ã€æœ›ã‚€ãªã‚‰ã„ãã¤ã‹ã®ãƒ©ãƒ™ãƒ«ã¨ã¨ã—ã¦ãƒ–ックマークã®ã‚¿ã‚°ã‚’付ã‘ã¦ãã ã•ã„。"
+
+#: ..\..\..\templates\about.tpl.php:9
+#, php-format
+msgid "<strong><a href=\"register.php\">Register now</a></strong> to start using %s!"
+msgstr "%s を使ã„始ã‚ã‚‹ã«ã¯<strong><a href=\"register.php\">今ã™ã登録</a>ã—ã¦ãã ã•ã„</strong>!"
+
+#: ..\..\..\templates\about.tpl.php:12
+msgid "Geek Stuff"
+msgstr "Geek スタッフ"
+
+#: ..\..\..\templates\about.tpl.php:14
+#, php-format
+msgid "%s is based on <a href=\"http://sourceforge.net/projects/scuttle/\">an open-source project</a> licensed under the <a href=\"http://www.gnu.org/copyleft/gpl.html\"><acronym title=\"GNU's Not Unix\">GNU</acronym> General Public License</a>. This means you can host it on your own web server for free, whether it is on the Internet, a private network or just your own computer."
+msgstr "%s 㯠<a href=\"http://sourceforge.net/projects/scuttle/\">オープンソース</a>ã«åŸºã¥ã„ãŸã€<a href=\"http://www.gnu.org/copyleft/gpl.html\"><acronym title=\"GNU's Not Unix\">GNU</acronym>General Public License</a> ã®å…ƒã§ãƒ©ã‚¤ã‚»ãƒ³ã‚¹ã•ã‚Œã¦ã„ã¾ã™ã€‚ã“ã‚Œã¯ã€ã‚¤ãƒ³ã‚¿ãƒ¼ãƒãƒƒãƒˆã‚„個人ã®ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã€ã‚ã‚‹ã„ã¯è‡ªåˆ†ã®ã‚³ãƒ³ãƒ”ュータやã€è‡ªåˆ†ã®ã‚¦ã‚§ãƒ–サーãƒã§ç„¡æ–™ã§é‹å–¶ã™ã‚‹ã“ã¨ãŒã§ãã‚‹ã“ã¨ã‚’æ„味ã—ã¾ã™ã€‚"
+
+#: ..\..\..\templates\about.tpl.php:15
+#, php-format
+msgid "%1$s supports most of the <a href=\"http://del.icio.us/doc/api\">del.icio.us <abbr title=\"Application Programming Interface\">API</abbr></a>. Almost all of the neat tools made for that system can be modified to work with %1$s instead. If you find a tool that won't let you change the API address, ask the creator to add this setting. You never know, they might just do it."
+msgstr "%1$s ã¯ã»ã¨ã‚“ã©ã® <a href=\"http://del.icio.us/doc/api\">del.icio.us <abbr title=\"Application Programming Interface\">API</abbr></a> をサãƒãƒ¼ãƒˆã—ã¾ã™ã€‚Almost all of the neat tools made for that system can be modified to work with %1$s instead. If you find a tool that won't let you change the API address, ask the creator to add this setting. You never know, they might just do it."
+
+#: ..\..\..\templates\bookmarks.tpl.php:17
+#: ..\..\..\templates\tags.tpl.php:7
+msgid "Sort by:"
+msgstr "ソート基準"
+
+#: ..\..\..\templates\bookmarks.tpl.php:18
+msgid "Date"
+msgstr "日付"
+
+#: ..\..\..\templates\bookmarks.tpl.php:19
+#: ..\..\..\templates\editbookmark.tpl.php:34
+msgid "Title"
+msgstr "é¡Œå"
+
+#: ..\..\..\templates\bookmarks.tpl.php:23
+msgid "URL"
+msgstr "URL"
+
+#: ..\..\..\templates\bookmarks.tpl.php:60
+msgid "Edit"
+msgstr "編集ã™ã‚‹"
+
+#: ..\..\..\templates\bookmarks.tpl.php:60
+msgid "Delete"
+msgstr "削除ã™ã‚‹"
+
+#: ..\..\..\templates\bookmarks.tpl.php:66
+msgid "by"
+msgstr ""
+
+#: ..\..\..\templates\bookmarks.tpl.php:78
+#, php-format
+msgid " and %s1 other%s"
+msgstr "ã¨ãã®ä»–%sã²ã¨ã‚Š%s"
+
+#: ..\..\..\templates\bookmarks.tpl.php:81
+#, php-format
+msgid " and %2$s%1$s others%3$s"
+msgstr "ã¨ãã®ä»– %2$s%1$s 人%3$s"
+
+#: ..\..\..\templates\bookmarks.tpl.php:90
+msgid "Copy"
+msgstr "コピーã™ã‚‹"
+
+#: ..\..\..\templates\bookmarks.tpl.php:136
+#: ..\..\..\templates\bookmarks.tpl.php:142
+msgid "First"
+msgstr "最åˆã¸"
+
+#: ..\..\..\templates\bookmarks.tpl.php:137
+#: ..\..\..\templates\bookmarks.tpl.php:143
+msgid "Previous"
+msgstr "å‰ã¸"
+
+#: ..\..\..\templates\bookmarks.tpl.php:150
+#: ..\..\..\templates\bookmarks.tpl.php:153
+msgid "Next"
+msgstr "次ã¸"
+
+#: ..\..\..\templates\bookmarks.tpl.php:151
+#: ..\..\..\templates\bookmarks.tpl.php:154
+msgid "Last"
+msgstr "最後ã¸"
+
+#: ..\..\..\templates\bookmarks.tpl.php:156
+#, php-format
+msgid "Page %d of %d"
+msgstr "ページ(%d/%d)"
+
+#: ..\..\..\templates\bookmarks.tpl.php:160
+msgid "No bookmarks available"
+msgstr "ブックマークã¯åˆ©ç”¨ã§ãã¾ã›ã‚“"
+
+#: ..\..\..\templates\dynamictags.inc.php:108
+#: ..\..\..\templates\sidebar.block.common.php:15
+#: ..\..\..\templates\sidebar.block.popular.php:21
+#: ..\..\..\templates\sidebar.block.recent.php:20
+#: ..\..\..\templates\tags.tpl.php:16
+msgid "bookmark"
+msgid_plural "bookmarks"
+msgstr[0] "ブックマーク"
+msgstr[1] "ブックマーク"
+
+#: ..\..\..\templates\editbookmark.tpl.php:29
+msgid "Address"
+msgstr "アドレス"
+
+#: ..\..\..\templates\editbookmark.tpl.php:31
+#: ..\..\..\templates\editbookmark.tpl.php:36
+#: ..\..\..\templates\editprofile.tpl.php:31
+msgid "Required"
+msgstr "å¿…é ˆ"
+
+#: ..\..\..\templates\editbookmark.tpl.php:39
+#: ..\..\..\templates\editprofile.tpl.php:47
+#: ..\..\..\templates\profile.tpl.php:28
+msgid "Description"
+msgstr "説明"
+
+#: ..\..\..\templates\editbookmark.tpl.php:46
+msgid "Comma-separated"
+msgstr "カンマ区切り"
+
+#: ..\..\..\templates\editbookmark.tpl.php:49
+#: ..\..\..\templates\importDelicious.tpl.php:15
+#: ..\..\..\templates\importNetscape.tpl.php:16
+msgid "Privacy"
+msgstr "プライãƒã‚·ãƒ¼"
+
+#: ..\..\..\templates\editbookmark.tpl.php:52
+#: ..\..\..\templates\importDelicious.tpl.php:18
+#: ..\..\..\templates\importNetscape.tpl.php:19
+msgid "Public"
+msgstr "公開"
+
+#: ..\..\..\templates\editbookmark.tpl.php:53
+#: ..\..\..\templates\importDelicious.tpl.php:19
+#: ..\..\..\templates\importNetscape.tpl.php:20
+msgid "Shared with Watch List"
+msgstr "注目リストã§å…±æœ‰"
+
+#: ..\..\..\templates\editbookmark.tpl.php:54
+#: ..\..\..\templates\importDelicious.tpl.php:20
+#: ..\..\..\templates\importNetscape.tpl.php:21
+msgid "Private"
+msgstr "プライベート"
+
+#: ..\..\..\templates\editbookmark.tpl.php:66
+msgid "Delete Bookmark"
+msgstr "ブックマークを削除ã™ã‚‹"
+
+#: ..\..\..\templates\editbookmark.tpl.php:93
+msgid "Bookmarklet"
+msgstr "ブックマークレット"
+
+#: ..\..\..\templates\editbookmark.tpl.php:94
+#, php-format
+msgid "Drag one of the following bookmarklets to your browser's bookmarks and click it whenever you want to add the page you are on to %s"
+msgstr "ブラウザーã®ãƒ–ックマークã«æ¬¡ã®ãƒ–ックマークレットã®ã†ã¡ã® 1 ã¤ã‚’ドラッグã—ã€%s ã«ãƒšãƒ¼ã‚¸ã‚’追加ã—ãŸã„å ´åˆã€å¸¸ã«ãれをクリックã—ã¾ã™ã€‚"
+
+#: ..\..\..\templates\editbookmark.tpl.php:106
+#, php-format
+msgid "Post to %s"
+msgstr "%s ã«æŠ•ç¨¿ã™ã‚‹"
+
+#: ..\..\..\templates\editbookmark.tpl.php:107
+#, php-format
+msgid "Post to %s (Pop-up)"
+msgstr "%s ã«æŠ•ç¨¿ã™ã‚‹ (ãƒãƒƒãƒ—アップ)"
+
+#: ..\..\..\templates\editbookmark.tpl.php:111
+#: ..\..\..\templates\importDelicious.tpl.php:26
+#: ..\..\..\templates\importNetscape.tpl.php:27
+msgid "Import"
+msgstr "インãƒãƒ¼ãƒˆã™ã‚‹"
+
+#: ..\..\..\templates\editbookmark.tpl.php:113
+msgid "Import bookmarks from bookmark file"
+msgstr "ブックマークファイルã‹ã‚‰ãƒ–ックマークをインãƒãƒ¼ãƒˆã™ã‚‹"
+
+#: ..\..\..\templates\editbookmark.tpl.php:113
+msgid "Internet Explorer, Mozilla Firefox and Netscape"
+msgstr "Internet Explorerã€Mozilla Firefox 㨠Netscape"
+
+#: ..\..\..\templates\editbookmark.tpl.php:114
+msgid "Import bookmarks from del.icio.us"
+msgstr "del.icio.us ã‹ã‚‰ãƒ–ックマークをインãƒãƒ¼ãƒˆã™ã‚‹"
+
+#: ..\..\..\templates\editprofile.tpl.php:10
+msgid "Account Details"
+msgstr "アカウントã®è©³ç´°"
+
+#: ..\..\..\templates\editprofile.tpl.php:14
+#: ..\..\..\templates\login.tpl.php:15
+#: ..\..\..\templates\password.tpl.php:10
+#: ..\..\..\templates\profile.tpl.php:7
+#: ..\..\..\templates\register.tpl.php:16
+msgid "Username"
+msgstr "ユーザーå"
+
+#: ..\..\..\templates\editprofile.tpl.php:19
+msgid "New Password"
+msgstr "æ–°è¦ãƒ‘スワード"
+
+#: ..\..\..\templates\editprofile.tpl.php:24
+msgid "Confirm Password"
+msgstr "パスワード(確èª)"
+
+#: ..\..\..\templates\editprofile.tpl.php:29
+#: ..\..\..\templates\register.tpl.php:26
+msgid "E-mail"
+msgstr "é›»å­ãƒ¡ãƒ¼ãƒ«"
+
+#: ..\..\..\templates\editprofile.tpl.php:35
+msgid "Personal Details"
+msgstr "個人ã®è©³ç´°"
+
+#: ..\..\..\templates\editprofile.tpl.php:39
+#: ..\..\..\templates\profile.tpl.php:12
+msgid "Name"
+msgstr "åå‰"
+
+#: ..\..\..\templates\editprofile.tpl.php:43
+#: ..\..\..\templates\profile.tpl.php:18
+msgid "Homepage"
+msgstr "ホームページ"
+
+#: ..\..\..\templates\error.404.tpl.php:5
+msgid "Not Found"
+msgstr "見ã¤ã‹ã‚Šã¾ã›ã‚“"
+
+#: ..\..\..\templates\error.404.tpl.php:6
+msgid "The requested URL was not found on this server"
+msgstr "è¦æ±‚ã•ã‚ŒãŸ URL ã¯ã“ã®ã‚µãƒ¼ãƒãƒ¼ã§è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
+
+#: ..\..\..\templates\error.500.tpl.php:5
+msgid "General server error"
+msgstr "サーãƒãƒ¼å…¨ä½“ã®ã‚¨ãƒ©ãƒ¼"
+
+#: ..\..\..\templates\error.500.tpl.php:6
+msgid "The requested URL could not be processed"
+msgstr "è¦æ±‚ã•ã‚ŒãŸ URL ã¯å‡¦ç†ã§ãã¾ã›ã‚“"
+
+#: ..\..\..\templates\importDelicious.tpl.php:33
+msgid "Log in to the <a href=\"http://del.icio.us/api/posts/all\">export page at del.icio.us</a>"
+msgstr "<a href=\"http://del.icio.us/api/posts/all\">del.icio.us ã®ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆãƒšãƒ¼ã‚¸</a> ã«ãƒ­ã‚°ã‚¤ãƒ³ã—ã¾ã™ã€‚"
+
+#: ..\..\..\templates\importDelicious.tpl.php:34
+msgid "Save the resulting <abbr title=\"Extensible Markup Language\">XML</abbr> file to your computer"
+msgstr "çµæžœã® <abbr title=\"Extensible Markup Language\">XML</abbr> ファイルをコンピューターã«ä¿å­˜ã—ã¾ã™ã€‚"
+
+#: ..\..\..\templates\importDelicious.tpl.php:35
+msgid "Click <kbd>Browse...</kbd> to find this file on your computer. The maximum size the file can be is 1MB"
+msgstr "コンピューター上ã®ã“ã®ãƒ•ã‚¡ã‚¤ãƒ«ã‚’見ã¤ã‘ã‚‹ãŸã‚ã« <kbd>å‚ç…§...</kbd> をクリックã—ã¾ã™ã€‚ファイルã®æœ€å¤§ã‚µã‚¤ã‚ºã¯ 1MB ã§ã™ã€‚"
+
+#: ..\..\..\templates\importDelicious.tpl.php:36
+#: ..\..\..\templates\importNetscape.tpl.php:43
+msgid "Select the default privacy setting for your imported bookmarks"
+msgstr "インãƒãƒ¼ãƒˆã—ãŸãƒ–ックマークã®ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆãƒ—ライãƒã‚·ãƒ¼è¨­å®šã‚’é¸æŠžã—ã¾ã™ã€‚"
+
+#: ..\..\..\templates\importDelicious.tpl.php:37
+#: ..\..\..\templates\importNetscape.tpl.php:44
+msgid "Click <kbd>Import</kbd> to start importing the bookmarks; it may take a minute"
+msgstr "<kbd>インãƒãƒ¼ãƒˆã™ã‚‹</kbd> をクリックã™ã‚‹ã¨ãƒ–ックマークã®ã‚¤ãƒ³ãƒãƒ¼ãƒˆã‚’開始ã—ã¾ã™ã€‚ã—ã°ã‚‰ãã‹ã‹ã‚‹ã‹ã‚‚ã—ã‚Œã¾ã›ã‚“。"
+
+#: ..\..\..\templates\importNetscape.tpl.php:32
+msgid "Instructions"
+msgstr "手順"
+
+#: ..\..\..\templates\importNetscape.tpl.php:35
+msgid "Export your bookmarks from your browser to a file"
+msgstr "ブラウザーã‹ã‚‰ãƒ•ã‚¡ã‚¤ãƒ«ã«ãƒ–ックマークをエクスãƒãƒ¼ãƒˆã™ã‚‹"
+
+#: ..\..\..\templates\importNetscape.tpl.php:37
+msgid "Internet Explorer: <kbd>File &gt; Import and Export... &gt; Export Favorites"
+msgstr "Internet Explorer: <kbd>ファイル &gt; インãƒãƒ¼ãƒˆã¨ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆ... &gt; ãŠæ°—ã«å…¥ã‚Šã®ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆ"
+
+#: ..\..\..\templates\importNetscape.tpl.php:38
+msgid "Mozilla Firefox: <kbd>Bookmarks &gt; Manage Bookmarks... &gt; File &gt; Export..."
+msgstr "Mozilla Firefox: <kbd>ブックマーク &gt; ブックマークã®ç®¡ç†... &gt; ファイル &gt; Export..."
+
+#: ..\..\..\templates\importNetscape.tpl.php:39
+msgid "Netscape: <kbd>Bookmarks &gt; Manage Bookmarks... &gt; Tools &gt; Export..."
+msgstr "Netscape: <kbd>ブックマーク &gt; ブックマークã®ç®¡ç†... &gt; ツール &gt; エクスãƒãƒ¼ãƒˆ..."
+
+#: ..\..\..\templates\importNetscape.tpl.php:42
+msgid "Click <kbd>Browse...</kbd> to find the saved bookmark file on your computer. The maximum size the file can be is 1MB"
+msgstr "コンピューター上ã«ä¿å­˜ã•ã‚ŒãŸãƒ–ックマークを見ã¤ã‘ã‚‹ãŸã‚ã« <kbd>å‚ç…§...</kbd> をクリックã—ã¾ã™ã€‚ファイルã®æœ€å¤§ã‚µã‚¤ã‚ºã¯ 1MB ã§ã™ã€‚"
+
+#: ..\..\..\templates\login.tpl.php:20
+#: ..\..\..\templates\register.tpl.php:21
+msgid "Password"
+msgstr "パスワード"
+
+#: ..\..\..\templates\login.tpl.php:22
+msgid "Don't ask for my password for 2 weeks"
+msgstr "2 週間自分ã®ãƒ‘スワードをå•ã„åˆã‚ã›ã¾ã›ã‚“"
+
+#: ..\..\..\templates\login.tpl.php:30
+msgid "Forgotten your password?"
+msgstr "パスワードを忘れã¾ã—ãŸã‹?"
+
+#: ..\..\..\templates\password.tpl.php:5
+#, php-format
+msgid "If you have forgotten your password, %s can generate a new one. Enter the username and e-mail address of your account into the form below and we will e-mail your new password to you."
+msgstr "パスワードを忘れã¦ã—ã¾ã£ãŸå ´åˆã€%s ã¯æ–°ã—ã„パスワードを生æˆã§ãã¾ã™ã€‚アカウントã®ãƒ¦ãƒ¼ã‚¶ãƒ¼åã¨é›»å­ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹ã‚’下ã®ãƒ•ã‚©ãƒ¼ãƒ ã«å…¥åŠ›ã—ã¦ãã ã•ã„。ãã†ã™ã‚Œã°ã€æ–°ã—ã„パスワードを電å­ãƒ¡ãƒ¼ãƒ«ã§é€ä¿¡ã™ã‚‹ã§ã—ょã†ã€‚"
+
+#: ..\..\..\templates\password.tpl.php:14
+msgid "<abbr title=\"Electronic mail\">E-mail</abbr>"
+msgstr "<abbr title=\"é›»å­ãƒ¡ãƒ¼ãƒ«\">é›»å­ãƒ¡ãƒ¼ãƒ«</abbr>"
+
+#: ..\..\..\templates\password.tpl.php:19
+msgid "Generate Password"
+msgstr "パスワードを生æˆã™ã‚‹"
+
+#: ..\..\..\templates\profile.tpl.php:23
+msgid "Member Since"
+msgstr "メンãƒãƒ¼ç™»éŒ²æ—¥"
+
+#: ..\..\..\templates\profile.tpl.php:35
+#: ..\..\..\templates\sidebar.block.watchlist.php:8
+msgid "Watching"
+msgstr "注目一覧"
+
+#: ..\..\..\templates\profile.tpl.php:50
+msgid "Watched By"
+msgstr ""
+
+#: ..\..\..\templates\register.tpl.php:11
+#, php-format
+msgid "Sign up here to create a free %s account. All the information requested below is required"
+msgstr "ã“ã“ã§ã‚µã‚¤ãƒ³ã‚¢ãƒƒãƒ—ã—ã€%s ã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã‚’自由ã«ä½œæˆã§ãã¾ã™ã€‚下記ã§è¦æ±‚ã•ã‚ŒãŸæƒ…å ±ã¯ã™ã¹ã¦å¿…é ˆã§ã™ã€‚"
+
+#: ..\..\..\templates\rss.tpl.php:9
+#, php-format
+msgid "Recent bookmarks posted to %s"
+msgstr "最近ã®ãƒ–ックマークを %s ã«æŠ•ç¨¿ã—ã¾ã—ãŸ"
+
+#: ..\..\..\templates\rss.tpl.php:17
+#: ..\..\..\templates\rss.tpl.php:19
+msgid "No bookmarks found"
+msgstr "ブックマークãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
+
+#: ..\..\..\templates\sidebar.block.recent.php:15
+msgid "Recent Tags"
+msgstr "最近ã®ã‚¿ã‚°"
+
+#: ..\..\..\templates\sidebar.block.related.php:15
+msgid "Related Tags"
+msgstr "関連ã™ã‚‹ã‚¿ã‚°"
+
+#: ..\..\..\templates\sidebar.block.watchstatus.php:10
+msgid "Remove from Watchlist"
+msgstr "注目一覧ã‹ã‚‰å‰Šé™¤ã™ã‚‹"
+
+#: ..\..\..\templates\sidebar.block.watchstatus.php:12
+msgid "Add to Watchlist"
+msgstr "注目一覧ã«è¿½åŠ "
+
+#: ..\..\..\templates\sidebar.block.watchstatus.php:17
+msgid "Actions"
+msgstr "æ“作"
+
+#: ..\..\..\templates\tags.tpl.php:8
+msgid "Alphabet"
+msgstr "アルファベット"
+
+#: ..\..\..\templates\tags.tpl.php:9
+msgid "Popularity"
+msgstr "人気"
+
+#: ..\..\..\templates\toolbar.inc.php:11
+msgid "Bookmarks"
+msgstr "ブックマーク"
+
+#: ..\..\..\templates\toolbar.inc.php:16
+msgid "Log Out"
+msgstr "ログアウト"
+
diff --git a/locales/lt_LT/LC_MESSAGES/messages.mo b/locales/lt_LT/LC_MESSAGES/messages.mo
new file mode 100644
index 0000000..216b01f
--- /dev/null
+++ b/locales/lt_LT/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/locales/lt_LT/LC_MESSAGES/messages.po b/locales/lt_LT/LC_MESSAGES/messages.po
new file mode 100644
index 0000000..90cd169
--- /dev/null
+++ b/locales/lt_LT/LC_MESSAGES/messages.po
@@ -0,0 +1,808 @@
+# Scuttle lt-LT Translation
+# Copyright (C) 2005 - 2006 Scuttle project
+# This file is distributed under the same license as the Scuttle package.
+# Audrius RadzeviÄius <audrius@gmail.com>
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Scuttle\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2005-04-29 11:17+0200\n"
+"PO-Revision-Date: 2006-03-26 14:26-0800\n"
+"Last-Translator: Marcus Campbell <marcus.campbell@gmail.com>\n"
+"Language-Team: lt-LT <audrius@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-Language: Lithuanian\n"
+"X-Poedit-Country: LITHUANIA\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: ..\..\..\about.php:25
+#: ..\..\..\templates\toolbar.inc.php:24
+msgid "About"
+msgstr "Apie"
+
+#: ..\..\..\ajaxDelete.php:29
+msgid "You are not allowed to delete this bookmark"
+msgstr "Jums neturite teisės ištrinti šį žymę"
+
+#: ..\..\..\ajaxDelete.php:33
+msgid "Failed to delete bookmark"
+msgstr "Nepavyko ištrinti žymės"
+
+#: ..\..\..\alltags.php:50
+msgid "All Tags"
+msgstr "Visos gairÄ—s"
+
+#: ..\..\..\alltags.php:59
+#: ..\..\..\populartags.php:63
+#: ..\..\..\profile.php:46
+#: ..\..\..\rss.php:55
+#: ..\..\..\search.php:61
+#: ..\..\..\watch.php:35
+#: ..\..\..\watched.php:62
+#, php-format
+msgid "User with username %s not was not found"
+msgstr "Nepavyko rasti vartotojo vardu %s"
+
+#: ..\..\..\bookmarks.php:71
+#, php-format
+msgid "User with username %s was not found"
+msgstr "Nepavyko rasti vartotojo vardu %s"
+
+#: ..\..\..\bookmarks.php:94
+#: ..\..\..\edit.php:44
+msgid "Your bookmark must have a title and an address"
+msgstr "Įrašoma žymė privalo turėti pavadinimą ir adresą"
+
+#: ..\..\..\bookmarks.php:114
+#: ..\..\..\edit.php:58
+msgid "Bookmark saved"
+msgstr "Žymė išsaugota"
+
+#: ..\..\..\bookmarks.php:122
+#: ..\..\..\import.php:99
+#: ..\..\..\importNetscape.php:74
+msgid "There was an error saving your bookmark. Please try again or contact the administrator."
+msgstr "Saugant žymę įvyko klaida. Bandykite dar kartą arba kreipkitės į administratorių."
+
+#: ..\..\..\bookmarks.php:160
+#: ..\..\..\templates\toolbar.inc.php:13
+msgid "Add a Bookmark"
+msgstr "Pridėti žymę"
+
+#: ..\..\..\bookmarks.php:163
+msgid "Add Bookmark"
+msgstr "Pridėti žymę"
+
+#: ..\..\..\bookmarks.php:166
+msgid "You must be logged in before you can add bookmarks."
+msgstr "Jei norite pridėti naujas žymes, privalote prisijungti."
+
+#: ..\..\..\bookmarks.php:213
+msgid "My Bookmarks"
+msgstr "Mano žymės"
+
+#: ..\..\..\edit.php:29
+msgid "Edit Bookmark"
+msgstr "Keisti žymę"
+
+#: ..\..\..\edit.php:34
+#, php-format
+msgid "Bookmark with id %s not was not found"
+msgstr "Žymės su id %s nepavyko rasti"
+
+#: ..\..\..\edit.php:39
+msgid "You are not allowed to edit this bookmark"
+msgstr "Jūs neturite teisės keisti šią žymę"
+
+#: ..\..\..\edit.php:55
+msgid "Error while saving your bookmark"
+msgstr "Saugant žymę įvyko klaida"
+
+#: ..\..\..\edit.php:78
+msgid "Failed to delete the bookmark"
+msgstr "Žymės ištrinti nepavyko"
+
+#: ..\..\..\edit.php:88
+#: ..\..\..\templates\editprofile.tpl.php:52
+msgid "Save Changes"
+msgstr "IÅ¡saugoti pakeitimus"
+
+#: ..\..\..\functions.inc.php:92
+msgid "message_die() was called multiple times."
+msgstr "message_die() buvo iškviesta daug kartų."
+
+#: ..\..\..\functions.inc.php:104
+msgid "SQL Error"
+msgstr "message_die() buvo iškviesta daug kartų."
+
+#: ..\..\..\functions.inc.php:110
+msgid "Line"
+msgstr "EilutÄ—"
+
+#: ..\..\..\functions.inc.php:110
+#: ..\..\..\templates\importDelicious.tpl.php:8
+#: ..\..\..\templates\importNetscape.tpl.php:9
+msgid "File"
+msgstr "Failas"
+
+#: ..\..\..\functions.inc.php:116
+msgid "Information"
+msgstr "Informacija"
+
+#: ..\..\..\functions.inc.php:121
+msgid "Critical Information"
+msgstr "KritinÄ— informacija"
+
+#: ..\..\..\functions.inc.php:126
+msgid "An error occured"
+msgstr "Įvyko klaida"
+
+#: ..\..\..\functions.inc.php:129
+msgid "General Error"
+msgstr "Bendro pobūdžio klaida"
+
+#: ..\..\..\functions.inc.php:137
+msgid "An critical error occured"
+msgstr "Įvyko kritinė klaida"
+
+#: ..\..\..\functions.inc.php:140
+msgid "Critical Error"
+msgstr "KritinÄ— klaida"
+
+#: ..\..\..\functions.inc.php:149
+msgid "DEBUG MODE"
+msgstr "Derinimo rėžimas"
+
+#: ..\..\..\history.php:65
+msgid "History"
+msgstr "Istorija"
+
+#: ..\..\..\history.php:66
+#, php-format
+msgid "History for %s"
+msgstr "%s istorija"
+
+#: ..\..\..\history.php:81
+msgid "Address was not found"
+msgstr "Adreso nepavyko rasti"
+
+#: ..\..\..\import.php:41
+msgid "Could not open XML input"
+msgstr "Nepavyko atidaryti XML įvesties"
+
+#: ..\..\..\import.php:45
+#, php-format
+msgid "XML error: %s at line %d"
+msgstr "XML klaida: %s eilutÄ—je %d"
+
+#: ..\..\..\import.php:54
+msgid "Import Bookmarks from del.icio.us"
+msgstr "Importuoti žymes iš del.icio.us"
+
+#: ..\..\..\import.php:86
+#: ..\..\..\importNetscape.php:64
+msgid "You have already submitted this bookmark."
+msgstr "Jūs jau išsaugojote šią žymę."
+
+#: ..\..\..\import.php:97
+#: ..\..\..\importNetscape.php:72
+msgid "Bookmark imported."
+msgstr "Žymė importuota."
+
+#: ..\..\..\importNetscape.php:81
+msgid "Import Bookmarks from Browser File"
+msgstr "Importuoti žymes iš naryklės failo"
+
+#: ..\..\..\index.php:32
+msgid "You have now logged out"
+msgstr "JÅ«s dabar atsijungÄ—te"
+
+#: ..\..\..\index.php:39
+#, php-format
+msgid "%s: Recent bookmarks"
+msgstr "%s: naujos žymės"
+
+#: ..\..\..\index.php:72
+msgid "Store, share and tag your favourite links"
+msgstr "Kaupkite, dalinkites ir aprašinėkite savo svarbiausias interneto žymes"
+
+#: ..\..\..\index.php:73
+msgid "Recent Bookmarks"
+msgstr "Naujos žymės"
+
+#: ..\..\..\jsScuttle.php:22
+msgid "Are you sure?"
+msgstr "Ar tikrai?"
+
+#: ..\..\..\jsScuttle.php:22
+msgid "Yes"
+msgstr "Taip"
+
+#: ..\..\..\jsScuttle.php:22
+msgid "No"
+msgstr "Ne"
+
+#: ..\..\..\jsScuttle.php:68
+msgid "Available"
+msgstr "Yra"
+
+#: ..\..\..\jsScuttle.php:71
+msgid "Not Available"
+msgstr "NÄ—ra"
+
+#: ..\..\..\login.php:38
+msgid "The details you have entered are incorrect. Please try again."
+msgstr "Jūsų įrašyti duomenys neteisingi. Bandykite dar kartą."
+
+#: ..\..\..\login.php:48
+#: ..\..\..\templates\login.tpl.php:26
+#: ..\..\..\templates\toolbar.inc.php:28
+msgid "Log In"
+msgstr "Prisijungti"
+
+#: ..\..\..\password.php:31
+msgid "You must enter your username."
+msgstr "Privalote įrašyti vartotojo vardą."
+
+#: ..\..\..\password.php:35
+msgid "You must enter your <abbr title=\"electronic mail\">e-mail</abbr> address."
+msgstr "Privalote įrašyti savo <abbr title=\"elektroninis paštas\">el. pašto</abbr> adresą."
+
+#: ..\..\..\password.php:42
+msgid "No matches found for that username."
+msgstr "Nepavyko rasti įrašų, susijusių su šiuo vartotoju."
+
+#: ..\..\..\password.php:45
+msgid "No matches found for that combination of username and <abbr title=\"electronic mail\">e-mail</abbr> address."
+msgstr "Nepavyko rasti įrašų, susijusių su šiuo vartotojo vardu ir <abbr title=\"elektroninis paštas\">el. pašto</abbr> adresu."
+
+#: ..\..\..\password.php:53
+msgid "There was an error while generating your new password. Please try again."
+msgstr "Generuojant naują Jūsų slaptažodį įvyko klaida. Bandykite dar kartą."
+
+#: ..\..\..\password.php:57
+msgid "Your new password is:"
+msgstr "Jūsų naujasis slaptažodis yra:"
+
+#: ..\..\..\password.php:57
+msgid "To keep your bookmarks secure, you should change this password in your profile the next time you log in."
+msgstr "Vardan Jūsų kaupiamos informacijos saugumo, rekomenduojame pasikeisti slaptažodį, kai kitą kartą prisijungsite prie vartotojo profilio."
+
+#: ..\..\..\password.php:60
+#, php-format
+msgid "%s Account Information"
+msgstr "%s paskyros informacija"
+
+#: ..\..\..\password.php:62
+#, php-format
+msgid "New password generated and sent to %s"
+msgstr "Naujas slaptažodis sukurtas ir išsiųstas %s"
+
+#: ..\..\..\password.php:69
+msgid "Forgotten Password"
+msgstr "Užmirštas slaptažodis"
+
+#: ..\..\..\populartags.php:54
+#: ..\..\..\templates\dynamictags.inc.php:101
+#: ..\..\..\templates\sidebar.block.common.php:9
+#: ..\..\..\templates\sidebar.block.popular.php:15
+#: ..\..\..\templates\sidebar.block.recent.php:25
+msgid "Popular Tags"
+msgstr "Populiarios gairÄ—s"
+
+#: ..\..\..\profile.php:54
+#: ..\..\..\watched.php:114
+msgid "Username was not specified"
+msgstr "Nenurodytas vartotojo vardas"
+
+#: ..\..\..\profile.php:60
+msgid "My Profile"
+msgstr "Mano profilis"
+
+#: ..\..\..\profile.php:62
+#: ..\..\..\templates\sidebar.block.profile.php:12
+msgid "Profile"
+msgstr "Profilis"
+
+#: ..\..\..\profile.php:80
+msgid "Password and confirmation do not match."
+msgstr "Įrašyti slaptažodžio variantai nesutampa."
+
+#: ..\..\..\profile.php:84
+msgid "Password must be at least 6 characters long."
+msgstr "Slaptažodis turi būti bent 6 simbolių ilgio."
+
+#: ..\..\..\profile.php:88
+msgid "E-mail address is not valid."
+msgstr "Neteisingas el. pašto adresas."
+
+#: ..\..\..\profile.php:92
+msgid "An error occurred while saving your changes."
+msgstr "Saugant pakeitimus įvyko klaida."
+
+#: ..\..\..\profile.php:94
+msgid "Changes saved."
+msgstr "Pakeitimai išsaugoti."
+
+#: ..\..\..\register.php:33
+msgid "You <em>must</em> enter a username, password and e-mail address."
+msgstr "<em>Privalote</em> įrašyti vartotojo vardą, slaptažodį, vardą ir <abbr title=\"elektroninis paštas\">el. pašto</abbr> adresą."
+
+#: ..\..\..\register.php:37
+msgid "This username already exists, please make another choice."
+msgstr "Toks vartotojas jau yra, prašom pasirinkti kitą."
+
+#: ..\..\..\register.php:41
+msgid "E-mail address is not valid. Please try again."
+msgstr "El. pašto adresas neteisingas. Bandykite dar kartą."
+
+#: ..\..\..\register.php:50
+msgid "You have successfully registered. Enjoy!"
+msgstr "Sveikiname sėkmingai užsiregistravus!"
+
+#: ..\..\..\register.php:52
+msgid "Registration failed. Please try again."
+msgstr "Registracija nepavyko. Bandykite dar kartÄ…."
+
+#: ..\..\..\register.php:57
+#: ..\..\..\templates\register.tpl.php:32
+#: ..\..\..\templates\toolbar.inc.php:27
+msgid "Register"
+msgstr "Registracija"
+
+#: ..\..\..\search.inc.php:29
+#: ..\..\..\search.inc.php:57
+msgid "Search"
+msgstr "Ieškoti"
+
+#: ..\..\..\search.inc.php:35
+msgid "this user's bookmarks"
+msgstr "šio vartotojo žymėse"
+
+#: ..\..\..\search.inc.php:40
+msgid "my bookmarks"
+msgstr "mano žymėse"
+
+#: ..\..\..\search.inc.php:41
+msgid "my watchlist"
+msgstr "biÄiulių žymÄ—se"
+
+#: ..\..\..\search.inc.php:45
+msgid "all bookmarks"
+msgstr "visose žymėse"
+
+#: ..\..\..\search.inc.php:48
+msgid "for"
+msgstr "teksto"
+
+#: ..\..\..\search.php:91
+#: ..\..\..\search.php:128
+msgid "Search Bookmarks"
+msgstr "Ieškoti žymėse"
+
+#: ..\..\..\search.php:97
+msgid "Search Results"
+msgstr "Paieškos rezultatai"
+
+#: ..\..\..\tags.php:38
+#: ..\..\..\templates\editbookmark.tpl.php:44
+#: ..\..\..\templates\sidebar.block.profile.php:13
+msgid "Tags"
+msgstr "GairÄ—s"
+
+#: ..\..\..\watch.php:79
+#, php-format
+msgid "%s Bookmarks"
+msgstr "%s žymės"
+
+#: ..\..\..\watch.php:84
+msgid "User removed from your watchlist"
+msgstr "Vartotojas iÅ¡brauktas iÅ¡ biÄiulių sÄ…raÅ¡o"
+
+#: ..\..\..\watch.php:86
+msgid "User added to your watchlist"
+msgstr "Vartotojas įtrauktas į biÄiulių sÄ…raÅ¡Ä…"
+
+#: ..\..\..\watched.php:105
+msgid "My Watchlist"
+msgstr "Mano biÄiuliai"
+
+#: ..\..\..\watched.php:107
+#: ..\..\..\templates\sidebar.block.profile.php:14
+#: ..\..\..\templates\toolbar.inc.php:12
+msgid "Watchlist"
+msgstr "BiÄiuliai"
+
+#: ..\..\..\templates\about.tpl.php:6
+msgid "<strong>Store</strong> all your favourite links in one place, accessible from anywhere."
+msgstr "<strong>Kaupkite</strong> Jus dominanÄias žymes vienoje, bet kur pasiekiamoje vietoje."
+
+#: ..\..\..\templates\about.tpl.php:7
+msgid "<strong>Share</strong> your bookmarks with everyone, with friends on your watchlist or just keep them private."
+msgstr "<strong>DalinkitÄ—s</strong> savo žymÄ—mis su visais ar į tik biÄiulių sÄ…raÅ¡Ä… įtrauktais draugais arba laikykite jas asmeniniam naudojimui."
+
+#: ..\..\..\templates\about.tpl.php:8
+msgid "<strong>Tag</strong> your bookmarks with as many labels as you want, instead of wrestling with folders."
+msgstr "<strong>Grupuokite</strong> savo žymes gairių pagalba. Jų galite sukurti tiek, kiek Jums reikia. PamirÅ¡kite nelanksÄius katalogus!"
+
+#: ..\..\..\templates\about.tpl.php:9
+#, php-format
+msgid "<strong><a href=\"register.php\">Register now</a></strong> to start using %s!"
+msgstr "<strong><a href=\"register.php\">RegistruokitÄ—s dabar</a></strong> ir pradÄ—kite darbÄ… su <strong>%s</strong>!"
+
+#: ..\..\..\templates\about.tpl.php:12
+msgid "Geek Stuff"
+msgstr "TechninÄ— informacija"
+
+#: ..\..\..\templates\about.tpl.php:14
+#, php-format
+msgid "%s is based on <a href=\"http://sourceforge.net/projects/scuttle/\">an open-source project</a> licensed under the <a href=\"http://www.gnu.org/copyleft/gpl.html\"><acronym title=\"GNU's Not Unix\">GNU</acronym> General Public License</a>. This means you can host it on your own web server for free, whether it is on the Internet, a private network or just your own computer."
+msgstr "<strong>%s</strong> veikia pagal <a href=\"http://www.gnu.org/copyleft/gpl.html\"><acronym title=\"GNU's Not Unix\">GNU</acronym> GPL</a> licenciją sukurto <a href=\"http://sourceforge.net/projects/scuttle/\">atvirojo kodo projekto</a> pagrindu. Tai reiškia, kad Jūs galite šią sistemą nemokamai naudoti ir talpinti internete, vidaus tinkle ar savo kompiuteryje."
+
+#: ..\..\..\templates\about.tpl.php:15
+#, php-format
+msgid "%1$s supports most of the <a href=\"http://del.icio.us/doc/api\">del.icio.us <abbr title=\"Application Programming Interface\">API</abbr></a>. Almost all of the neat tools made for that system can be modified to work with %1$s instead. If you find a tool that won't let you change the API address, ask the creator to add this setting. You never know, they might just do it."
+msgstr "<strong>%1$s</strong> palaiko <a href=\"http://del.icio.us/doc/api\">del.icio.us <abbr title=\"Application Programming Interface\">API</abbr></a>. Daugumą šiai sistemai skirtų įrankių galiama pakoreguoti taip, kad jie veiktų su <strong>%1$s</strong>. Jei radote įrankį, kuriame negalima pakeisti API adreso, paprašykite jo kūrėjų tai padaryti. Jie tikrai neatsilaikys Jūsų kerams."
+
+#: ..\..\..\templates\bookmarks.tpl.php:17
+#: ..\..\..\templates\tags.tpl.php:7
+msgid "Sort by:"
+msgstr "RÅ«Å¡iuoti pagal:"
+
+#: ..\..\..\templates\bookmarks.tpl.php:18
+msgid "Date"
+msgstr "datÄ…"
+
+#: ..\..\..\templates\bookmarks.tpl.php:19
+#: ..\..\..\templates\editbookmark.tpl.php:34
+msgid "Title"
+msgstr "pavadinimÄ…"
+
+#: ..\..\..\templates\bookmarks.tpl.php:23
+msgid "URL"
+msgstr "adresÄ…"
+
+#: ..\..\..\templates\bookmarks.tpl.php:60
+msgid "Edit"
+msgstr "Keisti"
+
+#: ..\..\..\templates\bookmarks.tpl.php:60
+msgid "Delete"
+msgstr "Trinti"
+
+#: ..\..\..\templates\bookmarks.tpl.php:66
+msgid "by"
+msgstr " įrašė"
+
+#: ..\..\..\templates\bookmarks.tpl.php:78
+#, php-format
+msgid " and %s1 other%s"
+msgstr " bei dar %s1 vartotojas%s"
+
+#: ..\..\..\templates\bookmarks.tpl.php:81
+#, php-format
+msgid " and %2$s%1$s others%3$s"
+msgstr " bei dar %2$s%1$s vartotojai%3$s"
+
+#: ..\..\..\templates\bookmarks.tpl.php:90
+msgid "Copy"
+msgstr "Kopijuoti"
+
+#: ..\..\..\templates\bookmarks.tpl.php:136
+#: ..\..\..\templates\bookmarks.tpl.php:142
+msgid "First"
+msgstr "Pirmas"
+
+#: ..\..\..\templates\bookmarks.tpl.php:137
+#: ..\..\..\templates\bookmarks.tpl.php:143
+msgid "Previous"
+msgstr "Ankstesnis"
+
+#: ..\..\..\templates\bookmarks.tpl.php:150
+#: ..\..\..\templates\bookmarks.tpl.php:153
+msgid "Next"
+msgstr "Kitas"
+
+#: ..\..\..\templates\bookmarks.tpl.php:151
+#: ..\..\..\templates\bookmarks.tpl.php:154
+msgid "Last"
+msgstr "Paskutinis"
+
+#: ..\..\..\templates\bookmarks.tpl.php:156
+#, php-format
+msgid "Page %d of %d"
+msgstr "%d iš %d puslapių"
+
+#: ..\..\..\templates\bookmarks.tpl.php:160
+msgid "No bookmarks available"
+msgstr "Žymių nėra"
+
+#: ..\..\..\templates\dynamictags.inc.php:108
+#: ..\..\..\templates\sidebar.block.common.php:15
+#: ..\..\..\templates\sidebar.block.popular.php:21
+#: ..\..\..\templates\sidebar.block.recent.php:20
+#: ..\..\..\templates\tags.tpl.php:16
+msgid "bookmark"
+msgid_plural "bookmarks"
+msgstr[0] "žymė"
+msgstr[1] "žymės"
+
+#: ..\..\..\templates\editbookmark.tpl.php:29
+msgid "Address"
+msgstr "Adresas"
+
+#: ..\..\..\templates\editbookmark.tpl.php:31
+#: ..\..\..\templates\editbookmark.tpl.php:36
+#: ..\..\..\templates\editprofile.tpl.php:31
+msgid "Required"
+msgstr "Privaloma"
+
+#: ..\..\..\templates\editbookmark.tpl.php:39
+#: ..\..\..\templates\editprofile.tpl.php:47
+#: ..\..\..\templates\profile.tpl.php:28
+msgid "Description"
+msgstr "Aprašas"
+
+#: ..\..\..\templates\editbookmark.tpl.php:46
+msgid "Comma-separated"
+msgstr "Skiriamos kableliais"
+
+#: ..\..\..\templates\editbookmark.tpl.php:49
+#: ..\..\..\templates\importDelicious.tpl.php:15
+#: ..\..\..\templates\importNetscape.tpl.php:16
+msgid "Privacy"
+msgstr "Privatumas"
+
+#: ..\..\..\templates\editbookmark.tpl.php:52
+#: ..\..\..\templates\importDelicious.tpl.php:18
+#: ..\..\..\templates\importNetscape.tpl.php:19
+msgid "Public"
+msgstr "Vieša"
+
+#: ..\..\..\templates\editbookmark.tpl.php:53
+#: ..\..\..\templates\importDelicious.tpl.php:19
+#: ..\..\..\templates\importNetscape.tpl.php:20
+msgid "Shared with Watch List"
+msgstr "Tik biÄiuliams"
+
+#: ..\..\..\templates\editbookmark.tpl.php:54
+#: ..\..\..\templates\importDelicious.tpl.php:20
+#: ..\..\..\templates\importNetscape.tpl.php:21
+msgid "Private"
+msgstr "Privati"
+
+#: ..\..\..\templates\editbookmark.tpl.php:66
+msgid "Delete Bookmark"
+msgstr "Trinti žymę"
+
+#: ..\..\..\templates\editbookmark.tpl.php:93
+msgid "Bookmarklet"
+msgstr "Žymeklis"
+
+#: ..\..\..\templates\editbookmark.tpl.php:94
+#, php-format
+msgid "Drag one of the following bookmarklets to your browser's bookmarks and click it whenever you want to add the page you are on to %s"
+msgstr "Perkelkite šį žymeklįį Jūsų naršyklėje esantį žymių katalogą ir naudokite, kai norėsite pridėti naują puslapį į <strong>%s</strong>"
+
+#: ..\..\..\templates\editbookmark.tpl.php:106
+#, php-format
+msgid "Post to %s"
+msgstr "Siųsti į <strong>%s</strong>"
+
+#: ..\..\..\templates\editbookmark.tpl.php:107
+#, php-format
+msgid "Post to %s (Pop-up)"
+msgstr "Siųsti į <strong>%s</strong> (atskirame lange)"
+
+#: ..\..\..\templates\editbookmark.tpl.php:111
+#: ..\..\..\templates\importDelicious.tpl.php:26
+#: ..\..\..\templates\importNetscape.tpl.php:27
+msgid "Import"
+msgstr "Importas"
+
+#: ..\..\..\templates\editbookmark.tpl.php:113
+msgid "Import bookmarks from bookmark file"
+msgstr "Importuoti žymes iš žymių failo"
+
+#: ..\..\..\templates\editbookmark.tpl.php:113
+msgid "Internet Explorer, Mozilla Firefox and Netscape"
+msgstr "Internet Explorer, Mozilla Firefox ir Netscape"
+
+#: ..\..\..\templates\editbookmark.tpl.php:114
+msgid "Import bookmarks from del.icio.us"
+msgstr "Importuoti žymes iš del.icio.us"
+
+#: ..\..\..\templates\editprofile.tpl.php:10
+msgid "Account Details"
+msgstr "Paskyris informacija"
+
+#: ..\..\..\templates\editprofile.tpl.php:14
+#: ..\..\..\templates\login.tpl.php:15
+#: ..\..\..\templates\password.tpl.php:10
+#: ..\..\..\templates\profile.tpl.php:7
+#: ..\..\..\templates\register.tpl.php:16
+msgid "Username"
+msgstr "Vartotojas"
+
+#: ..\..\..\templates\editprofile.tpl.php:19
+msgid "New Password"
+msgstr "Naujas slaptažodis"
+
+#: ..\..\..\templates\editprofile.tpl.php:24
+msgid "Confirm Password"
+msgstr "Pakartoti slaptažodį"
+
+#: ..\..\..\templates\editprofile.tpl.php:29
+#: ..\..\..\templates\register.tpl.php:26
+msgid "E-mail"
+msgstr "El. paštas"
+
+#: ..\..\..\templates\editprofile.tpl.php:35
+msgid "Personal Details"
+msgstr "Asmeniniai duomenys"
+
+#: ..\..\..\templates\editprofile.tpl.php:39
+#: ..\..\..\templates\profile.tpl.php:12
+msgid "Name"
+msgstr "Vardas"
+
+#: ..\..\..\templates\editprofile.tpl.php:43
+#: ..\..\..\templates\profile.tpl.php:18
+msgid "Homepage"
+msgstr "SvetainÄ—"
+
+#: ..\..\..\templates\error.404.tpl.php:5
+msgid "Not Found"
+msgstr "NÄ—ra"
+
+#: ..\..\..\templates\error.404.tpl.php:6
+msgid "The requested URL was not found on this server"
+msgstr "Užklausto saito darbo stotyje nėra"
+
+#: ..\..\..\templates\error.500.tpl.php:5
+msgid "General server error"
+msgstr "Bendro pobūdžio darbo stoties klaida"
+
+#: ..\..\..\templates\error.500.tpl.php:6
+msgid "The requested URL could not be processed"
+msgstr "Užklausa negali būti įvykdyta"
+
+#: ..\..\..\templates\importDelicious.tpl.php:33
+msgid "Log in to the <a href=\"http://del.icio.us/api/posts/all\">export page at del.icio.us</a>"
+msgstr "Prisijunkite prie <a href=\"http://del.icio.us/api/posts/all\">del.icio.us eksporto puslapio</a>"
+
+#: ..\..\..\templates\importDelicious.tpl.php:34
+msgid "Save the resulting <abbr title=\"Extensible Markup Language\">XML</abbr> file to your computer"
+msgstr "Išsaugoti <abbr title=\"Extensible Markup Language\">XML</abbr> failą Jūsų kompiuteryje"
+
+#: ..\..\..\templates\importDelicious.tpl.php:35
+msgid "Click <kbd>Browse...</kbd> to find this file on your computer. The maximum size the file can be is 1MB"
+msgstr "Paspauskite <kbd>Browse...</kbd> ir raskite šį failą kompiuteryje. Maksimalus failo dydis - 1 MB"
+
+#: ..\..\..\templates\importDelicious.tpl.php:36
+#: ..\..\..\templates\importNetscape.tpl.php:43
+msgid "Select the default privacy setting for your imported bookmarks"
+msgstr "Pasirinkite bazines privatumo nuostatas importuojamoms žymėms"
+
+#: ..\..\..\templates\importDelicious.tpl.php:37
+#: ..\..\..\templates\importNetscape.tpl.php:44
+msgid "Click <kbd>Import</kbd> to start importing the bookmarks; it may take a minute"
+msgstr "Norėdami importuoti žymes, spauskite <kbd>Importuoti</kbd>; tai gali šiek tiek užtrukti"
+
+#: ..\..\..\templates\importNetscape.tpl.php:32
+msgid "Instructions"
+msgstr "Instrukcija"
+
+#: ..\..\..\templates\importNetscape.tpl.php:35
+msgid "Export your bookmarks from your browser to a file"
+msgstr "Eksportuokite savo žymes iš naršyklės į failą"
+
+#: ..\..\..\templates\importNetscape.tpl.php:37
+msgid "Internet Explorer: <kbd>File &gt; Import and Export... &gt; Export Favorites"
+msgstr "Internet Explorer: <kbd>File &gt; Import and Export... &gt; Export Favorites"
+
+#: ..\..\..\templates\importNetscape.tpl.php:38
+msgid "Mozilla Firefox: <kbd>Bookmarks &gt; Manage Bookmarks... &gt; File &gt; Export..."
+msgstr "Mozilla Firefox: <kbd>Bookmarks &gt; Manage Bookmarks... &gt; File &gt; Export..."
+
+#: ..\..\..\templates\importNetscape.tpl.php:39
+msgid "Netscape: <kbd>Bookmarks &gt; Manage Bookmarks... &gt; Tools &gt; Export..."
+msgstr "Netscape: <kbd>Bookmarks &gt; Manage Bookmarks... &gt; Tools &gt; Export..."
+
+#: ..\..\..\templates\importNetscape.tpl.php:42
+msgid "Click <kbd>Browse...</kbd> to find the saved bookmark file on your computer. The maximum size the file can be is 1MB"
+msgstr "Paspauskite <kbd>Browse...</kbd> ir raskite žymes savo kompiuteryje. Maksimalus failo dydis - 1MB."
+
+#: ..\..\..\templates\login.tpl.php:20
+#: ..\..\..\templates\register.tpl.php:21
+msgid "Password"
+msgstr "Slaptažodis"
+
+#: ..\..\..\templates\login.tpl.php:22
+msgid "Don't ask for my password for 2 weeks"
+msgstr "Neklausti slaptažodžio dvi savaites"
+
+#: ..\..\..\templates\login.tpl.php:30
+msgid "Forgotten your password?"
+msgstr "Pamiršote slaptažodį?"
+
+#: ..\..\..\templates\password.tpl.php:5
+#, php-format
+msgid "If you have forgotten your password, %s can generate a new one. Enter the username and e-mail address of your account into the form below and we will e-mail your new password to you."
+msgstr "Jei pamiršote savo slaptažodį, <strong>%s</strong> gali sukurti Jums naują. Įrašykite savo paskyros vartotojo vardą ir mums pateikto el. pašto adresą ir mes Jums persiųsime naująjį slaptažodį."
+
+#: ..\..\..\templates\password.tpl.php:14
+msgid "<abbr title=\"Electronic mail\">E-mail</abbr>"
+msgstr "<abbr title=\"Elektroninis paštas\">El. paštas</abbr>"
+
+#: ..\..\..\templates\password.tpl.php:19
+msgid "Generate Password"
+msgstr "Generuoti slaptažodį"
+
+#: ..\..\..\templates\profile.tpl.php:23
+msgid "Member Since"
+msgstr "Dalyvauja nuo"
+
+#: ..\..\..\templates\profile.tpl.php:35
+#: ..\..\..\templates\sidebar.block.watchlist.php:8
+msgid "Watching"
+msgstr "Stebi"
+
+#: ..\..\..\templates\profile.tpl.php:50
+msgid "Watched By"
+msgstr "Yra stebimas"
+
+#: ..\..\..\templates\register.tpl.php:11
+#, php-format
+msgid "Sign up here to create a free %s account. All the information requested below is required"
+msgstr "NorÄ—dami prisiregistruoti <strong>%s</strong> užlipdykite žemiau esanÄiÄ… anketÄ…"
+
+#: ..\..\..\templates\rss.tpl.php:9
+#, php-format
+msgid "Recent bookmarks posted to %s"
+msgstr "Naujos, %s išsiųstos gairės"
+
+#: ..\..\..\templates\rss.tpl.php:17
+#: ..\..\..\templates\rss.tpl.php:19
+msgid "No bookmarks found"
+msgstr "Žymių nėra"
+
+#: ..\..\..\templates\sidebar.block.recent.php:15
+msgid "Recent Tags"
+msgstr "Naujos gairÄ—s"
+
+#: ..\..\..\templates\sidebar.block.related.php:15
+msgid "Related Tags"
+msgstr "SusijÄ™ gairÄ—s"
+
+#: ..\..\..\templates\sidebar.block.watchstatus.php:10
+msgid "Remove from Watchlist"
+msgstr "PaÅ¡alinti iÅ¡ biÄiulių sÄ…raÅ¡o"
+
+#: ..\..\..\templates\sidebar.block.watchstatus.php:12
+msgid "Add to Watchlist"
+msgstr "Ä®traukti į biÄiulių sÄ…raÅ¡Ä…"
+
+#: ..\..\..\templates\sidebar.block.watchstatus.php:17
+msgid "Actions"
+msgstr "Veiksmai"
+
+#: ..\..\..\templates\tags.tpl.php:8
+msgid "Alphabet"
+msgstr "AbÄ—cÄ—lÄ—"
+
+#: ..\..\..\templates\tags.tpl.php:9
+msgid "Popularity"
+msgstr "Populiarumas"
+
+#: ..\..\..\templates\toolbar.inc.php:11
+msgid "Bookmarks"
+msgstr "Žymės"
+
+#: ..\..\..\templates\toolbar.inc.php:16
+msgid "Log Out"
+msgstr "Atsijungti"
+
diff --git a/locales/messages.po b/locales/messages.po
new file mode 100644
index 0000000..1d9c8ca
--- /dev/null
+++ b/locales/messages.po
@@ -0,0 +1,825 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2006-03-18 21:39-0800\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
+
+#: ..\..\..\about.php:25 ..\..\..\templates\toolbar.inc.php:24
+msgid "About"
+msgstr ""
+
+#: ..\..\..\ajaxDelete.php:29
+msgid "You are not allowed to delete this bookmark"
+msgstr ""
+
+#: ..\..\..\ajaxDelete.php:33
+msgid "Failed to delete bookmark"
+msgstr ""
+
+#: ..\..\..\alltags.php:50
+msgid "All Tags"
+msgstr ""
+
+#: ..\..\..\alltags.php:59 ..\..\..\populartags.php:63 ..\..\..\profile.php:46
+#: ..\..\..\rss.php:55 ..\..\..\search.php:61 ..\..\..\watch.php:35
+#: ..\..\..\watched.php:62
+#, php-format
+msgid "User with username %s not was not found"
+msgstr ""
+
+#: ..\..\..\bookmarks.php:71
+#, php-format
+msgid "User with username %s was not found"
+msgstr ""
+
+#: ..\..\..\bookmarks.php:94 ..\..\..\edit.php:44
+msgid "Your bookmark must have a title and an address"
+msgstr ""
+
+#: ..\..\..\bookmarks.php:114 ..\..\..\edit.php:58
+msgid "Bookmark saved"
+msgstr ""
+
+#: ..\..\..\bookmarks.php:122 ..\..\..\import.php:99
+#: ..\..\..\importNetscape.php:74
+msgid ""
+"There was an error saving your bookmark. Please try again or contact the "
+"administrator."
+msgstr ""
+
+#: ..\..\..\bookmarks.php:160 ..\..\..\templates\toolbar.inc.php:13
+msgid "Add a Bookmark"
+msgstr ""
+
+#: ..\..\..\bookmarks.php:163
+msgid "Add Bookmark"
+msgstr ""
+
+#: ..\..\..\bookmarks.php:166
+msgid "You must be logged in before you can add bookmarks."
+msgstr ""
+
+#: ..\..\..\bookmarks.php:213
+msgid "My Bookmarks"
+msgstr ""
+
+#: ..\..\..\edit.php:29
+msgid "Edit Bookmark"
+msgstr ""
+
+#: ..\..\..\edit.php:34
+#, php-format
+msgid "Bookmark with id %s not was not found"
+msgstr ""
+
+#: ..\..\..\edit.php:39
+msgid "You are not allowed to edit this bookmark"
+msgstr ""
+
+#: ..\..\..\edit.php:55
+msgid "Error while saving your bookmark"
+msgstr ""
+
+#: ..\..\..\edit.php:78
+msgid "Failed to delete the bookmark"
+msgstr ""
+
+#: ..\..\..\edit.php:88 ..\..\..\templates\editprofile.tpl.php:52
+msgid "Save Changes"
+msgstr ""
+
+#: ..\..\..\functions.inc.php:92
+msgid "message_die() was called multiple times."
+msgstr ""
+
+#: ..\..\..\functions.inc.php:104
+msgid "SQL Error"
+msgstr ""
+
+#: ..\..\..\functions.inc.php:110
+msgid "Line"
+msgstr ""
+
+#: ..\..\..\functions.inc.php:110 ..\..\..\templates\importDelicious.tpl.php:8
+#: ..\..\..\templates\importNetscape.tpl.php:9
+msgid "File"
+msgstr ""
+
+#: ..\..\..\functions.inc.php:116
+msgid "Information"
+msgstr ""
+
+#: ..\..\..\functions.inc.php:121
+msgid "Critical Information"
+msgstr ""
+
+#: ..\..\..\functions.inc.php:126
+msgid "An error occured"
+msgstr ""
+
+#: ..\..\..\functions.inc.php:129
+msgid "General Error"
+msgstr ""
+
+#: ..\..\..\functions.inc.php:137
+msgid "An critical error occured"
+msgstr ""
+
+#: ..\..\..\functions.inc.php:140
+msgid "Critical Error"
+msgstr ""
+
+#: ..\..\..\functions.inc.php:149
+msgid "DEBUG MODE"
+msgstr ""
+
+#: ..\..\..\history.php:65
+msgid "History"
+msgstr ""
+
+#: ..\..\..\history.php:66
+#, php-format
+msgid "History for %s"
+msgstr ""
+
+#: ..\..\..\history.php:81
+msgid "Address was not found"
+msgstr ""
+
+#: ..\..\..\import.php:41
+msgid "Could not open XML input"
+msgstr ""
+
+#: ..\..\..\import.php:45
+#, php-format
+msgid "XML error: %s at line %d"
+msgstr ""
+
+#: ..\..\..\import.php:54
+msgid "Import Bookmarks from del.icio.us"
+msgstr ""
+
+#: ..\..\..\import.php:86 ..\..\..\importNetscape.php:64
+msgid "You have already submitted this bookmark."
+msgstr ""
+
+#: ..\..\..\import.php:97 ..\..\..\importNetscape.php:72
+msgid "Bookmark imported."
+msgstr ""
+
+#: ..\..\..\importNetscape.php:81
+msgid "Import Bookmarks from Browser File"
+msgstr ""
+
+#: ..\..\..\index.php:32
+msgid "You have now logged out"
+msgstr ""
+
+#: ..\..\..\index.php:39
+#, php-format
+msgid "%s: Recent bookmarks"
+msgstr ""
+
+#: ..\..\..\index.php:72
+msgid "Store, share and tag your favourite links"
+msgstr ""
+
+#: ..\..\..\index.php:73
+msgid "Recent Bookmarks"
+msgstr ""
+
+#: ..\..\..\jsScuttle.php:22
+msgid "Are you sure?"
+msgstr ""
+
+#: ..\..\..\jsScuttle.php:22
+msgid "Yes"
+msgstr ""
+
+#: ..\..\..\jsScuttle.php:22
+msgid "No"
+msgstr ""
+
+#: ..\..\..\jsScuttle.php:68
+msgid "Available"
+msgstr ""
+
+#: ..\..\..\jsScuttle.php:71
+msgid "Not Available"
+msgstr ""
+
+#: ..\..\..\login.php:38
+msgid "The details you have entered are incorrect. Please try again."
+msgstr ""
+
+#: ..\..\..\login.php:48 ..\..\..\templates\login.tpl.php:26
+#: ..\..\..\templates\toolbar.inc.php:28
+msgid "Log In"
+msgstr ""
+
+#: ..\..\..\password.php:31
+msgid "You must enter your username."
+msgstr ""
+
+#: ..\..\..\password.php:35
+msgid ""
+"You must enter your <abbr title=\"electronic mail\">e-mail</abbr> address."
+msgstr ""
+
+#: ..\..\..\password.php:42
+msgid "No matches found for that username."
+msgstr ""
+
+#: ..\..\..\password.php:45
+msgid ""
+"No matches found for that combination of username and <abbr title="
+"\"electronic mail\">e-mail</abbr> address."
+msgstr ""
+
+#: ..\..\..\password.php:53
+msgid ""
+"There was an error while generating your new password. Please try again."
+msgstr ""
+
+#: ..\..\..\password.php:57
+msgid "Your new password is:"
+msgstr ""
+
+#: ..\..\..\password.php:57
+msgid ""
+"To keep your bookmarks secure, you should change this password in your "
+"profile the next time you log in."
+msgstr ""
+
+#: ..\..\..\password.php:60
+#, php-format
+msgid "%s Account Information"
+msgstr ""
+
+#: ..\..\..\password.php:62
+#, php-format
+msgid "New password generated and sent to %s"
+msgstr ""
+
+#: ..\..\..\password.php:69
+msgid "Forgotten Password"
+msgstr ""
+
+#: ..\..\..\populartags.php:54 ..\..\..\templates\dynamictags.inc.php:101
+#: ..\..\..\templates\sidebar.block.common.php:9
+#: ..\..\..\templates\sidebar.block.popular.php:15
+#: ..\..\..\templates\sidebar.block.recent.php:25
+msgid "Popular Tags"
+msgstr ""
+
+#: ..\..\..\profile.php:54 ..\..\..\watched.php:114
+msgid "Username was not specified"
+msgstr ""
+
+#: ..\..\..\profile.php:60
+msgid "My Profile"
+msgstr ""
+
+#: ..\..\..\profile.php:62 ..\..\..\templates\sidebar.block.profile.php:12
+msgid "Profile"
+msgstr ""
+
+#: ..\..\..\profile.php:80
+msgid "Password and confirmation do not match."
+msgstr ""
+
+#: ..\..\..\profile.php:84
+msgid "Password must be at least 6 characters long."
+msgstr ""
+
+#: ..\..\..\profile.php:88
+msgid "E-mail address is not valid."
+msgstr ""
+
+#: ..\..\..\profile.php:92
+msgid "An error occurred while saving your changes."
+msgstr ""
+
+#: ..\..\..\profile.php:94
+msgid "Changes saved."
+msgstr ""
+
+#: ..\..\..\register.php:33
+msgid "You <em>must</em> enter a username, password and e-mail address."
+msgstr ""
+
+#: ..\..\..\register.php:37
+msgid "This username already exists, please make another choice."
+msgstr ""
+
+#: ..\..\..\register.php:41
+msgid "E-mail address is not valid. Please try again."
+msgstr ""
+
+#: ..\..\..\register.php:50
+msgid "You have successfully registered. Enjoy!"
+msgstr ""
+
+#: ..\..\..\register.php:52
+msgid "Registration failed. Please try again."
+msgstr ""
+
+#: ..\..\..\register.php:57 ..\..\..\templates\register.tpl.php:32
+#: ..\..\..\templates\toolbar.inc.php:27
+msgid "Register"
+msgstr ""
+
+#: ..\..\..\search.inc.php:29 ..\..\..\search.inc.php:57
+msgid "Search"
+msgstr ""
+
+#: ..\..\..\search.inc.php:35
+msgid "this user's bookmarks"
+msgstr ""
+
+#: ..\..\..\search.inc.php:40
+msgid "my bookmarks"
+msgstr ""
+
+#: ..\..\..\search.inc.php:41
+msgid "my watchlist"
+msgstr ""
+
+#: ..\..\..\search.inc.php:45
+msgid "all bookmarks"
+msgstr ""
+
+#: ..\..\..\search.inc.php:48
+msgid "for"
+msgstr ""
+
+#: ..\..\..\search.php:91 ..\..\..\search.php:128
+msgid "Search Bookmarks"
+msgstr ""
+
+#: ..\..\..\search.php:97
+msgid "Search Results"
+msgstr ""
+
+#: ..\..\..\tags.php:38 ..\..\..\templates\editbookmark.tpl.php:44
+#: ..\..\..\templates\sidebar.block.profile.php:13
+msgid "Tags"
+msgstr ""
+
+#: ..\..\..\watch.php:79
+#, php-format
+msgid "%s Bookmarks"
+msgstr ""
+
+#: ..\..\..\watch.php:84
+msgid "User removed from your watchlist"
+msgstr ""
+
+#: ..\..\..\watch.php:86
+msgid "User added to your watchlist"
+msgstr ""
+
+#: ..\..\..\watched.php:105
+msgid "My Watchlist"
+msgstr ""
+
+#: ..\..\..\watched.php:107 ..\..\..\templates\sidebar.block.profile.php:14
+#: ..\..\..\templates\toolbar.inc.php:12
+msgid "Watchlist"
+msgstr ""
+
+#: ..\..\..\templates\about.tpl.php:6
+msgid ""
+"<strong>Store</strong> all your favourite links in one place, accessible "
+"from anywhere."
+msgstr ""
+
+#: ..\..\..\templates\about.tpl.php:7
+msgid ""
+"<strong>Share</strong> your bookmarks with everyone, with friends on your "
+"watchlist or just keep them private."
+msgstr ""
+
+#: ..\..\..\templates\about.tpl.php:8
+msgid ""
+"<strong>Tag</strong> your bookmarks with as many labels as you want, instead "
+"of wrestling with folders."
+msgstr ""
+
+#: ..\..\..\templates\about.tpl.php:9
+#, php-format
+msgid ""
+"<strong><a href=\"register.php\">Register now</a></strong> to start using %s!"
+msgstr ""
+
+#: ..\..\..\templates\about.tpl.php:12
+msgid "Geek Stuff"
+msgstr ""
+
+#: ..\..\..\templates\about.tpl.php:14
+#, php-format
+msgid ""
+"%s is based on <a href=\"http://sourceforge.net/projects/scuttle/\">an open-"
+"source project</a> licensed under the <a href=\"http://www.gnu.org/copyleft/"
+"gpl.html\"><acronym title=\"GNU's Not Unix\">GNU</acronym> General Public "
+"License</a>. This means you can host it on your own web server for free, "
+"whether it is on the Internet, a private network or just your own computer."
+msgstr ""
+
+#: ..\..\..\templates\about.tpl.php:15
+#, php-format
+msgid ""
+"%1$s supports most of the <a href=\"http://del.icio.us/doc/api\">del.icio.us "
+"<abbr title=\"Application Programming Interface\">API</abbr></a>. Almost all "
+"of the neat tools made for that system can be modified to work with %1$s "
+"instead. If you find a tool that won't let you change the API address, ask "
+"the creator to add this setting. You never know, they might just do it."
+msgstr ""
+
+#: ..\..\..\templates\bookmarks.tpl.php:17 ..\..\..\templates\tags.tpl.php:7
+msgid "Sort by:"
+msgstr ""
+
+#: ..\..\..\templates\bookmarks.tpl.php:18
+msgid "Date"
+msgstr ""
+
+#: ..\..\..\templates\bookmarks.tpl.php:19
+#: ..\..\..\templates\editbookmark.tpl.php:34
+msgid "Title"
+msgstr ""
+
+#: ..\..\..\templates\bookmarks.tpl.php:23
+msgid "URL"
+msgstr ""
+
+#: ..\..\..\templates\bookmarks.tpl.php:60
+msgid "Edit"
+msgstr ""
+
+#: ..\..\..\templates\bookmarks.tpl.php:60
+msgid "Delete"
+msgstr ""
+
+#: ..\..\..\templates\bookmarks.tpl.php:66
+msgid "by"
+msgstr ""
+
+#: ..\..\..\templates\bookmarks.tpl.php:78
+#, php-format
+msgid " and %s1 other%s"
+msgstr ""
+
+#: ..\..\..\templates\bookmarks.tpl.php:81
+#, php-format
+msgid " and %2$s%1$s others%3$s"
+msgstr ""
+
+#: ..\..\..\templates\bookmarks.tpl.php:90
+msgid "Copy"
+msgstr ""
+
+#: ..\..\..\templates\bookmarks.tpl.php:136
+#: ..\..\..\templates\bookmarks.tpl.php:142
+msgid "First"
+msgstr ""
+
+#: ..\..\..\templates\bookmarks.tpl.php:137
+#: ..\..\..\templates\bookmarks.tpl.php:143
+msgid "Previous"
+msgstr ""
+
+#: ..\..\..\templates\bookmarks.tpl.php:150
+#: ..\..\..\templates\bookmarks.tpl.php:153
+msgid "Next"
+msgstr ""
+
+#: ..\..\..\templates\bookmarks.tpl.php:151
+#: ..\..\..\templates\bookmarks.tpl.php:154
+msgid "Last"
+msgstr ""
+
+#: ..\..\..\templates\bookmarks.tpl.php:156
+#, php-format
+msgid "Page %d of %d"
+msgstr ""
+
+#: ..\..\..\templates\bookmarks.tpl.php:160
+msgid "No bookmarks available"
+msgstr ""
+
+#: ..\..\..\templates\dynamictags.inc.php:108
+#: ..\..\..\templates\sidebar.block.common.php:15
+#: ..\..\..\templates\sidebar.block.popular.php:21
+#: ..\..\..\templates\sidebar.block.recent.php:20
+#: ..\..\..\templates\tags.tpl.php:16
+msgid "bookmark"
+msgid_plural "bookmarks"
+msgstr[0] ""
+msgstr[1] ""
+
+#: ..\..\..\templates\editbookmark.tpl.php:29
+msgid "Address"
+msgstr ""
+
+#: ..\..\..\templates\editbookmark.tpl.php:31
+#: ..\..\..\templates\editbookmark.tpl.php:36
+#: ..\..\..\templates\editprofile.tpl.php:31
+msgid "Required"
+msgstr ""
+
+#: ..\..\..\templates\editbookmark.tpl.php:39
+#: ..\..\..\templates\editprofile.tpl.php:47
+#: ..\..\..\templates\profile.tpl.php:28
+msgid "Description"
+msgstr ""
+
+#: ..\..\..\templates\editbookmark.tpl.php:46
+msgid "Comma-separated"
+msgstr ""
+
+#: ..\..\..\templates\editbookmark.tpl.php:49
+#: ..\..\..\templates\importDelicious.tpl.php:15
+#: ..\..\..\templates\importNetscape.tpl.php:16
+msgid "Privacy"
+msgstr ""
+
+#: ..\..\..\templates\editbookmark.tpl.php:52
+#: ..\..\..\templates\importDelicious.tpl.php:18
+#: ..\..\..\templates\importNetscape.tpl.php:19
+msgid "Public"
+msgstr ""
+
+#: ..\..\..\templates\editbookmark.tpl.php:53
+#: ..\..\..\templates\importDelicious.tpl.php:19
+#: ..\..\..\templates\importNetscape.tpl.php:20
+msgid "Shared with Watch List"
+msgstr ""
+
+#: ..\..\..\templates\editbookmark.tpl.php:54
+#: ..\..\..\templates\importDelicious.tpl.php:20
+#: ..\..\..\templates\importNetscape.tpl.php:21
+msgid "Private"
+msgstr ""
+
+#: ..\..\..\templates\editbookmark.tpl.php:66
+msgid "Delete Bookmark"
+msgstr ""
+
+#: ..\..\..\templates\editbookmark.tpl.php:93
+msgid "Bookmarklet"
+msgstr ""
+
+#: ..\..\..\templates\editbookmark.tpl.php:94
+#, php-format
+msgid ""
+"Drag one of the following bookmarklets to your browser's bookmarks and click "
+"it whenever you want to add the page you are on to %s"
+msgstr ""
+
+#: ..\..\..\templates\editbookmark.tpl.php:106
+#, php-format
+msgid "Post to %s"
+msgstr ""
+
+#: ..\..\..\templates\editbookmark.tpl.php:107
+#, php-format
+msgid "Post to %s (Pop-up)"
+msgstr ""
+
+#: ..\..\..\templates\editbookmark.tpl.php:111
+#: ..\..\..\templates\importDelicious.tpl.php:26
+#: ..\..\..\templates\importNetscape.tpl.php:27
+msgid "Import"
+msgstr ""
+
+#: ..\..\..\templates\editbookmark.tpl.php:113
+msgid "Import bookmarks from bookmark file"
+msgstr ""
+
+#: ..\..\..\templates\editbookmark.tpl.php:113
+msgid "Internet Explorer, Mozilla Firefox and Netscape"
+msgstr ""
+
+#: ..\..\..\templates\editbookmark.tpl.php:114
+msgid "Import bookmarks from del.icio.us"
+msgstr ""
+
+#: ..\..\..\templates\editprofile.tpl.php:10
+msgid "Account Details"
+msgstr ""
+
+#: ..\..\..\templates\editprofile.tpl.php:14
+#: ..\..\..\templates\login.tpl.php:15 ..\..\..\templates\password.tpl.php:10
+#: ..\..\..\templates\profile.tpl.php:7 ..\..\..\templates\register.tpl.php:16
+msgid "Username"
+msgstr ""
+
+#: ..\..\..\templates\editprofile.tpl.php:19
+msgid "New Password"
+msgstr ""
+
+#: ..\..\..\templates\editprofile.tpl.php:24
+msgid "Confirm Password"
+msgstr ""
+
+#: ..\..\..\templates\editprofile.tpl.php:29
+#: ..\..\..\templates\register.tpl.php:26
+msgid "E-mail"
+msgstr ""
+
+#: ..\..\..\templates\editprofile.tpl.php:35
+msgid "Personal Details"
+msgstr ""
+
+#: ..\..\..\templates\editprofile.tpl.php:39
+#: ..\..\..\templates\profile.tpl.php:12
+msgid "Name"
+msgstr ""
+
+#: ..\..\..\templates\editprofile.tpl.php:43
+#: ..\..\..\templates\profile.tpl.php:18
+msgid "Homepage"
+msgstr ""
+
+#: ..\..\..\templates\error.404.tpl.php:5
+msgid "Not Found"
+msgstr ""
+
+#: ..\..\..\templates\error.404.tpl.php:6
+msgid "The requested URL was not found on this server"
+msgstr ""
+
+#: ..\..\..\templates\error.500.tpl.php:5
+msgid "General server error"
+msgstr ""
+
+#: ..\..\..\templates\error.500.tpl.php:6
+msgid "The requested URL could not be processed"
+msgstr ""
+
+#: ..\..\..\templates\importDelicious.tpl.php:33
+msgid ""
+"Log in to the <a href=\"http://del.icio.us/api/posts/all\">export page at "
+"del.icio.us</a>"
+msgstr ""
+
+#: ..\..\..\templates\importDelicious.tpl.php:34
+msgid ""
+"Save the resulting <abbr title=\"Extensible Markup Language\">XML</abbr> "
+"file to your computer"
+msgstr ""
+
+#: ..\..\..\templates\importDelicious.tpl.php:35
+msgid ""
+"Click <kbd>Browse...</kbd> to find this file on your computer. The maximum "
+"size the file can be is 1MB"
+msgstr ""
+
+#: ..\..\..\templates\importDelicious.tpl.php:36
+#: ..\..\..\templates\importNetscape.tpl.php:43
+msgid "Select the default privacy setting for your imported bookmarks"
+msgstr ""
+
+#: ..\..\..\templates\importDelicious.tpl.php:37
+#: ..\..\..\templates\importNetscape.tpl.php:44
+msgid ""
+"Click <kbd>Import</kbd> to start importing the bookmarks; it may take a "
+"minute"
+msgstr ""
+
+#: ..\..\..\templates\importNetscape.tpl.php:32
+msgid "Instructions"
+msgstr ""
+
+#: ..\..\..\templates\importNetscape.tpl.php:35
+msgid "Export your bookmarks from your browser to a file"
+msgstr ""
+
+#: ..\..\..\templates\importNetscape.tpl.php:37
+msgid ""
+"Internet Explorer: <kbd>File &gt; Import and Export... &gt; Export Favorites"
+msgstr ""
+
+#: ..\..\..\templates\importNetscape.tpl.php:38
+msgid ""
+"Mozilla Firefox: <kbd>Bookmarks &gt; Manage Bookmarks... &gt; File &gt; "
+"Export..."
+msgstr ""
+
+#: ..\..\..\templates\importNetscape.tpl.php:39
+msgid ""
+"Netscape: <kbd>Bookmarks &gt; Manage Bookmarks... &gt; Tools &gt; Export..."
+msgstr ""
+
+#: ..\..\..\templates\importNetscape.tpl.php:42
+msgid ""
+"Click <kbd>Browse...</kbd> to find the saved bookmark file on your computer. "
+"The maximum size the file can be is 1MB"
+msgstr ""
+
+#: ..\..\..\templates\login.tpl.php:20 ..\..\..\templates\register.tpl.php:21
+msgid "Password"
+msgstr ""
+
+#: ..\..\..\templates\login.tpl.php:22
+msgid "Don't ask for my password for 2 weeks"
+msgstr ""
+
+#: ..\..\..\templates\login.tpl.php:30
+msgid "Forgotten your password?"
+msgstr ""
+
+#: ..\..\..\templates\password.tpl.php:5
+#, php-format
+msgid ""
+"If you have forgotten your password, %s can generate a new one. Enter the "
+"username and e-mail address of your account into the form below and we will "
+"e-mail your new password to you."
+msgstr ""
+
+#: ..\..\..\templates\password.tpl.php:14
+msgid "<abbr title=\"Electronic mail\">E-mail</abbr>"
+msgstr ""
+
+#: ..\..\..\templates\password.tpl.php:19
+msgid "Generate Password"
+msgstr ""
+
+#: ..\..\..\templates\profile.tpl.php:23
+msgid "Member Since"
+msgstr ""
+
+#: ..\..\..\templates\profile.tpl.php:35
+#: ..\..\..\templates\sidebar.block.watchlist.php:8
+msgid "Watching"
+msgstr ""
+
+#: ..\..\..\templates\profile.tpl.php:50
+msgid "Watched By"
+msgstr ""
+
+#: ..\..\..\templates\register.tpl.php:11
+#, php-format
+msgid ""
+"Sign up here to create a free %s account. All the information requested "
+"below is required"
+msgstr ""
+
+#: ..\..\..\templates\rss.tpl.php:9
+#, php-format
+msgid "Recent bookmarks posted to %s"
+msgstr ""
+
+#: ..\..\..\templates\rss.tpl.php:17 ..\..\..\templates\rss.tpl.php:19
+msgid "No bookmarks found"
+msgstr ""
+
+#: ..\..\..\templates\sidebar.block.recent.php:15
+msgid "Recent Tags"
+msgstr ""
+
+#: ..\..\..\templates\sidebar.block.related.php:15
+msgid "Related Tags"
+msgstr ""
+
+#: ..\..\..\templates\sidebar.block.watchstatus.php:10
+msgid "Remove from Watchlist"
+msgstr ""
+
+#: ..\..\..\templates\sidebar.block.watchstatus.php:12
+msgid "Add to Watchlist"
+msgstr ""
+
+#: ..\..\..\templates\sidebar.block.watchstatus.php:17
+msgid "Actions"
+msgstr ""
+
+#: ..\..\..\templates\tags.tpl.php:8
+msgid "Alphabet"
+msgstr ""
+
+#: ..\..\..\templates\tags.tpl.php:9
+msgid "Popularity"
+msgstr ""
+
+#: ..\..\..\templates\toolbar.inc.php:11
+msgid "Bookmarks"
+msgstr ""
+
+#: ..\..\..\templates\toolbar.inc.php:16
+msgid "Log Out"
+msgstr ""
diff --git a/locales/nl_NL/LC_MESSAGES/messages.mo b/locales/nl_NL/LC_MESSAGES/messages.mo
new file mode 100644
index 0000000..b4b617c
--- /dev/null
+++ b/locales/nl_NL/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/locales/nl_NL/LC_MESSAGES/messages.po b/locales/nl_NL/LC_MESSAGES/messages.po
new file mode 100644
index 0000000..1dd6526
--- /dev/null
+++ b/locales/nl_NL/LC_MESSAGES/messages.po
@@ -0,0 +1,851 @@
+# Scuttle nl-NL Translation
+# Copyright (C) 2005 - 2006 Scuttle project
+# This file is distributed under the same license as the Scuttle package.
+# <alley@ilikeu2.nl>
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: scuttle\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2005-04-29 11:17+0200\n"
+"PO-Revision-Date: 2006-03-18 21:46-0800\n"
+"Last-Translator: Marcus Campbell <marcus.campbell@gmail.com>\n"
+"Language-Team: nl-NL <alley@ilikeu2.nl>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-Language: Dutch\n"
+"X-Poedit-Country: NETHERLANDS\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: ..\..\..\about.php:25
+#: ..\..\..\templates\toolbar.inc.php:24
+msgid "About"
+msgstr "Over ons"
+
+#: ..\..\..\ajaxDelete.php:29
+#, fuzzy
+msgid "You are not allowed to delete this bookmark"
+msgstr "De bookmark kon niet worden verwijderd"
+
+#: ..\..\..\ajaxDelete.php:33
+#, fuzzy
+msgid "Failed to delete bookmark"
+msgstr "Bookmark Verwijderen"
+
+#: ..\..\..\alltags.php:50
+msgid "All Tags"
+msgstr "Alle tags"
+
+#: ..\..\..\alltags.php:59
+#: ..\..\..\populartags.php:63
+#: ..\..\..\profile.php:46
+#: ..\..\..\rss.php:55
+#: ..\..\..\search.php:61
+#: ..\..\..\watch.php:35
+#: ..\..\..\watched.php:62
+#, php-format
+msgid "User with username %s not was not found"
+msgstr ""
+
+#: ..\..\..\bookmarks.php:71
+#, fuzzy, php-format
+msgid "User with username %s was not found"
+msgstr "Bookmark werd niet gevonden"
+
+#: ..\..\..\bookmarks.php:94
+#: ..\..\..\edit.php:44
+msgid "Your bookmark must have a title and an address"
+msgstr "Je bookmarks moeten een titel en adres hebben"
+
+#: ..\..\..\bookmarks.php:114
+#: ..\..\..\edit.php:58
+msgid "Bookmark saved"
+msgstr "Bookmark opgeslagen"
+
+#: ..\..\..\bookmarks.php:122
+#: ..\..\..\import.php:99
+#: ..\..\..\importNetscape.php:74
+msgid "There was an error saving your bookmark. Please try again or contact the administrator."
+msgstr ""
+
+#: ..\..\..\bookmarks.php:160
+#: ..\..\..\templates\toolbar.inc.php:13
+msgid "Add a Bookmark"
+msgstr "Voeg een bookmark toe"
+
+#: ..\..\..\bookmarks.php:163
+msgid "Add Bookmark"
+msgstr "Bookmark toevoegen"
+
+#: ..\..\..\bookmarks.php:166
+msgid "You must be logged in before you can add bookmarks."
+msgstr "Je moet ingelogd zijn om bookmarks toe te kunnen voegen"
+
+#: ..\..\..\bookmarks.php:213
+#, fuzzy
+msgid "My Bookmarks"
+msgstr "%s Bookmarks"
+
+#: ..\..\..\edit.php:29
+msgid "Edit Bookmark"
+msgstr "Bookmark Bewerken"
+
+#: ..\..\..\edit.php:34
+#, fuzzy, php-format
+msgid "Bookmark with id %s not was not found"
+msgstr "Bookmark werd niet gevonden"
+
+#: ..\..\..\edit.php:39
+#, fuzzy
+msgid "You are not allowed to edit this bookmark"
+msgstr "De bookmark kon niet worden verwijderd"
+
+#: ..\..\..\edit.php:55
+msgid "Error while saving your bookmark"
+msgstr ""
+
+#: ..\..\..\edit.php:78
+#, fuzzy
+msgid "Failed to delete the bookmark"
+msgstr "De bookmark kon niet worden verwijderd"
+
+#: ..\..\..\edit.php:88
+#: ..\..\..\templates\editprofile.tpl.php:52
+msgid "Save Changes"
+msgstr "Veranderingen opslaan"
+
+#: ..\..\..\functions.inc.php:92
+msgid "message_die() was called multiple times."
+msgstr ""
+
+#: ..\..\..\functions.inc.php:104
+msgid "SQL Error"
+msgstr ""
+
+#: ..\..\..\functions.inc.php:110
+msgid "Line"
+msgstr ""
+
+#: ..\..\..\functions.inc.php:110
+#: ..\..\..\templates\importDelicious.tpl.php:8
+#: ..\..\..\templates\importNetscape.tpl.php:9
+msgid "File"
+msgstr "Bestand"
+
+#: ..\..\..\functions.inc.php:116
+#, fuzzy
+msgid "Information"
+msgstr "Instructies"
+
+#: ..\..\..\functions.inc.php:121
+msgid "Critical Information"
+msgstr ""
+
+#: ..\..\..\functions.inc.php:126
+msgid "An error occured"
+msgstr ""
+
+#: ..\..\..\functions.inc.php:129
+msgid "General Error"
+msgstr ""
+
+#: ..\..\..\functions.inc.php:137
+msgid "An critical error occured"
+msgstr ""
+
+#: ..\..\..\functions.inc.php:140
+msgid "Critical Error"
+msgstr ""
+
+#: ..\..\..\functions.inc.php:149
+msgid "DEBUG MODE"
+msgstr ""
+
+#: ..\..\..\history.php:65
+msgid "History"
+msgstr ""
+
+#: ..\..\..\history.php:66
+#, php-format
+msgid "History for %s"
+msgstr ""
+
+#: ..\..\..\history.php:81
+msgid "Address was not found"
+msgstr ""
+
+#: ..\..\..\import.php:41
+msgid "Could not open XML input"
+msgstr "XML bestand kon niet geopend worden"
+
+#: ..\..\..\import.php:45
+#, php-format
+msgid "XML error: %s at line %d"
+msgstr "XML fout: %s op regel %d"
+
+#: ..\..\..\import.php:54
+#, fuzzy
+msgid "Import Bookmarks from del.icio.us"
+msgstr "Importeer van del.icio.us"
+
+#: ..\..\..\import.php:86
+#: ..\..\..\importNetscape.php:64
+#, fuzzy
+msgid "You have already submitted this bookmark."
+msgstr "Je hebt deze bookmark al opgenomen"
+
+#: ..\..\..\import.php:97
+#: ..\..\..\importNetscape.php:72
+#, fuzzy
+msgid "Bookmark imported."
+msgstr "Bookmark opgeslagen"
+
+#: ..\..\..\importNetscape.php:81
+#, fuzzy
+msgid "Import Bookmarks from Browser File"
+msgstr "Importeer bookmarks uit een bookmark bestand"
+
+#: ..\..\..\index.php:32
+msgid "You have now logged out"
+msgstr "Je bent uitgelogd"
+
+#: ..\..\..\index.php:39
+#, php-format
+msgid "%s: Recent bookmarks"
+msgstr "%s: Recente bookmarks"
+
+#: ..\..\..\index.php:72
+msgid "Store, share and tag your favourite links"
+msgstr ""
+
+#: ..\..\..\index.php:73
+msgid "Recent Bookmarks"
+msgstr "Recente bookmarks"
+
+#: ..\..\..\jsScuttle.php:22
+msgid "Are you sure?"
+msgstr ""
+
+#: ..\..\..\jsScuttle.php:22
+msgid "Yes"
+msgstr ""
+
+#: ..\..\..\jsScuttle.php:22
+msgid "No"
+msgstr ""
+
+#: ..\..\..\jsScuttle.php:68
+msgid "Available"
+msgstr ""
+
+#: ..\..\..\jsScuttle.php:71
+#, fuzzy
+msgid "Not Available"
+msgstr "Geen bookmarks beschikbaar"
+
+#: ..\..\..\login.php:38
+#, fuzzy
+msgid "The details you have entered are incorrect. Please try again."
+msgstr "De ingevoerde details zijn niet correct. Probeer het nog eens."
+
+#: ..\..\..\login.php:48
+#: ..\..\..\templates\login.tpl.php:26
+#: ..\..\..\templates\toolbar.inc.php:28
+msgid "Log In"
+msgstr "Inloggen"
+
+#: ..\..\..\password.php:31
+msgid "You must enter your username."
+msgstr ""
+
+#: ..\..\..\password.php:35
+#, fuzzy
+msgid "You must enter your <abbr title=\"electronic mail\">e-mail</abbr> address."
+msgstr "Een gebruikersnaam, wachtwoord, naam en <abbr title=\"Electronic mail\">email</abbr> adres <em>moeten</em> worden opgegeven"
+
+#: ..\..\..\password.php:42
+msgid "No matches found for that username."
+msgstr ""
+
+#: ..\..\..\password.php:45
+#, fuzzy
+msgid "No matches found for that combination of username and <abbr title=\"electronic mail\">e-mail</abbr> address."
+msgstr "Een gebruikersnaam, wachtwoord, naam en <abbr title=\"Electronic mail\">email</abbr> adres <em>moeten</em> worden opgegeven"
+
+#: ..\..\..\password.php:53
+#, fuzzy
+msgid "There was an error while generating your new password. Please try again."
+msgstr "De ingevoerde details zijn niet correct. Probeer het nog eens."
+
+#: ..\..\..\password.php:57
+#, fuzzy
+msgid "Your new password is:"
+msgstr "Bevestiging nieuw wachtwoord"
+
+#: ..\..\..\password.php:57
+msgid "To keep your bookmarks secure, you should change this password in your profile the next time you log in."
+msgstr ""
+
+#: ..\..\..\password.php:60
+#, fuzzy, php-format
+msgid "%s Account Information"
+msgstr "Instructies"
+
+#: ..\..\..\password.php:62
+#, php-format
+msgid "New password generated and sent to %s"
+msgstr ""
+
+#: ..\..\..\password.php:69
+#, fuzzy
+msgid "Forgotten Password"
+msgstr "Nieuw wachtwoord"
+
+#: ..\..\..\populartags.php:54
+#: ..\..\..\templates\dynamictags.inc.php:101
+#: ..\..\..\templates\sidebar.block.common.php:9
+#: ..\..\..\templates\sidebar.block.popular.php:15
+#: ..\..\..\templates\sidebar.block.recent.php:25
+msgid "Popular Tags"
+msgstr "Populaire Tags"
+
+#: ..\..\..\profile.php:54
+#: ..\..\..\watched.php:114
+msgid "Username was not specified"
+msgstr ""
+
+#: ..\..\..\profile.php:60
+#, fuzzy
+msgid "My Profile"
+msgstr "Profiel"
+
+#: ..\..\..\profile.php:62
+#: ..\..\..\templates\sidebar.block.profile.php:12
+msgid "Profile"
+msgstr "Profiel"
+
+#: ..\..\..\profile.php:80
+#, fuzzy
+msgid "Password and confirmation do not match."
+msgstr "Wachtwoord en wachtwoordbevestiging komen niet overen"
+
+#: ..\..\..\profile.php:84
+#, fuzzy
+msgid "Password must be at least 6 characters long."
+msgstr "Wachtwoord dient minimaal 6 karakters lang te zijn"
+
+#: ..\..\..\profile.php:88
+#, fuzzy
+msgid "E-mail address is not valid."
+msgstr "Email adres is ongeldig"
+
+#: ..\..\..\profile.php:92
+msgid "An error occurred while saving your changes."
+msgstr ""
+
+#: ..\..\..\profile.php:94
+#, fuzzy
+msgid "Changes saved."
+msgstr "Wijzigingen opgeslagen"
+
+#: ..\..\..\register.php:33
+#, fuzzy
+msgid "You <em>must</em> enter a username, password and e-mail address."
+msgstr "Een gebruikersnaam, wachtwoord, naam en <abbr title=\"Electronic mail\">email</abbr> adres <em>moeten</em> worden opgegeven"
+
+#: ..\..\..\register.php:37
+msgid "This username already exists, please make another choice."
+msgstr ""
+
+#: ..\..\..\register.php:41
+#, fuzzy
+msgid "E-mail address is not valid. Please try again."
+msgstr "Email adres is ongeldig"
+
+#: ..\..\..\register.php:50
+#, fuzzy
+msgid "You have successfully registered. Enjoy!"
+msgstr "De bookmark is succesvol verwijderd"
+
+#: ..\..\..\register.php:52
+msgid "Registration failed. Please try again."
+msgstr ""
+
+#: ..\..\..\register.php:57
+#: ..\..\..\templates\register.tpl.php:32
+#: ..\..\..\templates\toolbar.inc.php:27
+msgid "Register"
+msgstr ""
+
+#: ..\..\..\search.inc.php:29
+#: ..\..\..\search.inc.php:57
+msgid "Search"
+msgstr ""
+
+#: ..\..\..\search.inc.php:35
+#, fuzzy
+msgid "this user's bookmarks"
+msgstr "%s Bookmarks"
+
+#: ..\..\..\search.inc.php:40
+msgid "my bookmarks"
+msgstr "Mijn bookmarks"
+
+#: ..\..\..\search.inc.php:41
+#, fuzzy
+msgid "my watchlist"
+msgstr "Voeg toe aan 'watch-list'"
+
+#: ..\..\..\search.inc.php:45
+msgid "all bookmarks"
+msgstr "Alle bookmarks"
+
+#: ..\..\..\search.inc.php:48
+msgid "for"
+msgstr "voor"
+
+#: ..\..\..\search.php:91
+#: ..\..\..\search.php:128
+msgid "Search Bookmarks"
+msgstr "Bookmarks zoeken"
+
+#: ..\..\..\search.php:97
+msgid "Search Results"
+msgstr ""
+
+#: ..\..\..\tags.php:38
+#: ..\..\..\templates\editbookmark.tpl.php:44
+#: ..\..\..\templates\sidebar.block.profile.php:13
+msgid "Tags"
+msgstr "Tags"
+
+#: ..\..\..\watch.php:79
+#, php-format
+msgid "%s Bookmarks"
+msgstr "%s Bookmarks"
+
+#: ..\..\..\watch.php:84
+#, fuzzy
+msgid "User removed from your watchlist"
+msgstr "Van 'watch-list' verwijderen"
+
+#: ..\..\..\watch.php:86
+#, fuzzy
+msgid "User added to your watchlist"
+msgstr "Voeg toe aan 'watch-list'"
+
+#: ..\..\..\watched.php:105
+#, fuzzy
+msgid "My Watchlist"
+msgstr "Watch List"
+
+#: ..\..\..\watched.php:107
+#: ..\..\..\templates\sidebar.block.profile.php:14
+#: ..\..\..\templates\toolbar.inc.php:12
+#, fuzzy
+msgid "Watchlist"
+msgstr "Watch List"
+
+#: ..\..\..\templates\about.tpl.php:6
+msgid "<strong>Store</strong> all your favourite links in one place, accessible from anywhere."
+msgstr ""
+
+#: ..\..\..\templates\about.tpl.php:7
+#, fuzzy
+msgid "<strong>Share</strong> your bookmarks with everyone, with friends on your watchlist or just keep them private."
+msgstr "Deel je bookmarks met iedereen, met gebruikers op jouw 'watch-list' of hou ze gewoon voor jezelf"
+
+#: ..\..\..\templates\about.tpl.php:8
+msgid "<strong>Tag</strong> your bookmarks with as many labels as you want, instead of wrestling with folders."
+msgstr ""
+
+#: ..\..\..\templates\about.tpl.php:9
+#, fuzzy, php-format
+msgid "<strong><a href=\"register.php\">Register now</a></strong> to start using %s!"
+msgstr "<a href=\"register.php\">Registreer nu</a> om je eigen bookmarks op te slaan"
+
+#: ..\..\..\templates\about.tpl.php:12
+msgid "Geek Stuff"
+msgstr ""
+
+#: ..\..\..\templates\about.tpl.php:14
+#, php-format
+msgid "%s is based on <a href=\"http://sourceforge.net/projects/scuttle/\">an open-source project</a> licensed under the <a href=\"http://www.gnu.org/copyleft/gpl.html\"><acronym title=\"GNU's Not Unix\">GNU</acronym> General Public License</a>. This means you can host it on your own web server for free, whether it is on the Internet, a private network or just your own computer."
+msgstr ""
+
+#: ..\..\..\templates\about.tpl.php:15
+#, php-format
+msgid "%1$s supports most of the <a href=\"http://del.icio.us/doc/api\">del.icio.us <abbr title=\"Application Programming Interface\">API</abbr></a>. Almost all of the neat tools made for that system can be modified to work with %1$s instead. If you find a tool that won't let you change the API address, ask the creator to add this setting. You never know, they might just do it."
+msgstr ""
+
+#: ..\..\..\templates\bookmarks.tpl.php:17
+#: ..\..\..\templates\tags.tpl.php:7
+msgid "Sort by:"
+msgstr ""
+
+#: ..\..\..\templates\bookmarks.tpl.php:18
+msgid "Date"
+msgstr "Datum"
+
+#: ..\..\..\templates\bookmarks.tpl.php:19
+#: ..\..\..\templates\editbookmark.tpl.php:34
+msgid "Title"
+msgstr "Titel"
+
+#: ..\..\..\templates\bookmarks.tpl.php:23
+msgid "URL"
+msgstr ""
+
+#: ..\..\..\templates\bookmarks.tpl.php:60
+msgid "Edit"
+msgstr "Bewerken"
+
+#: ..\..\..\templates\bookmarks.tpl.php:60
+msgid "Delete"
+msgstr "Verwijderen"
+
+#: ..\..\..\templates\bookmarks.tpl.php:66
+msgid "by"
+msgstr ""
+
+#: ..\..\..\templates\bookmarks.tpl.php:78
+#, php-format
+msgid " and %s1 other%s"
+msgstr ""
+
+#: ..\..\..\templates\bookmarks.tpl.php:81
+#, php-format
+msgid " and %2$s%1$s others%3$s"
+msgstr ""
+
+#: ..\..\..\templates\bookmarks.tpl.php:90
+msgid "Copy"
+msgstr "Kopi&euml;ren"
+
+#: ..\..\..\templates\bookmarks.tpl.php:136
+#: ..\..\..\templates\bookmarks.tpl.php:142
+msgid "First"
+msgstr ""
+
+#: ..\..\..\templates\bookmarks.tpl.php:137
+#: ..\..\..\templates\bookmarks.tpl.php:143
+msgid "Previous"
+msgstr ""
+
+#: ..\..\..\templates\bookmarks.tpl.php:150
+#: ..\..\..\templates\bookmarks.tpl.php:153
+msgid "Next"
+msgstr ""
+
+#: ..\..\..\templates\bookmarks.tpl.php:151
+#: ..\..\..\templates\bookmarks.tpl.php:154
+msgid "Last"
+msgstr ""
+
+#: ..\..\..\templates\bookmarks.tpl.php:156
+#, php-format
+msgid "Page %d of %d"
+msgstr "Pagina %d van %d"
+
+#: ..\..\..\templates\bookmarks.tpl.php:160
+msgid "No bookmarks available"
+msgstr "Geen bookmarks beschikbaar"
+
+#: ..\..\..\templates\dynamictags.inc.php:108
+#: ..\..\..\templates\sidebar.block.common.php:15
+#: ..\..\..\templates\sidebar.block.popular.php:21
+#: ..\..\..\templates\sidebar.block.recent.php:20
+#: ..\..\..\templates\tags.tpl.php:16
+#, fuzzy
+msgid "bookmark"
+msgid_plural "bookmarks"
+msgstr[0] "%s Bookmarks"
+msgstr[1] "%s Bookmarks"
+
+#: ..\..\..\templates\editbookmark.tpl.php:29
+msgid "Address"
+msgstr "Adres"
+
+#: ..\..\..\templates\editbookmark.tpl.php:31
+#: ..\..\..\templates\editbookmark.tpl.php:36
+#: ..\..\..\templates\editprofile.tpl.php:31
+msgid "Required"
+msgstr "Verplicht"
+
+#: ..\..\..\templates\editbookmark.tpl.php:39
+#: ..\..\..\templates\editprofile.tpl.php:47
+#: ..\..\..\templates\profile.tpl.php:28
+msgid "Description"
+msgstr "Omschrijving"
+
+#: ..\..\..\templates\editbookmark.tpl.php:46
+msgid "Comma-separated"
+msgstr "Door comma's gescheiden"
+
+#: ..\..\..\templates\editbookmark.tpl.php:49
+#: ..\..\..\templates\importDelicious.tpl.php:15
+#: ..\..\..\templates\importNetscape.tpl.php:16
+msgid "Privacy"
+msgstr "Privacy"
+
+#: ..\..\..\templates\editbookmark.tpl.php:52
+#: ..\..\..\templates\importDelicious.tpl.php:18
+#: ..\..\..\templates\importNetscape.tpl.php:19
+msgid "Public"
+msgstr "Publiekelijk"
+
+#: ..\..\..\templates\editbookmark.tpl.php:53
+#: ..\..\..\templates\importDelicious.tpl.php:19
+#: ..\..\..\templates\importNetscape.tpl.php:20
+msgid "Shared with Watch List"
+msgstr "Gedeeld met 'watch list'"
+
+#: ..\..\..\templates\editbookmark.tpl.php:54
+#: ..\..\..\templates\importDelicious.tpl.php:20
+#: ..\..\..\templates\importNetscape.tpl.php:21
+msgid "Private"
+msgstr "Priv&egrav;"
+
+#: ..\..\..\templates\editbookmark.tpl.php:66
+msgid "Delete Bookmark"
+msgstr "Bookmark Verwijderen"
+
+#: ..\..\..\templates\editbookmark.tpl.php:93
+msgid "Bookmarklet"
+msgstr "Bookmarklet"
+
+#: ..\..\..\templates\editbookmark.tpl.php:94
+#, php-format
+msgid "Drag one of the following bookmarklets to your browser's bookmarks and click it whenever you want to add the page you are on to %s"
+msgstr "Sleep een van de volgende 'bookmarklets' naar de link-balk van je browser, en klik er vervolgens op als je je op een pagina bevind die je aan %s wilt toevoegen"
+
+#: ..\..\..\templates\editbookmark.tpl.php:106
+#, php-format
+msgid "Post to %s"
+msgstr "Plaats op %s"
+
+#: ..\..\..\templates\editbookmark.tpl.php:107
+#, php-format
+msgid "Post to %s (Pop-up)"
+msgstr "Plaats op %s (pop-up)"
+
+#: ..\..\..\templates\editbookmark.tpl.php:111
+#: ..\..\..\templates\importDelicious.tpl.php:26
+#: ..\..\..\templates\importNetscape.tpl.php:27
+msgid "Import"
+msgstr "Importeren"
+
+#: ..\..\..\templates\editbookmark.tpl.php:113
+msgid "Import bookmarks from bookmark file"
+msgstr "Importeer bookmarks uit een bookmark bestand"
+
+#: ..\..\..\templates\editbookmark.tpl.php:113
+msgid "Internet Explorer, Mozilla Firefox and Netscape"
+msgstr "Internet Explorer, Mozilla Firefox en Netscape"
+
+#: ..\..\..\templates\editbookmark.tpl.php:114
+msgid "Import bookmarks from del.icio.us"
+msgstr "Importeer van del.icio.us"
+
+#: ..\..\..\templates\editprofile.tpl.php:10
+msgid "Account Details"
+msgstr ""
+
+#: ..\..\..\templates\editprofile.tpl.php:14
+#: ..\..\..\templates\login.tpl.php:15
+#: ..\..\..\templates\password.tpl.php:10
+#: ..\..\..\templates\profile.tpl.php:7
+#: ..\..\..\templates\register.tpl.php:16
+msgid "Username"
+msgstr "Gebruikersnaam"
+
+#: ..\..\..\templates\editprofile.tpl.php:19
+msgid "New Password"
+msgstr "Nieuw wachtwoord"
+
+#: ..\..\..\templates\editprofile.tpl.php:24
+#, fuzzy
+msgid "Confirm Password"
+msgstr "Bevestiging nieuw wachtwoord"
+
+#: ..\..\..\templates\editprofile.tpl.php:29
+#: ..\..\..\templates\register.tpl.php:26
+msgid "E-mail"
+msgstr "Email"
+
+#: ..\..\..\templates\editprofile.tpl.php:35
+msgid "Personal Details"
+msgstr ""
+
+#: ..\..\..\templates\editprofile.tpl.php:39
+#: ..\..\..\templates\profile.tpl.php:12
+msgid "Name"
+msgstr "Naam"
+
+#: ..\..\..\templates\editprofile.tpl.php:43
+#: ..\..\..\templates\profile.tpl.php:18
+msgid "Homepage"
+msgstr "Homepage"
+
+#: ..\..\..\templates\error.404.tpl.php:5
+#, fuzzy
+msgid "Not Found"
+msgstr "Gebruiker werd niet gevonden"
+
+#: ..\..\..\templates\error.404.tpl.php:6
+msgid "The requested URL was not found on this server"
+msgstr ""
+
+#: ..\..\..\templates\error.500.tpl.php:5
+msgid "General server error"
+msgstr ""
+
+#: ..\..\..\templates\error.500.tpl.php:6
+msgid "The requested URL could not be processed"
+msgstr ""
+
+#: ..\..\..\templates\importDelicious.tpl.php:33
+msgid "Log in to the <a href=\"http://del.icio.us/api/posts/all\">export page at del.icio.us</a>"
+msgstr "Log in op de <a href=\"http://del.icio.us/api/posts/all\">export pagina op del.icio.us</a>"
+
+#: ..\..\..\templates\importDelicious.tpl.php:34
+msgid "Save the resulting <abbr title=\"Extensible Markup Language\">XML</abbr> file to your computer"
+msgstr "Sla het resulterende <abbr title=\"Extensible Markup Language\">XML</abbr> bestand op, op de locale computer"
+
+#: ..\..\..\templates\importDelicious.tpl.php:35
+msgid "Click <kbd>Browse...</kbd> to find this file on your computer. The maximum size the file can be is 1MB"
+msgstr "Klik vervolgens op <kbd>Bladeren...</kbd> om dit opgeslagen bestand op de computer te vinden. De maximum toegelaten bestandsgrootte op onze server is 1MB"
+
+#: ..\..\..\templates\importDelicious.tpl.php:36
+#: ..\..\..\templates\importNetscape.tpl.php:43
+msgid "Select the default privacy setting for your imported bookmarks"
+msgstr "Selecteer welke privacy instelling moet worden toegepast op de ge&iuml;mporteerde bookmarks"
+
+#: ..\..\..\templates\importDelicious.tpl.php:37
+#: ..\..\..\templates\importNetscape.tpl.php:44
+msgid "Click <kbd>Import</kbd> to start importing the bookmarks; it may take a minute"
+msgstr "Klik op <kbd>Importeren</kbd> om het importeren te starten. Dit kan enkele minuten duren."
+
+#: ..\..\..\templates\importNetscape.tpl.php:32
+msgid "Instructions"
+msgstr "Instructies"
+
+#: ..\..\..\templates\importNetscape.tpl.php:35
+msgid "Export your bookmarks from your browser to a file"
+msgstr "Bookmarks exporteren vanuit een browser"
+
+#: ..\..\..\templates\importNetscape.tpl.php:37
+msgid "Internet Explorer: <kbd>File &gt; Import and Export... &gt; Export Favorites"
+msgstr "Internet Explorer: <kbd>File &gt; Import and Export... &gt; Export Favorites"
+
+#: ..\..\..\templates\importNetscape.tpl.php:38
+msgid "Mozilla Firefox: <kbd>Bookmarks &gt; Manage Bookmarks... &gt; File &gt; Export..."
+msgstr "Mozilla Firefox: <kbd>Bookmarks &gt; Manage Bookmarks... &gt; File &gt; Export..."
+
+#: ..\..\..\templates\importNetscape.tpl.php:39
+msgid "Netscape: <kbd>Bookmarks &gt; Manage Bookmarks... &gt; Tools &gt; Export..."
+msgstr "Netscape: <kbd>Bookmarks &gt; Manage Bookmarks... &gt; Tools &gt; Export..."
+
+#: ..\..\..\templates\importNetscape.tpl.php:42
+msgid "Click <kbd>Browse...</kbd> to find the saved bookmark file on your computer. The maximum size the file can be is 1MB"
+msgstr "Klik vervolgens op <kbd>Bladeren...</kbd> om het opgeslagen bookmark bestand op de computer te vinden. De maximum toegelaten bestandsgrootte op onze server is 1MB"
+
+#: ..\..\..\templates\login.tpl.php:20
+#: ..\..\..\templates\register.tpl.php:21
+msgid "Password"
+msgstr "Wachtwoord"
+
+#: ..\..\..\templates\login.tpl.php:22
+msgid "Don't ask for my password for 2 weeks"
+msgstr "Wachtwoord de komende 2 weken niet nog een keer vragen"
+
+#: ..\..\..\templates\login.tpl.php:30
+msgid "Forgotten your password?"
+msgstr ""
+
+#: ..\..\..\templates\password.tpl.php:5
+#, php-format
+msgid "If you have forgotten your password, %s can generate a new one. Enter the username and e-mail address of your account into the form below and we will e-mail your new password to you."
+msgstr ""
+
+#: ..\..\..\templates\password.tpl.php:14
+msgid "<abbr title=\"Electronic mail\">E-mail</abbr>"
+msgstr ""
+
+#: ..\..\..\templates\password.tpl.php:19
+#, fuzzy
+msgid "Generate Password"
+msgstr "Nieuw wachtwoord"
+
+#: ..\..\..\templates\profile.tpl.php:23
+msgid "Member Since"
+msgstr "Lid sinds"
+
+#: ..\..\..\templates\profile.tpl.php:35
+#: ..\..\..\templates\sidebar.block.watchlist.php:8
+#, fuzzy
+msgid "Watching"
+msgstr "Watch List"
+
+#: ..\..\..\templates\profile.tpl.php:50
+#, fuzzy
+msgid "Watched By"
+msgstr "Watched"
+
+#: ..\..\..\templates\register.tpl.php:11
+#, php-format
+msgid "Sign up here to create a free %s account. All the information requested below is required"
+msgstr ""
+
+#: ..\..\..\templates\rss.tpl.php:9
+#, fuzzy, php-format
+msgid "Recent bookmarks posted to %s"
+msgstr "Recente bookmarks"
+
+#: ..\..\..\templates\rss.tpl.php:17
+#: ..\..\..\templates\rss.tpl.php:19
+#, fuzzy
+msgid "No bookmarks found"
+msgstr "Geen bookmarks beschikbaar"
+
+#: ..\..\..\templates\sidebar.block.recent.php:15
+#, fuzzy
+msgid "Recent Tags"
+msgstr "Gerelateerde Tags"
+
+#: ..\..\..\templates\sidebar.block.related.php:15
+msgid "Related Tags"
+msgstr "Gerelateerde Tags"
+
+#: ..\..\..\templates\sidebar.block.watchstatus.php:10
+msgid "Remove from Watchlist"
+msgstr "Van 'watch-list' verwijderen"
+
+#: ..\..\..\templates\sidebar.block.watchstatus.php:12
+msgid "Add to Watchlist"
+msgstr "Voeg toe aan 'watch-list'"
+
+#: ..\..\..\templates\sidebar.block.watchstatus.php:17
+#, fuzzy
+msgid "Actions"
+msgstr "Instructies"
+
+#: ..\..\..\templates\tags.tpl.php:8
+msgid "Alphabet"
+msgstr ""
+
+#: ..\..\..\templates\tags.tpl.php:9
+#, fuzzy
+msgid "Popularity"
+msgstr "Populaire Tags"
+
+#: ..\..\..\templates\toolbar.inc.php:11
+#, fuzzy
+msgid "Bookmarks"
+msgstr "%s Bookmarks"
+
+#: ..\..\..\templates\toolbar.inc.php:16
+msgid "Log Out"
+msgstr ""
+
diff --git a/locales/pt_BR/LC_MESSAGES/messages.mo b/locales/pt_BR/LC_MESSAGES/messages.mo
new file mode 100644
index 0000000..4faf24a
--- /dev/null
+++ b/locales/pt_BR/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/locales/pt_BR/LC_MESSAGES/messages.po b/locales/pt_BR/LC_MESSAGES/messages.po
new file mode 100644
index 0000000..36df105
--- /dev/null
+++ b/locales/pt_BR/LC_MESSAGES/messages.po
@@ -0,0 +1,814 @@
+# Scuttle pt-BR Translation
+# Copyright (C) 2006 Scuttle project
+# This file is distributed under the same license as the Scuttle package.
+# Marcelo Jorge Vieira (metal) <metal@alucinados.com>, 2006.
+#
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Scuttle\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2005-04-29 11:17+0200\n"
+"PO-Revision-Date: 2006-04-06 17:26-0300\n"
+"Last-Translator: Daniel duende Carvalho <daniel.carvalho@gmail.com>\n"
+"Language-Team: Portuguese/Brazil\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: ..\..\..\about.php:25
+#: ..\..\..\toolbar.inc.php:14
+#: ..\..\..\templates\toolbar.inc.php:24
+msgid "About"
+msgstr "Sobre"
+
+#: ..\..\..\ajaxDelete.php:28
+msgid "You are not allowed to delete this bookmark"
+msgstr "Você não tem permissão para apagar este bookmark"
+
+#: ..\..\..\ajaxDelete.php:32
+msgid "Failed to delete bookmark"
+msgstr "Falha ao apagar bookmark"
+
+#: ..\..\..\alltags.php:48
+msgid "All Tags"
+msgstr "Todos os Tags"
+
+#: ..\..\..\alltags.php:57
+#: ..\..\..\bookmarks.php:64
+#: ..\..\..\populartags.php:63
+#: ..\..\..\profile.php:39
+#: ..\..\..\rss.php:55
+#: ..\..\..\search.php:55
+#: ..\..\..\watch.php:35
+#: ..\..\..\watched.php:56
+#, php-format
+msgid "User with username %s not was not found"
+msgstr "O Nome de Usuário %s não foi encontrado"
+
+#: ..\..\..\bookmarks.php:87
+#: ..\..\..\edit.php:44
+msgid "Your bookmark must have a title and an address"
+msgstr "O seu bookmark deve possuir um título e um endereço"
+
+#: ..\..\..\bookmarks.php:104
+msgid "Bookmark saved"
+msgstr "Bookmark gravado"
+
+#: ..\..\..\bookmarks.php:106
+#: ..\..\..\import.php:99
+#: ..\..\..\importNetscape.php:71
+msgid "There was an error saving your bookmark. Please try again or contact the administrator."
+msgstr "Ocorreu um erro na gravação do seu bookmark. Por favor tente novamente ou entre em contato com o administrador."
+
+#: ..\..\..\bookmarks.php:143
+#: ..\..\..\toolbar.inc.php:9
+#: ..\..\..\templates\toolbar.inc.php:13
+msgid "Add a Bookmark"
+msgstr "Adicione um Bookmark"
+
+#: ..\..\..\bookmarks.php:144
+msgid "Add Bookmark"
+msgstr "Adicionar Bookmark"
+
+#: ..\..\..\bookmarks.php:147
+msgid "You must be logged in before you can add bookmarks."
+msgstr "Você deve dar entrada no sistema para poder adicionar bookmarks"
+
+#: ..\..\..\bookmarks.php:196
+#: ..\..\..\watch.php:79
+#, php-format
+msgid "%s Bookmarks"
+msgstr "%s Bookmarks"
+
+#: ..\..\..\edit.php:29
+msgid "Edit Bookmark"
+msgstr "Editar Bookmark"
+
+#: ..\..\..\edit.php:34
+#, php-format
+msgid "Bookmark with id %s not was not found"
+msgstr "O Bookmark com a identificação %s não foi encontrado"
+
+#: ..\..\..\edit.php:39
+msgid "You are not allowed to edit this bookmark"
+msgstr "Você não tem permissão para editar este bookmark"
+
+#: ..\..\..\edit.php:55
+msgid "Error while saving your bookmark"
+msgstr "Erro durante a gravação do seu bookmark"
+
+#: ..\..\..\edit.php:73
+msgid "Failed to delete the bookmark"
+msgstr "Falha ao apagar o bookmark"
+
+#: ..\..\..\edit.php:80
+#: ..\..\..\templates\editprofile.tpl.php:59
+msgid "Save Changes"
+msgstr "Salva Alterações"
+
+#: ..\..\..\functions.inc.php:98
+msgid "message_die() was called multiple times."
+msgstr "message_die() foi chamada múltiplas vezes"
+
+#: ..\..\..\functions.inc.php:110
+msgid "SQL Error"
+msgstr "Erro de SQL"
+
+#: ..\..\..\functions.inc.php:116
+msgid "Line"
+msgstr "Linha"
+
+#: ..\..\..\functions.inc.php:116
+#: ..\..\..\templates\importDelicious.tpl.php:8
+#: ..\..\..\templates\importNetscape.tpl.php:9
+msgid "File"
+msgstr "Arquivo"
+
+#: ..\..\..\functions.inc.php:122
+msgid "Information"
+msgstr "Informações"
+
+#: ..\..\..\functions.inc.php:127
+msgid "Critical Information"
+msgstr "Informações Importantes"
+
+#: ..\..\..\functions.inc.php:132
+msgid "An error occured"
+msgstr "Um erro ocorreu"
+
+#: ..\..\..\functions.inc.php:135
+msgid "General Error"
+msgstr "Erro Geral"
+
+#: ..\..\..\functions.inc.php:143
+msgid "An critical error occured"
+msgstr "Um erro crítico ocorreu"
+
+#: ..\..\..\functions.inc.php:146
+msgid "Critical Error"
+msgstr "Erro Crítico"
+
+#: ..\..\..\functions.inc.php:155
+msgid "DEBUG MODE"
+msgstr "MODO DEBUG"
+
+#: ..\..\..\import.php:39
+msgid "Could not open XML input"
+msgstr "Não foi possível abrir a entrada XML"
+
+#: ..\..\..\import.php:43
+#, php-format
+msgid "XML error: %s at line %d"
+msgstr "Erro de XML: %s na linha %d"
+
+#: ..\..\..\import.php:52
+msgid "Import Bookmarks from del.icio.us"
+msgstr "Importar Bookmarks do del.icio.us"
+
+#: ..\..\..\import.php:84
+#: ..\..\..\importNetscape.php:62
+msgid "You have already submitted this bookmark."
+msgstr "Você já submeteu este Bookmark."
+
+#: ..\..\..\import.php:97
+#: ..\..\..\importNetscape.php:69
+msgid "Bookmark imported."
+msgstr "Bookmark importado."
+
+#: ..\..\..\importNetscape.php:77
+msgid "Import Bookmarks from Browser File"
+msgstr "Importar Bookmarks (Favoritos) do Arquivo do Navegador"
+
+#: ..\..\..\index.php:31
+msgid "You have now logged out"
+msgstr "Você saiu do sistema"
+
+#: ..\..\..\index.php:38
+#, php-format
+msgid "%s: Recent bookmarks"
+msgstr "%s: Bookmarks recentes"
+
+#: ..\..\..\index.php:71
+msgid "Online Bookmarks Manager"
+msgstr "Gerenciador Online de Bookmarks"
+
+#: ..\..\..\index.php:72
+msgid "Recent Bookmarks"
+msgstr "Bookmarks Recentes"
+
+#: ..\..\..\jsScuttle.php:42
+msgid "Are you sure?"
+msgstr "Você tem certeza disso!?"
+
+#: ..\..\..\jsScuttle.php:42
+msgid "Yes"
+msgstr "Sim"
+
+#: ..\..\..\jsScuttle.php:42
+msgid "No"
+msgstr "Não"
+
+#: ..\..\..\login.php:36
+msgid "The details you have entered are incorrect. Please try again."
+msgstr "Os detalhes submetidos por você estão incorretos. Por favor tente novamente."
+
+#: ..\..\..\login.php:53
+msgid "You are already logged in."
+msgstr "Você já entrou no sistema."
+
+#: ..\..\..\login.php:55
+#: ..\..\..\toolbar.inc.php:14
+#: ..\..\..\templates\login.tpl.php:20
+#: ..\..\..\templates\toolbar.inc.php:28
+msgid "Log In"
+msgstr "Entrar no sistema"
+
+#: ..\..\..\password.php:31
+msgid "You must enter your username."
+msgstr "Você tem que digitar o seu nome de usuário"
+
+#: ..\..\..\password.php:35
+msgid "You must enter your <abbr title=\"electronic mail\">e-mail</abbr> address."
+msgstr "Você tem que digitar o seu endereço de <abbr title=\"electronic mail\">e-mail</abbr>."
+
+#: ..\..\..\password.php:42
+msgid "No matches found for that username."
+msgstr "Nenhum resultado encontrado pra este nome de usuário"
+
+#: ..\..\..\password.php:45
+msgid "No matches found for that combination of username and <abbr title=\"electronic mail\">e-mail</abbr> address."
+msgstr "Nenhum resultado encontrado para esta combinação de nome de usuário e endereço de <abbr title=\"electronic mail\">e-mail</abbr> "
+
+#: ..\..\..\password.php:53
+msgid "There was an error while generating your new password. Please try again."
+msgstr "Ocorreu um erro durante a geração de sua nova senha. Por favor tente novamente."
+
+#: ..\..\..\password.php:57
+msgid "Your new password is:"
+msgstr "A sua nova senha é:"
+
+#: ..\..\..\password.php:57
+msgid "To keep your bookmarks secure, you should change this password in your profile the next time you log in."
+msgstr "Para manter seguros os seus bookmarks, você deveria alterar esta senha (em seu perfil) na próxima vez que entrar no sistema."
+
+#: ..\..\..\password.php:60
+#, php-format
+msgid "%s Account Information"
+msgstr "Informações da Conta de %s"
+
+#: ..\..\..\password.php:62
+#, php-format
+msgid "New password generated and sent to %s"
+msgstr "Nova senha gerada e enviada para %s"
+
+#: ..\..\..\password.php:69
+msgid "Forgotten Password"
+msgstr "Esquecí a Senha"
+
+#: ..\..\..\populartags.php:54
+#: ..\..\..\templates\sidebar.block.popular.php:13
+msgid "Popular Tags"
+msgstr "Tags populares"
+
+#: ..\..\..\profile.php:47
+#: ..\..\..\templates\sidebar.block.profile.php:11
+msgid "Profile"
+msgstr "Perfil"
+
+#: ..\..\..\profile.php:49
+msgid "Username was not specified"
+msgstr "O nome de usuário não foi especificado"
+
+#: ..\..\..\profile.php:57
+#, php-format
+msgid "%s Profile"
+msgstr "Perfil de %s"
+
+#: ..\..\..\profile.php:71
+msgid "Your name and e-mail address are required and must be completed."
+msgstr "Seu nome e endereço de email são requeridos e devem ser preenchidos."
+
+#: ..\..\..\profile.php:75
+msgid "Password and confirmation do not match."
+msgstr "A senha digitada não é idêntica àquela digitada no campo de confirmação de senha."
+
+#: ..\..\..\profile.php:79
+msgid "Password must be at least 6 characters long."
+msgstr "A senha deve ter um mínimo de 6 caracteres."
+
+#: ..\..\..\profile.php:87
+msgid "E-mail address is not valid."
+msgstr "O endereço de e-mail fornecido não é válido."
+
+#: ..\..\..\profile.php:91
+msgid "An error occurred while saving your changes."
+msgstr "Um erro ocorreu durante a gravação das suas alterações."
+
+#: ..\..\..\profile.php:93
+msgid "Changes saved."
+msgstr "Alterações gravadas."
+
+#: ..\..\..\register.php:30
+msgid "You <em>must</em> enter a username, password, name and <abbr title=\"electronic mail\">e-mail</abbr> address."
+msgstr "Você <em>deve</em> digitar um nome de usuário, uma senha, seu nome e endereço de <abbr title=\"electronic mail\">e-mail</abbr>."
+
+#: ..\..\..\register.php:34
+msgid "This username already exists, please make another choice."
+msgstr "Este nome de usuário já existe. Por favor, escolha outro nome de usuário."
+
+#: ..\..\..\register.php:38
+msgid "E-mail address is not valid. Please try again."
+msgstr "Endereço de email inválido. Por favor tente novamente."
+
+#: ..\..\..\register.php:46
+msgid "You have successfully registered. Enjoy!"
+msgstr "Você completou o seu registro. Agora divirta-se!"
+
+#: ..\..\..\register.php:48
+msgid "Registration failed. Please try again."
+msgstr "Falha ao registrar-se. Por favor tente novamente."
+
+#: ..\..\..\register.php:52
+#: ..\..\..\toolbar.inc.php:14
+#: ..\..\..\templates\register.tpl.php:27
+#: ..\..\..\templates\toolbar.inc.php:27
+msgid "Register"
+msgstr "Registre-se"
+
+#: ..\..\..\search.inc.php:29
+#: ..\..\..\search.inc.php:58
+msgid "Search"
+msgstr "Busca"
+
+#: ..\..\..\search.inc.php:36
+#, php-format
+msgid "%s bookmarks"
+msgstr "%s bookmarks"
+
+#: ..\..\..\search.inc.php:41
+msgid "my bookmarks"
+msgstr "meus bookmarks"
+
+#: ..\..\..\search.inc.php:42
+msgid "my watched bookmarks"
+msgstr "meus bookmarks observados"
+
+#: ..\..\..\search.inc.php:46
+msgid "all bookmarks"
+msgstr "todos os bookmarks"
+
+#: ..\..\..\search.inc.php:49
+msgid "for"
+msgstr "por"
+
+#: ..\..\..\search.php:110
+#: ..\..\..\search.php:114
+msgid "Search Bookmarks"
+msgstr "Busca Bookmarks"
+
+#: ..\..\..\search.php:112
+msgid "Search Results"
+msgstr "Resultados da Busca"
+
+#: ..\..\..\toolbar.inc.php:9
+msgid "Your Bookmarks"
+msgstr "Seus Bookmarks"
+
+#: ..\..\..\toolbar.inc.php:9
+msgid "Watched Bookmarks"
+msgstr "Bookmarks Observados"
+
+#: ..\..\..\toolbar.inc.php:9
+msgid "All Bookmarks"
+msgstr "Todos os Bookmarks"
+
+#: ..\..\..\toolbar.inc.php:9
+#: ..\..\..\templates\toolbar.inc.php:16
+msgid "Log Out"
+msgstr "Sair do Sistema"
+
+#: ..\..\..\watch.php:84
+msgid "User removed from your watchlist"
+msgstr "Usuário removido da sua lista de observação"
+
+#: ..\..\..\watch.php:86
+msgid "User added to your watchlist"
+msgstr "Usuário adicionado à sua lista de observação"
+
+#: ..\..\..\watched.php:64
+#: ..\..\..\watched.php:101
+#, php-format
+msgid "%s Watched Bookmarks"
+msgstr "%s Bookmarks Observados"
+
+#: ..\..\..\services\userservice.php:93
+msgid "Your"
+msgstr "Seu"
+
+#: ..\..\..\services\userservice.php:101
+#, php-format
+msgid "%s'"
+msgstr ""
+
+#: ..\..\..\templates\about.tpl.php:6
+msgid "<strong>Store</strong> all your favourite links in one place, accessible from anywhere."
+msgstr "<strong>Agregue</strong> todos os seus links favoritos em um só local, acessível de qualquer lugar."
+
+#: ..\..\..\templates\about.tpl.php:7
+msgid "<strong>Share</strong> your bookmarks with everyone, with friends on your watchlist or just keep them private."
+msgstr "<strong>Compartilhe</strong> seus bookmarks com todo o mundo, com amigos em sua lista de observação ou guarde-os apenas para você."
+
+#: ..\..\..\templates\about.tpl.php:8
+msgid "<strong>Tag</strong> your bookmarks with as many labels as you want, instead of wrestling with folders."
+msgstr "<strong>Identifique</strong> seus bookmarks com tantos tags quanto quiser, em vez de lutar contra pastas e diretórios."
+
+#: ..\..\..\templates\about.tpl.php:9
+#, php-format
+msgid "<strong><a href=\"register.php\">Register now</a></strong> to start using %s!"
+msgstr "<strong><a href=\"register.php\">Registre-se agora</a></strong> para começar a usar o %s!"
+
+#: ..\..\..\templates\about.tpl.php:12
+msgid "Geek Stuff"
+msgstr "Coisas de Geek"
+
+#: ..\..\..\templates\about.tpl.php:14
+#, php-format
+msgid "%s is based on <a href=\"http://sourceforge.net/projects/scuttle/\">an open-source project</a> licensed under the <a href=\"http://www.gnu.org/copyleft/gpl.html\"><acronym title=\"GNU's Not Unix\">GNU</acronym> General Public License</a>. This means you can host it on your own web server for free, whether it is on the Internet, a private network or just your own computer."
+msgstr "O %s é baseado em <a href=\"http://sourceforge.net/projects/scuttle/\">um projeto open source</a> licenciado sob a <a href=\"http://www.gnu.org/copyleft/gpl.html\"><acronym title=\"GNU's Not Unix\">GNU</acronym> General Public Licence</a>. Isso significa que você pode hospedá-lo em seu próprio servidor de rede gratuitamente, esteja ele na Internet, em uma rede privada ou apenas em seu computador."
+
+#: ..\..\..\templates\about.tpl.php:15
+#, php-format
+msgid "%1$s supports most of the <a href=\"http://del.icio.us/doc/api\">del.icio.us <abbr title=\"Application Programming Interface\">API</abbr></a>. Almost all of the neat tools made for that system can be modified to work with %1$s instead. If you find a tool that won't let you change the API address, ask the creator to add this setting. You never know, they might just do it."
+msgstr "O %1$s suporta a maior parte do <a href=\"http://del.icio.us/doc/api\"><abbr title=\"Application Programming Interface\">API</abbr> do del.icio.us</a>. Quase todas as adoráveis ferramentas desenvolvidas para aquele sistema podem ser modificadas para funcionar com o %1$s. Se você encontrar uma ferramenta que não permita a mudança de seu endereço de API, solicite a seu criador para que adicione esta configuração. Nunca se sabe. Ele pode simplesmente atender a seu pedido."
+
+#: ..\..\..\templates\bookmarks.tpl.php:10
+#: ..\..\..\templates\tags.tpl.php:6
+msgid "Sort by:"
+msgstr "Ordenar por:"
+
+#: ..\..\..\templates\bookmarks.tpl.php:11
+msgid "Date"
+msgstr "Data"
+
+#: ..\..\..\templates\bookmarks.tpl.php:12
+#: ..\..\..\templates\editbookmark.tpl.php:28
+msgid "Title"
+msgstr "Título"
+
+#: ..\..\..\templates\bookmarks.tpl.php:13
+msgid "URL"
+msgstr "URL"
+
+#: ..\..\..\templates\bookmarks.tpl.php:52
+msgid "Edit"
+msgstr "Editar"
+
+#: ..\..\..\templates\bookmarks.tpl.php:52
+msgid "Delete"
+msgstr "Apagar"
+
+#: ..\..\..\templates\bookmarks.tpl.php:67
+msgid " and 1 other"
+msgstr "e 1 outro"
+
+#: ..\..\..\templates\bookmarks.tpl.php:70
+#, php-format
+msgid " and %s others"
+msgstr "e %s outros"
+
+#: ..\..\..\templates\bookmarks.tpl.php:73
+msgid "Copy"
+msgstr "Copiar"
+
+#: ..\..\..\templates\bookmarks.tpl.php:121
+#: ..\..\..\templates\bookmarks.tpl.php:125
+msgid "Previous"
+msgstr "Anterior"
+
+#: ..\..\..\templates\bookmarks.tpl.php:132
+#: ..\..\..\templates\bookmarks.tpl.php:134
+msgid "Next"
+msgstr "Próximo"
+
+#: ..\..\..\templates\bookmarks.tpl.php:135
+#, php-format
+msgid "Page %d of %d"
+msgstr "Página %d de %d"
+
+#: ..\..\..\templates\bookmarks.tpl.php:145
+msgid "No bookmarks available"
+msgstr "Nenhum bookmark disponível"
+
+#: ..\..\..\templates\editbookmark.tpl.php:23
+msgid "Address"
+msgstr "Endereço"
+
+#: ..\..\..\templates\editbookmark.tpl.php:25
+#: ..\..\..\templates\editbookmark.tpl.php:30
+#: ..\..\..\templates\editprofile.tpl.php:17
+#: ..\..\..\templates\editprofile.tpl.php:19
+msgid "Required"
+msgstr "Requerido"
+
+#: ..\..\..\templates\editbookmark.tpl.php:33
+#: ..\..\..\templates\editprofile.tpl.php:24
+#: ..\..\..\templates\profile.tpl.php:28
+msgid "Description"
+msgstr "Descrição"
+
+#: ..\..\..\templates\editbookmark.tpl.php:38
+#: ..\..\..\templates\importDelicious.tpl.php:15
+#: ..\..\..\templates\importNetscape.tpl.php:16
+#: ..\..\..\templates\sidebar.block.profile.php:12
+msgid "Tags"
+msgstr "Tags (Rótulos)"
+
+#: ..\..\..\templates\editbookmark.tpl.php:40
+#: ..\..\..\templates\importDelicious.tpl.php:17
+#: ..\..\..\templates\importNetscape.tpl.php:18
+msgid "Comma-separated"
+msgstr "Separados por vírgula"
+
+#: ..\..\..\templates\editbookmark.tpl.php:43
+#: ..\..\..\templates\importDelicious.tpl.php:20
+#: ..\..\..\templates\importNetscape.tpl.php:21
+msgid "Privacy"
+msgstr "Privacidade"
+
+#: ..\..\..\templates\editbookmark.tpl.php:46
+#: ..\..\..\templates\importDelicious.tpl.php:23
+#: ..\..\..\templates\importNetscape.tpl.php:24
+msgid "Public"
+msgstr "Público"
+
+#: ..\..\..\templates\editbookmark.tpl.php:47
+#: ..\..\..\templates\importDelicious.tpl.php:24
+#: ..\..\..\templates\importNetscape.tpl.php:25
+msgid "Shared with Watch List"
+msgstr "Partilhado com a sua Lista de Observação"
+
+#: ..\..\..\templates\editbookmark.tpl.php:48
+#: ..\..\..\templates\importDelicious.tpl.php:25
+#: ..\..\..\templates\importNetscape.tpl.php:26
+msgid "Private"
+msgstr "Privado"
+
+#: ..\..\..\templates\editbookmark.tpl.php:60
+msgid "Delete Bookmark"
+msgstr "Apagar Bookmark"
+
+#: ..\..\..\templates\editbookmark.tpl.php:74
+msgid "Bookmarklet"
+msgstr "Gerador de Bookmarks"
+
+#: ..\..\..\templates\editbookmark.tpl.php:75
+#, php-format
+msgid "Drag one of the following bookmarklets to your browser's bookmarks and click it whenever you want to add the page you are on to %s"
+msgstr "Arraste um dos seguintes Geradores de Bookmark para a área de favoridos de seu navegador. Clique nele toda vez que quiser adicionar a página na qual você se encontra ao %s"
+
+#: ..\..\..\templates\editbookmark.tpl.php:77
+#, php-format
+msgid "Post to %s"
+msgstr "Postar para %s"
+
+#: ..\..\..\templates\editbookmark.tpl.php:78
+#, php-format
+msgid "Post to %s (Pop-up)"
+msgstr "Postar para %s (versão Pop-Up)"
+
+#: ..\..\..\templates\editbookmark.tpl.php:81
+#: ..\..\..\templates\importDelicious.tpl.php:31
+#: ..\..\..\templates\importNetscape.tpl.php:32
+msgid "Import"
+msgstr "Importar"
+
+#: ..\..\..\templates\editbookmark.tpl.php:83
+msgid "Import bookmarks from bookmark file"
+msgstr "Importar bookmarks do arquivo de bookmarks"
+
+#: ..\..\..\templates\editbookmark.tpl.php:83
+msgid "Internet Explorer, Mozilla Firefox and Netscape"
+msgstr "Internet Explorer, Mozilla Firefox and Netscape"
+
+#: ..\..\..\templates\editbookmark.tpl.php:84
+msgid "Import bookmarks from del.icio.us"
+msgstr "Importar bookmarks do del.icio.us"
+
+#: ..\..\..\templates\editprofile.tpl.php:10
+#: ..\..\..\templates\login.tpl.php:9
+#: ..\..\..\templates\password.tpl.php:10
+#: ..\..\..\templates\profile.tpl.php:7
+#: ..\..\..\templates\register.tpl.php:10
+msgid "Username"
+msgstr "Nome de Usuário"
+
+#: ..\..\..\templates\editprofile.tpl.php:12
+msgid "New Password"
+msgstr "Nova Senha"
+
+#: ..\..\..\templates\editprofile.tpl.php:14
+msgid "Confirm New Password"
+msgstr "Confirme a Nova Senha"
+
+#: ..\..\..\templates\editprofile.tpl.php:16
+#: ..\..\..\templates\profile.tpl.php:12
+#: ..\..\..\templates\register.tpl.php:18
+msgid "Name"
+msgstr "Nome"
+
+#: ..\..\..\templates\editprofile.tpl.php:18
+msgid "E-mail"
+msgstr "E-mail"
+
+#: ..\..\..\templates\editprofile.tpl.php:20
+#: ..\..\..\templates\profile.tpl.php:18
+msgid "Homepage"
+msgstr "Página na Web"
+
+#: ..\..\..\templates\editprofile.tpl.php:22
+#: ..\..\..\templates\profile.tpl.php:23
+msgid "Member Since"
+msgstr "Membro Desde"
+
+#: ..\..\..\templates\editprofile.tpl.php:30
+#: ..\..\..\templates\profile.tpl.php:35
+msgid "Watch List"
+msgstr "Lista de Observação"
+
+#: ..\..\..\templates\editprofile.tpl.php:45
+#: ..\..\..\templates\profile.tpl.php:50
+msgid "Watched By"
+msgstr "Observado Por"
+
+#: ..\..\..\templates\error.404.tpl.php:5
+msgid "Not Found"
+msgstr "Não Encontrado"
+
+#: ..\..\..\templates\error.404.tpl.php:6
+msgid "The requested URL was not found on this server"
+msgstr "A URL requisitada não foi encontrada neste servidor"
+
+#: ..\..\..\templates\error.500.tpl.php:5
+msgid "General server error"
+msgstr "Erro Geral de servidor"
+
+#: ..\..\..\templates\error.500.tpl.php:6
+msgid "The requested URL could not be processed"
+msgstr "A URL requisitada não pôde ser processada"
+
+#: ..\..\..\templates\importDelicious.tpl.php:38
+msgid "Log in to the <a href=\"http://del.icio.us/api/posts/all\">export page at del.icio.us</a>"
+msgstr "Entrar na <a href=\"http://del.icio.us/api/posts/all\">página de exportação do del.icio.us</a>"
+
+#: ..\..\..\templates\importDelicious.tpl.php:39
+msgid "Save the resulting <abbr title=\"Extensible Markup Language\">XML</abbr> file to your computer"
+msgstr "Salvar o arquivo <abbr title=\"Extensible Markup Language\">XML</abbr> resultante em seu computador."
+
+#: ..\..\..\templates\importDelicious.tpl.php:40
+msgid "Click <kbd>Browse...</kbd> to find this file on your computer. The maximum size the file can be is 1MB"
+msgstr "Clique em <kbd>Navegar...</kbd>para encontrar este arquivo no seu computador. O tamanho máximo que o arquivo pode ter é 1MB"
+
+#: ..\..\..\templates\importDelicious.tpl.php:41
+#: ..\..\..\templates\importNetscape.tpl.php:48
+msgid "Input the default tags you want added to your imported bookmarks"
+msgstr "Digite as tags padrão que você deseja que sejam adicionadas aos bookmarks importados"
+
+#: ..\..\..\templates\importDelicious.tpl.php:42
+#: ..\..\..\templates\importNetscape.tpl.php:49
+msgid "Select the default privacy setting for your imported bookmarks"
+msgstr "Selecione o status de privacidade padrão para os seus bookmarks importados"
+
+#: ..\..\..\templates\importDelicious.tpl.php:43
+#: ..\..\..\templates\importNetscape.tpl.php:50
+msgid "Click <kbd>Import</kbd> to start importing the bookmarks; it may take a minute"
+msgstr "Clique em <kbd>Importar</kbd> para começar a importar os bookmarks. Isso pode levar um minutinho..."
+
+#: ..\..\..\templates\importNetscape.tpl.php:37
+msgid "Instructions"
+msgstr "Instruções"
+
+#: ..\..\..\templates\importNetscape.tpl.php:40
+msgid "Export your bookmarks from your browser to a file"
+msgstr "Exporte seus bookmarks de seu navegador para um arquivo"
+
+#: ..\..\..\templates\importNetscape.tpl.php:42
+msgid "Internet Explorer: <kbd>File &gt; Import and Export... &gt; Export Favorites"
+msgstr "Internet Explorer: <kbd>Arquivo &gt; Importar e Exportar... &gt; Exportar Favoritos"
+
+#: ..\..\..\templates\importNetscape.tpl.php:43
+msgid "Mozilla Firefox: <kbd>Bookmarks &gt; Manage Bookmarks... &gt; File &gt; Export..."
+msgstr "Mozilla Firefox: <kbd>Bookmarks &gt; Gerenciar Bookmarks... &gt; Arquivo &gt; Exportar..."
+
+#: ..\..\..\templates\importNetscape.tpl.php:44
+msgid "Netscape: <kbd>Bookmarks &gt; Manage Bookmarks... &gt; Tools &gt; Export..."
+msgstr "Netscape: <kbd>Bookmarks &gt; Gerenciar Bookmarks... &gt; Ferramentas &gt; Exportar..."
+
+#: ..\..\..\templates\importNetscape.tpl.php:47
+msgid "Click <kbd>Browse...</kbd> to find the saved bookmark file on your computer. The maximum size the file can be is 1MB"
+msgstr "Clique <kbd>Procurar...</kbd> para encontrar o arquivo de bookmarks gravado em seu computador. O tamanho máximo permitido para o arquivo é 1MB"
+
+#: ..\..\..\templates\login.tpl.php:14
+#: ..\..\..\templates\register.tpl.php:14
+msgid "Password"
+msgstr "Senha"
+
+#: ..\..\..\templates\login.tpl.php:16
+msgid "Don't ask for my password for 2 weeks"
+msgstr "Não pergunte minha senha por duas semanas"
+
+#: ..\..\..\templates\login.tpl.php:24
+msgid "Forgotten your password?"
+msgstr "Esqueceu a sua senha?"
+
+#: ..\..\..\templates\myTagsDynamicInsert.inc.php:34
+#: ..\..\..\templates\myTagsDynamicInsert.inc.php:65
+msgid "My Tags"
+msgstr "Minhas Tags"
+
+#: ..\..\..\templates\myTagsDynamicInsert.inc.php:44
+msgid "Show"
+msgstr "Mostrar"
+
+#: ..\..\..\templates\myTagsDynamicInsert.inc.php:57
+msgid "System Popular Tags"
+msgstr "Tags Populares Gerais"
+
+#: ..\..\..\templates\myTagsDynamicInsert.inc.php:70
+msgid "My Popular Tags"
+msgstr "Minhas Tags Populares"
+
+#: ..\..\..\templates\password.tpl.php:5
+#, php-format
+msgid "If you have forgotten your password, %s can generate a new one. Enter the username and e-mail address of your account into the form below and we will e-mail your new password to you."
+msgstr "Se você esqueceu a sua senha, o %s pode gerar uma nova para você. Digite o seu nome de usuário e o seu endereço de e-mail no formulário abaixo e nós enviaremos a nova senha para seu e-mail."
+
+#: ..\..\..\templates\password.tpl.php:14
+#: ..\..\..\templates\register.tpl.php:22
+msgid "<abbr title=\"Electronic mail\">E-mail</abbr>"
+msgstr "<abbr title=\"Correio Eletrônico\">E-mail</abbr>"
+
+#: ..\..\..\templates\password.tpl.php:19
+msgid "Generate Password"
+msgstr "Gerar Senha"
+
+#: ..\..\..\templates\register.tpl.php:5
+#, php-format
+msgid "Sign up here to create a free %s account. All the information requested below is required"
+msgstr "Cadastre-se aqui para criar uma conta gratuita no %s. Todas as informações solicitadas abaixo são necessárias."
+
+#: ..\..\..\templates\rss.tpl.php:9
+#, php-format
+msgid "Recent bookmarks posted to %s"
+msgstr "Bookmarks recentemente postados para %s"
+
+#: ..\..\..\templates\rss.tpl.php:17
+#: ..\..\..\templates\rss.tpl.php:19
+msgid "No bookmarks found"
+msgstr "Nenhum bookmark encontrado"
+
+#: ..\..\..\templates\sidebar.block.profile.php:13
+msgid "Watched"
+msgstr "Observado"
+
+#: ..\..\..\templates\sidebar.block.recent.php:13
+msgid "Recent Tags"
+msgstr "Tags Recentes"
+
+#: ..\..\..\templates\sidebar.block.related.php:14
+msgid "Related Tags"
+msgstr "Tags Relacionadas"
+
+#: ..\..\..\templates\sidebar.block.watchstatus.php:10
+msgid "Remove from Watchlist"
+msgstr "Remover da Lista de Observação"
+
+#: ..\..\..\templates\sidebar.block.watchstatus.php:12
+msgid "Add to Watchlist"
+msgstr "Adicionar à Lista de Observação"
+
+#: ..\..\..\templates\tags.tpl.php:7
+msgid "Alphabet"
+msgstr "Alfabeto"
+
+#: ..\..\..\templates\tags.tpl.php:8
+msgid "Popularity"
+msgstr "Popularidade"
+
+#: ..\..\..\templates\tags.tpl.php:15
+msgid "bookmark"
+msgstr "bookmark"
+
+#: ..\..\..\templates\toolbar.inc.php:10
+msgid "My Bookmarks"
+msgstr "Meus Bookmarks"
+
+#: ..\..\..\templates\toolbar.inc.php:11
+msgid "My Watched"
+msgstr "Meus Observados"
+
+#: ..\..\..\templates\toolbar.inc.php:12
+msgid "All Recent"
+msgstr "Todos os Recentes"
+
diff --git a/locales/zh_CN/LC_MESSAGES/messages.mo b/locales/zh_CN/LC_MESSAGES/messages.mo
new file mode 100644
index 0000000..2bdc82e
--- /dev/null
+++ b/locales/zh_CN/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/locales/zh_CN/LC_MESSAGES/messages.po b/locales/zh_CN/LC_MESSAGES/messages.po
new file mode 100644
index 0000000..b6aadcb
--- /dev/null
+++ b/locales/zh_CN/LC_MESSAGES/messages.po
@@ -0,0 +1,827 @@
+# Scuttle zh-CN Translation
+# Copyright (C) 2005 - 2006 Scuttle project
+# This file is distributed under the same license as the Scuttle package.
+# Yanni Zheng <ynzheng@gmail.com>
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Scuttle\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2005-04-29 11:17+0200\n"
+"PO-Revision-Date: 2006-03-18 21:45-0800\n"
+"Last-Translator: Marcus Campbell <marcus.campbell@gmail.com>\n"
+"Language-Team: zh-CN <ynzheng@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-Language: Chinese\n"
+"X-Poedit-Country: CHINA\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: ..\..\..\about.php:25
+#: ..\..\..\templates\toolbar.inc.php:24
+msgid "About"
+msgstr "关于"
+
+#: ..\..\..\ajaxDelete.php:29
+msgid "You are not allowed to delete this bookmark"
+msgstr "您没有æƒé™åˆ é™¤æ­¤æ¡ä¹¦ç­¾"
+
+#: ..\..\..\ajaxDelete.php:33
+msgid "Failed to delete bookmark"
+msgstr "删除书签失败"
+
+#: ..\..\..\alltags.php:50
+msgid "All Tags"
+msgstr "所有标签"
+
+#: ..\..\..\alltags.php:59
+#: ..\..\..\populartags.php:63
+#: ..\..\..\profile.php:46
+#: ..\..\..\rss.php:55
+#: ..\..\..\search.php:61
+#: ..\..\..\watch.php:35
+#: ..\..\..\watched.php:62
+#, php-format
+msgid "User with username %s not was not found"
+msgstr "未å‘现以 %s 为用户å的用户"
+
+#: ..\..\..\bookmarks.php:71
+#, fuzzy, php-format
+msgid "User with username %s was not found"
+msgstr "未å‘现以 %s 为用户å的用户"
+
+#: ..\..\..\bookmarks.php:94
+#: ..\..\..\edit.php:44
+msgid "Your bookmark must have a title and an address"
+msgstr "æ¯æ¡ä¹¦ç­¾å¿…须包å«æ ‡é¢˜å’Œç½‘å€"
+
+#: ..\..\..\bookmarks.php:114
+#: ..\..\..\edit.php:58
+msgid "Bookmark saved"
+msgstr "录入书签已被æˆåŠŸä¿å­˜"
+
+#: ..\..\..\bookmarks.php:122
+#: ..\..\..\import.php:99
+#: ..\..\..\importNetscape.php:74
+msgid "There was an error saving your bookmark. Please try again or contact the administrator."
+msgstr "ä¿å­˜ä¹¦ç­¾æ—¶å‡ºé”™ï¼Œè¯·å†ä¿å­˜é‡è¯•ä¸€æ¬¡æˆ–者è”系管ç†å‘˜"
+
+#: ..\..\..\bookmarks.php:160
+#: ..\..\..\templates\toolbar.inc.php:13
+msgid "Add a Bookmark"
+msgstr "添加书签"
+
+#: ..\..\..\bookmarks.php:163
+msgid "Add Bookmark"
+msgstr "添加书签"
+
+#: ..\..\..\bookmarks.php:166
+msgid "You must be logged in before you can add bookmarks."
+msgstr "您必须登陆åŽæ‰èƒ½æ·»åŠ ä¹¦ç­¾"
+
+#: ..\..\..\bookmarks.php:213
+msgid "My Bookmarks"
+msgstr "您的书签"
+
+#: ..\..\..\edit.php:29
+msgid "Edit Bookmark"
+msgstr "编辑书签"
+
+#: ..\..\..\edit.php:34
+#, php-format
+msgid "Bookmark with id %s not was not found"
+msgstr "id为 %s 的书签ä¸å­˜åœ¨"
+
+#: ..\..\..\edit.php:39
+msgid "You are not allowed to edit this bookmark"
+msgstr "您没有æƒé™ç¼–辑此æ¡ä¹¦ç­¾"
+
+#: ..\..\..\edit.php:55
+msgid "Error while saving your bookmark"
+msgstr "在ä¿å­˜ä¹¦ç­¾æ—¶å‡ºé”™"
+
+#: ..\..\..\edit.php:78
+msgid "Failed to delete the bookmark"
+msgstr "删除书签失败"
+
+#: ..\..\..\edit.php:88
+#: ..\..\..\templates\editprofile.tpl.php:52
+msgid "Save Changes"
+msgstr "ä¿å­˜ä¿®æ”¹"
+
+#: ..\..\..\functions.inc.php:92
+msgid "message_die() was called multiple times."
+msgstr "message_die()被调用了多次"
+
+#: ..\..\..\functions.inc.php:104
+msgid "SQL Error"
+msgstr "SQL出错"
+
+#: ..\..\..\functions.inc.php:110
+msgid "Line"
+msgstr "行"
+
+#: ..\..\..\functions.inc.php:110
+#: ..\..\..\templates\importDelicious.tpl.php:8
+#: ..\..\..\templates\importNetscape.tpl.php:9
+msgid "File"
+msgstr "文件"
+
+#: ..\..\..\functions.inc.php:116
+msgid "Information"
+msgstr "ä¿¡æ¯"
+
+#: ..\..\..\functions.inc.php:121
+msgid "Critical Information"
+msgstr "关键性信æ¯"
+
+#: ..\..\..\functions.inc.php:126
+msgid "An error occured"
+msgstr "有错误å‘生"
+
+#: ..\..\..\functions.inc.php:129
+msgid "General Error"
+msgstr "一般性错误"
+
+#: ..\..\..\functions.inc.php:137
+msgid "An critical error occured"
+msgstr "有严é‡é”™è¯¯å‘生"
+
+#: ..\..\..\functions.inc.php:140
+msgid "Critical Error"
+msgstr "严é‡é”™è¯¯"
+
+#: ..\..\..\functions.inc.php:149
+msgid "DEBUG MODE"
+msgstr "调试模å¼"
+
+#: ..\..\..\history.php:65
+msgid "History"
+msgstr ""
+
+#: ..\..\..\history.php:66
+#, php-format
+msgid "History for %s"
+msgstr ""
+
+#: ..\..\..\history.php:81
+msgid "Address was not found"
+msgstr ""
+
+#: ..\..\..\import.php:41
+msgid "Could not open XML input"
+msgstr "无法打开XML输入"
+
+#: ..\..\..\import.php:45
+#, php-format
+msgid "XML error: %s at line %d"
+msgstr "XML错误: %s å‘生在 %d è¡Œ"
+
+#: ..\..\..\import.php:54
+msgid "Import Bookmarks from del.icio.us"
+msgstr "将del.icio.us的书签文件导入 "
+
+#: ..\..\..\import.php:86
+#: ..\..\..\importNetscape.php:64
+msgid "You have already submitted this bookmark."
+msgstr "您过去已ç»å½•å…¥è¿‡è¿™æ¡ä¹¦ç­¾"
+
+#: ..\..\..\import.php:97
+#: ..\..\..\importNetscape.php:72
+msgid "Bookmark imported."
+msgstr "书签导入完毕."
+
+#: ..\..\..\importNetscape.php:81
+msgid "Import Bookmarks from Browser File"
+msgstr "å°†æµè§ˆå™¨çš„书签文件导入(Internet Explorer, Mozilla Firefox and Netscape)"
+
+#: ..\..\..\index.php:32
+msgid "You have now logged out"
+msgstr "您已ç»æˆåŠŸç™»å‡º"
+
+#: ..\..\..\index.php:39
+#, php-format
+msgid "%s: Recent bookmarks"
+msgstr "%s: 最近书签"
+
+#: ..\..\..\index.php:72
+msgid "Store, share and tag your favourite links"
+msgstr ""
+
+#: ..\..\..\index.php:73
+msgid "Recent Bookmarks"
+msgstr "最近书签"
+
+#: ..\..\..\jsScuttle.php:22
+msgid "Are you sure?"
+msgstr ""
+
+#: ..\..\..\jsScuttle.php:22
+msgid "Yes"
+msgstr ""
+
+#: ..\..\..\jsScuttle.php:22
+msgid "No"
+msgstr ""
+
+#: ..\..\..\jsScuttle.php:68
+msgid "Available"
+msgstr ""
+
+#: ..\..\..\jsScuttle.php:71
+#, fuzzy
+msgid "Not Available"
+msgstr "尚未有书签列入"
+
+#: ..\..\..\login.php:38
+msgid "The details you have entered are incorrect. Please try again."
+msgstr "您输入的详细信æ¯ä¸æ­£ç¡®ï¼Œè¯·é‡è¯•."
+
+#: ..\..\..\login.php:48
+#: ..\..\..\templates\login.tpl.php:26
+#: ..\..\..\templates\toolbar.inc.php:28
+msgid "Log In"
+msgstr "登陆"
+
+#: ..\..\..\password.php:31
+msgid "You must enter your username."
+msgstr ""
+
+#: ..\..\..\password.php:35
+#, fuzzy
+msgid "You must enter your <abbr title=\"electronic mail\">e-mail</abbr> address."
+msgstr "您 <em>å¿…é¡»</em> 输入用户å,密ç ,姓åå’Œ <abbr title=\"电å­é‚®ä»¶\">e-mail</abbr> 地å€."
+
+#: ..\..\..\password.php:42
+msgid "No matches found for that username."
+msgstr ""
+
+#: ..\..\..\password.php:45
+#, fuzzy
+msgid "No matches found for that combination of username and <abbr title=\"electronic mail\">e-mail</abbr> address."
+msgstr "您 <em>å¿…é¡»</em> 输入用户å,密ç ,姓åå’Œ <abbr title=\"电å­é‚®ä»¶\">e-mail</abbr> 地å€."
+
+#: ..\..\..\password.php:53
+#, fuzzy
+msgid "There was an error while generating your new password. Please try again."
+msgstr "ä¿å­˜ä¹¦ç­¾æ—¶å‡ºé”™ï¼Œè¯·å†ä¿å­˜é‡è¯•ä¸€æ¬¡æˆ–者è”系管ç†å‘˜"
+
+#: ..\..\..\password.php:57
+#, fuzzy
+msgid "Your new password is:"
+msgstr "确认密ç "
+
+#: ..\..\..\password.php:57
+msgid "To keep your bookmarks secure, you should change this password in your profile the next time you log in."
+msgstr ""
+
+#: ..\..\..\password.php:60
+#, fuzzy, php-format
+msgid "%s Account Information"
+msgstr "ä¿¡æ¯"
+
+#: ..\..\..\password.php:62
+#, php-format
+msgid "New password generated and sent to %s"
+msgstr ""
+
+#: ..\..\..\password.php:69
+#, fuzzy
+msgid "Forgotten Password"
+msgstr "新的密ç "
+
+#: ..\..\..\populartags.php:54
+#: ..\..\..\templates\dynamictags.inc.php:101
+#: ..\..\..\templates\sidebar.block.common.php:9
+#: ..\..\..\templates\sidebar.block.popular.php:15
+#: ..\..\..\templates\sidebar.block.recent.php:25
+msgid "Popular Tags"
+msgstr "热门标签"
+
+#: ..\..\..\profile.php:54
+#: ..\..\..\watched.php:114
+msgid "Username was not specified"
+msgstr "没有æ供用户å"
+
+#: ..\..\..\profile.php:60
+#, fuzzy
+msgid "My Profile"
+msgstr "个人资料"
+
+#: ..\..\..\profile.php:62
+#: ..\..\..\templates\sidebar.block.profile.php:12
+msgid "Profile"
+msgstr "个人资料"
+
+#: ..\..\..\profile.php:80
+msgid "Password and confirmation do not match."
+msgstr "密ç å’Œç¡®è®¤å¯†ç ä¸ä¸€è‡´."
+
+#: ..\..\..\profile.php:84
+msgid "Password must be at least 6 characters long."
+msgstr "密ç è‡³å°‘6ä½."
+
+#: ..\..\..\profile.php:88
+msgid "E-mail address is not valid."
+msgstr "Email地å€ä¸åˆæ³•."
+
+#: ..\..\..\profile.php:92
+msgid "An error occurred while saving your changes."
+msgstr "ä¿å­˜ä¿®æ”¹æ—¶å‡ºé”™."
+
+#: ..\..\..\profile.php:94
+msgid "Changes saved."
+msgstr "ä¿å­˜ä¿®æ”¹æˆåŠŸ."
+
+#: ..\..\..\register.php:33
+#, fuzzy
+msgid "You <em>must</em> enter a username, password and e-mail address."
+msgstr "您 <em>å¿…é¡»</em> 输入用户å,密ç ,姓åå’Œ <abbr title=\"电å­é‚®ä»¶\">e-mail</abbr> 地å€."
+
+#: ..\..\..\register.php:37
+msgid "This username already exists, please make another choice."
+msgstr "用户åå·²ç»å­˜åœ¨ï¼Œè¯·é€‰æ‹©å…¶ä»–用户å."
+
+#: ..\..\..\register.php:41
+#, fuzzy
+msgid "E-mail address is not valid. Please try again."
+msgstr "Email地å€ä¸åˆæ³•."
+
+#: ..\..\..\register.php:50
+msgid "You have successfully registered. Enjoy!"
+msgstr "您已ç»æ³¨å†ŒæˆåŠŸ."
+
+#: ..\..\..\register.php:52
+msgid "Registration failed. Please try again."
+msgstr "注册失败,请é‡è¯•."
+
+#: ..\..\..\register.php:57
+#: ..\..\..\templates\register.tpl.php:32
+#: ..\..\..\templates\toolbar.inc.php:27
+msgid "Register"
+msgstr "注册"
+
+#: ..\..\..\search.inc.php:29
+#: ..\..\..\search.inc.php:57
+msgid "Search"
+msgstr "æœç´¢"
+
+#: ..\..\..\search.inc.php:35
+#, fuzzy
+msgid "this user's bookmarks"
+msgstr "%s 书签"
+
+#: ..\..\..\search.inc.php:40
+msgid "my bookmarks"
+msgstr "您的书签"
+
+#: ..\..\..\search.inc.php:41
+#, fuzzy
+msgid "my watchlist"
+msgstr "将用户加入到您的关注列表"
+
+#: ..\..\..\search.inc.php:45
+msgid "all bookmarks"
+msgstr "所有书签"
+
+#: ..\..\..\search.inc.php:48
+msgid "for"
+msgstr "关于"
+
+#: ..\..\..\search.php:91
+#: ..\..\..\search.php:128
+msgid "Search Bookmarks"
+msgstr "æœç´¢ä¹¦ç­¾"
+
+#: ..\..\..\search.php:97
+msgid "Search Results"
+msgstr "æœç´¢ç»“æžœ"
+
+#: ..\..\..\tags.php:38
+#: ..\..\..\templates\editbookmark.tpl.php:44
+#: ..\..\..\templates\sidebar.block.profile.php:13
+msgid "Tags"
+msgstr "标签"
+
+#: ..\..\..\watch.php:79
+#, php-format
+msgid "%s Bookmarks"
+msgstr "%s 书签"
+
+#: ..\..\..\watch.php:84
+msgid "User removed from your watchlist"
+msgstr "已将用户从您的关注列表中删除"
+
+#: ..\..\..\watch.php:86
+msgid "User added to your watchlist"
+msgstr "已将用户加入到您的关注列表中"
+
+#: ..\..\..\watched.php:105
+#, fuzzy
+msgid "My Watchlist"
+msgstr "我关注的其他用户"
+
+#: ..\..\..\watched.php:107
+#: ..\..\..\templates\sidebar.block.profile.php:14
+#: ..\..\..\templates\toolbar.inc.php:12
+#, fuzzy
+msgid "Watchlist"
+msgstr "我关注的其他用户"
+
+#: ..\..\..\templates\about.tpl.php:6
+msgid "<strong>Store</strong> all your favourite links in one place, accessible from anywhere."
+msgstr ""
+
+#: ..\..\..\templates\about.tpl.php:7
+msgid "<strong>Share</strong> your bookmarks with everyone, with friends on your watchlist or just keep them private."
+msgstr "您å¯ä»¥å°†æ‚¨æ”¶è—的书签资æºä¸Žæ‰€æœ‰æœ‹å‹åˆ†äº«ï¼Œä¹Ÿè®¸å› æ­¤å‘现与您志åŒé“åˆçš„朋å‹ã€‚或者ä¿å­˜ä¸ºåªèƒ½æ‚¨è‡ªå·±æŸ¥çœ‹çš„ç§æœ‰çŠ¶æ€"
+
+#: ..\..\..\templates\about.tpl.php:8
+msgid "<strong>Tag</strong> your bookmarks with as many labels as you want, instead of wrestling with folders."
+msgstr "您å¯ä»¥å°†æ‚¨è®¤ä¸ºä¼˜ç§€çš„站点用标签(Tag)定义,这是一ç§æ›´ä¸ºçµæ´»çš„分类形å¼ï¼Œæ–¹ä¾¿æ‚¨çš„å‘散记忆和管ç†ã€‚"
+
+#: ..\..\..\templates\about.tpl.php:9
+#, php-format
+msgid "<strong><a href=\"register.php\">Register now</a></strong> to start using %s!"
+msgstr ""
+
+#: ..\..\..\templates\about.tpl.php:12
+msgid "Geek Stuff"
+msgstr "致谢"
+
+#: ..\..\..\templates\about.tpl.php:14
+#, php-format
+msgid "%s is based on <a href=\"http://sourceforge.net/projects/scuttle/\">an open-source project</a> licensed under the <a href=\"http://www.gnu.org/copyleft/gpl.html\"><acronym title=\"GNU's Not Unix\">GNU</acronym> General Public License</a>. This means you can host it on your own web server for free, whether it is on the Internet, a private network or just your own computer."
+msgstr ""
+
+#: ..\..\..\templates\about.tpl.php:15
+#, php-format
+msgid "%1$s supports most of the <a href=\"http://del.icio.us/doc/api\">del.icio.us <abbr title=\"Application Programming Interface\">API</abbr></a>. Almost all of the neat tools made for that system can be modified to work with %1$s instead. If you find a tool that won't let you change the API address, ask the creator to add this setting. You never know, they might just do it."
+msgstr ""
+
+#: ..\..\..\templates\bookmarks.tpl.php:17
+#: ..\..\..\templates\tags.tpl.php:7
+msgid "Sort by:"
+msgstr "排åºæ–¹å¼:"
+
+#: ..\..\..\templates\bookmarks.tpl.php:18
+msgid "Date"
+msgstr "å‘布时间"
+
+#: ..\..\..\templates\bookmarks.tpl.php:19
+#: ..\..\..\templates\editbookmark.tpl.php:34
+msgid "Title"
+msgstr "书签标题"
+
+#: ..\..\..\templates\bookmarks.tpl.php:23
+msgid "URL"
+msgstr "URL网å€"
+
+#: ..\..\..\templates\bookmarks.tpl.php:60
+msgid "Edit"
+msgstr "编辑"
+
+#: ..\..\..\templates\bookmarks.tpl.php:60
+msgid "Delete"
+msgstr "删除"
+
+#: ..\..\..\templates\bookmarks.tpl.php:66
+msgid "by"
+msgstr ""
+
+#: ..\..\..\templates\bookmarks.tpl.php:78
+#, fuzzy, php-format
+msgid " and %s1 other%s"
+msgstr "åŒæ—¶è¢«å…¶ä»– %s 个用户收è—"
+
+#: ..\..\..\templates\bookmarks.tpl.php:81
+#, fuzzy, php-format
+msgid " and %2$s%1$s others%3$s"
+msgstr "åŒæ—¶è¢«å…¶ä»– %s 个用户收è—"
+
+#: ..\..\..\templates\bookmarks.tpl.php:90
+msgid "Copy"
+msgstr "å¤åˆ¶"
+
+#: ..\..\..\templates\bookmarks.tpl.php:136
+#: ..\..\..\templates\bookmarks.tpl.php:142
+msgid "First"
+msgstr ""
+
+#: ..\..\..\templates\bookmarks.tpl.php:137
+#: ..\..\..\templates\bookmarks.tpl.php:143
+msgid "Previous"
+msgstr "上一页"
+
+#: ..\..\..\templates\bookmarks.tpl.php:150
+#: ..\..\..\templates\bookmarks.tpl.php:153
+msgid "Next"
+msgstr "下一页"
+
+#: ..\..\..\templates\bookmarks.tpl.php:151
+#: ..\..\..\templates\bookmarks.tpl.php:154
+msgid "Last"
+msgstr ""
+
+#: ..\..\..\templates\bookmarks.tpl.php:156
+#, php-format
+msgid "Page %d of %d"
+msgstr "第 %d 页 / 共 %d 页"
+
+#: ..\..\..\templates\bookmarks.tpl.php:160
+msgid "No bookmarks available"
+msgstr "尚未有书签列入"
+
+#: ..\..\..\templates\dynamictags.inc.php:108
+#: ..\..\..\templates\sidebar.block.common.php:15
+#: ..\..\..\templates\sidebar.block.popular.php:21
+#: ..\..\..\templates\sidebar.block.recent.php:20
+#: ..\..\..\templates\tags.tpl.php:16
+msgid "bookmark"
+msgid_plural "bookmarks"
+msgstr[0] "书签"
+msgstr[1] "书签"
+
+#: ..\..\..\templates\editbookmark.tpl.php:29
+msgid "Address"
+msgstr "网å€"
+
+#: ..\..\..\templates\editbookmark.tpl.php:31
+#: ..\..\..\templates\editbookmark.tpl.php:36
+#: ..\..\..\templates\editprofile.tpl.php:31
+msgid "Required"
+msgstr "必填项目"
+
+#: ..\..\..\templates\editbookmark.tpl.php:39
+#: ..\..\..\templates\editprofile.tpl.php:47
+#: ..\..\..\templates\profile.tpl.php:28
+msgid "Description"
+msgstr "æè¿°"
+
+#: ..\..\..\templates\editbookmark.tpl.php:46
+msgid "Comma-separated"
+msgstr "以å•å­—节逗å·åˆ†å¼€"
+
+#: ..\..\..\templates\editbookmark.tpl.php:49
+#: ..\..\..\templates\importDelicious.tpl.php:15
+#: ..\..\..\templates\importNetscape.tpl.php:16
+msgid "Privacy"
+msgstr "ç§å¯†"
+
+#: ..\..\..\templates\editbookmark.tpl.php:52
+#: ..\..\..\templates\importDelicious.tpl.php:18
+#: ..\..\..\templates\importNetscape.tpl.php:19
+msgid "Public"
+msgstr "公开å‘布"
+
+#: ..\..\..\templates\editbookmark.tpl.php:53
+#: ..\..\..\templates\importDelicious.tpl.php:19
+#: ..\..\..\templates\importNetscape.tpl.php:20
+msgid "Shared with Watch List"
+msgstr "仅关注者"
+
+#: ..\..\..\templates\editbookmark.tpl.php:54
+#: ..\..\..\templates\importDelicious.tpl.php:20
+#: ..\..\..\templates\importNetscape.tpl.php:21
+msgid "Private"
+msgstr "仅本用户"
+
+#: ..\..\..\templates\editbookmark.tpl.php:66
+msgid "Delete Bookmark"
+msgstr "删除书签"
+
+#: ..\..\..\templates\editbookmark.tpl.php:93
+msgid "Bookmarklet"
+msgstr "Bookmarklet"
+
+#: ..\..\..\templates\editbookmark.tpl.php:94
+#, php-format
+msgid "Drag one of the following bookmarklets to your browser's bookmarks and click it whenever you want to add the page you are on to %s"
+msgstr "Bookmarklet是一个内å«ç®€å•JavaScript代ç çš„书签,使用的方法和您的æµè§ˆå™¨ä¸­çš„书签一样,ä¸åŒçš„地方是:书签是用æ¥è®°å½•æµè§ˆçš„ä½ç½®ï¼Œè€ŒBookmarklet则是记录æŸäº›å¯¹æ‚¨æ­£åœ¨æµè§ˆçš„页é¢è¿›è¡Œå¤„ç†çš„程åºå’Œæ–¹æ³•ã€‚<br>使用Bookmarklet之å‰ï¼Œæ‚¨æ— éœ€å¦å¤–安装或下载程å¼ï¼Œåªè¦ç®€å•çš„将如下链接加入您的æµè§ˆå™¨ä¹¦ç­¾æˆ–是收è—夹之中。 <br>选择如下Bookmarklet之一,并将其加入到您的æµè§ˆå™¨ä¹¦ç­¾ä¸­,当您æµè§ˆå¹¶å¸Œæœ›æ”¶è—其他网站页é¢æ—¶,åªéœ€ç‚¹å‡»æ‚¨çš„æµè§ˆå™¨ä¸­ Bookmarklet 书签,就会将您希望收è—的页é¢å‘布到 %s"
+
+#: ..\..\..\templates\editbookmark.tpl.php:106
+#, php-format
+msgid "Post to %s"
+msgstr "收è—到 %s"
+
+#: ..\..\..\templates\editbookmark.tpl.php:107
+#, php-format
+msgid "Post to %s (Pop-up)"
+msgstr "收è—到 %s(弹出窗å£ï¼‰ "
+
+#: ..\..\..\templates\editbookmark.tpl.php:111
+#: ..\..\..\templates\importDelicious.tpl.php:26
+#: ..\..\..\templates\importNetscape.tpl.php:27
+msgid "Import"
+msgstr "导入书签"
+
+#: ..\..\..\templates\editbookmark.tpl.php:113
+msgid "Import bookmarks from bookmark file"
+msgstr "导入(Internet Explorer, Mozilla Firefox and Netscape)æµè§ˆå™¨çš„书签文件"
+
+#: ..\..\..\templates\editbookmark.tpl.php:113
+msgid "Internet Explorer, Mozilla Firefox and Netscape"
+msgstr "Internet Explorer, Mozilla Firefox and Netscape"
+
+#: ..\..\..\templates\editbookmark.tpl.php:114
+msgid "Import bookmarks from del.icio.us"
+msgstr "导入del.icio.us的书签文件"
+
+#: ..\..\..\templates\editprofile.tpl.php:10
+msgid "Account Details"
+msgstr ""
+
+#: ..\..\..\templates\editprofile.tpl.php:14
+#: ..\..\..\templates\login.tpl.php:15
+#: ..\..\..\templates\password.tpl.php:10
+#: ..\..\..\templates\profile.tpl.php:7
+#: ..\..\..\templates\register.tpl.php:16
+msgid "Username"
+msgstr "用户å¸å·"
+
+#: ..\..\..\templates\editprofile.tpl.php:19
+msgid "New Password"
+msgstr "新的密ç "
+
+#: ..\..\..\templates\editprofile.tpl.php:24
+#, fuzzy
+msgid "Confirm Password"
+msgstr "确认密ç "
+
+#: ..\..\..\templates\editprofile.tpl.php:29
+#: ..\..\..\templates\register.tpl.php:26
+msgid "E-mail"
+msgstr "用户Email"
+
+#: ..\..\..\templates\editprofile.tpl.php:35
+msgid "Personal Details"
+msgstr ""
+
+#: ..\..\..\templates\editprofile.tpl.php:39
+#: ..\..\..\templates\profile.tpl.php:12
+msgid "Name"
+msgstr "用户全å"
+
+#: ..\..\..\templates\editprofile.tpl.php:43
+#: ..\..\..\templates\profile.tpl.php:18
+msgid "Homepage"
+msgstr "用户网站"
+
+#: ..\..\..\templates\error.404.tpl.php:5
+msgid "Not Found"
+msgstr "文件ä¸å­˜åœ¨"
+
+#: ..\..\..\templates\error.404.tpl.php:6
+msgid "The requested URL was not found on this server"
+msgstr "您指定的文件ä¸å­˜åœ¨ã€‚"
+
+#: ..\..\..\templates\error.500.tpl.php:5
+msgid "General server error"
+msgstr "一般性æœåŠ¡å™¨é”™è¯¯"
+
+#: ..\..\..\templates\error.500.tpl.php:6
+msgid "The requested URL could not be processed"
+msgstr "无法对您指定的文件进行导入æ“作。"
+
+#: ..\..\..\templates\importDelicious.tpl.php:33
+msgid "Log in to the <a href=\"http://del.icio.us/api/posts/all\">export page at del.icio.us</a>"
+msgstr "登录<a href=\"http://del.icio.us/api/posts/all\">del.icio.us</a>导出书签数æ®"
+
+#: ..\..\..\templates\importDelicious.tpl.php:34
+msgid "Save the resulting <abbr title=\"Extensible Markup Language\">XML</abbr> file to your computer"
+msgstr "ä¿å­˜<abbr title=\"Extensible Markup Language\">XML</abbr>文件到您的电脑中。"
+
+#: ..\..\..\templates\importDelicious.tpl.php:35
+msgid "Click <kbd>Browse...</kbd> to find this file on your computer. The maximum size the file can be is 1MB"
+msgstr "点击<kbd>æµè§ˆ...</kbd>在您的电脑中找到书签文件,最大å…许导入1Mbæ•°æ®"
+
+#: ..\..\..\templates\importDelicious.tpl.php:36
+#: ..\..\..\templates\importNetscape.tpl.php:43
+msgid "Select the default privacy setting for your imported bookmarks"
+msgstr "为导入的书签选择默认ç§å¯†è®¾ç½®"
+
+#: ..\..\..\templates\importDelicious.tpl.php:37
+#: ..\..\..\templates\importNetscape.tpl.php:44
+msgid "Click <kbd>Import</kbd> to start importing the bookmarks; it may take a minute"
+msgstr "点击<kbd>导入</kbd>书签开始导入,耗时1分钟左å³ã€‚"
+
+#: ..\..\..\templates\importNetscape.tpl.php:32
+msgid "Instructions"
+msgstr "步骤和导入方法"
+
+#: ..\..\..\templates\importNetscape.tpl.php:35
+msgid "Export your bookmarks from your browser to a file"
+msgstr "将您的æµè§ˆå™¨ä¹¦ç­¾æ•°æ®å¯¼å‡ºä¸ºä¸€ä¸ªæ–‡ä»¶"
+
+#: ..\..\..\templates\importNetscape.tpl.php:37
+msgid "Internet Explorer: <kbd>File &gt; Import and Export... &gt; Export Favorites"
+msgstr "Internet Explorer: <kbd>文件 &gt; 导入和导出... &gt; 导出收è—夹 "
+
+#: ..\..\..\templates\importNetscape.tpl.php:38
+msgid "Mozilla Firefox: <kbd>Bookmarks &gt; Manage Bookmarks... &gt; File &gt; Export..."
+msgstr "Mozilla Firefox: <kbd>书签 &gt; 管ç†ä¹¦ç­¾... &gt; 文件 &gt; 导出书签... "
+
+#: ..\..\..\templates\importNetscape.tpl.php:39
+msgid "Netscape: <kbd>Bookmarks &gt; Manage Bookmarks... &gt; Tools &gt; Export..."
+msgstr "Netscape: <kbd>书签 &gt; 管ç†ä¹¦ç­¾... &gt; 工具 &gt;> 导出书签... "
+
+#: ..\..\..\templates\importNetscape.tpl.php:42
+msgid "Click <kbd>Browse...</kbd> to find the saved bookmark file on your computer. The maximum size the file can be is 1MB"
+msgstr "点击<kbd>æµè§ˆ...</kbd> 在您的电脑中找到书签文件,最大å…许导入1Mbæ•°æ®"
+
+#: ..\..\..\templates\login.tpl.php:20
+#: ..\..\..\templates\register.tpl.php:21
+msgid "Password"
+msgstr "密ç "
+
+#: ..\..\..\templates\login.tpl.php:22
+msgid "Don't ask for my password for 2 weeks"
+msgstr "存储å¸å·å¯†ç ä¿¡æ¯2周"
+
+#: ..\..\..\templates\login.tpl.php:30
+msgid "Forgotten your password?"
+msgstr ""
+
+#: ..\..\..\templates\password.tpl.php:5
+#, php-format
+msgid "If you have forgotten your password, %s can generate a new one. Enter the username and e-mail address of your account into the form below and we will e-mail your new password to you."
+msgstr ""
+
+#: ..\..\..\templates\password.tpl.php:14
+msgid "<abbr title=\"Electronic mail\">E-mail</abbr>"
+msgstr "<abbr title=\"电å­é‚®ä»¶l\">E-mail</abbr>"
+
+#: ..\..\..\templates\password.tpl.php:19
+#, fuzzy
+msgid "Generate Password"
+msgstr "新的密ç "
+
+#: ..\..\..\templates\profile.tpl.php:23
+msgid "Member Since"
+msgstr "注册时间"
+
+#: ..\..\..\templates\profile.tpl.php:35
+#: ..\..\..\templates\sidebar.block.watchlist.php:8
+#, fuzzy
+msgid "Watching"
+msgstr "我关注的其他用户"
+
+#: ..\..\..\templates\profile.tpl.php:50
+msgid "Watched By"
+msgstr "关注该用户的其他用户"
+
+#: ..\..\..\templates\register.tpl.php:11
+#, php-format
+msgid "Sign up here to create a free %s account. All the information requested below is required"
+msgstr "您å¯ä»¥å…费注册æˆä¸º %s 的用户,请填写如下表å•:"
+
+#: ..\..\..\templates\rss.tpl.php:9
+#, php-format
+msgid "Recent bookmarks posted to %s"
+msgstr "最新å‘布到%s的书签"
+
+#: ..\..\..\templates\rss.tpl.php:17
+#: ..\..\..\templates\rss.tpl.php:19
+msgid "No bookmarks found"
+msgstr "尚无书签"
+
+#: ..\..\..\templates\sidebar.block.recent.php:15
+msgid "Recent Tags"
+msgstr "最新标签"
+
+#: ..\..\..\templates\sidebar.block.related.php:15
+msgid "Related Tags"
+msgstr "å…³è”标签"
+
+#: ..\..\..\templates\sidebar.block.watchstatus.php:10
+msgid "Remove from Watchlist"
+msgstr "将用户从您的关注列表中删除"
+
+#: ..\..\..\templates\sidebar.block.watchstatus.php:12
+msgid "Add to Watchlist"
+msgstr "将用户加入到您的关注列表"
+
+#: ..\..\..\templates\sidebar.block.watchstatus.php:17
+#, fuzzy
+msgid "Actions"
+msgstr "步骤和导入方法"
+
+#: ..\..\..\templates\tags.tpl.php:8
+msgid "Alphabet"
+msgstr ""
+
+#: ..\..\..\templates\tags.tpl.php:9
+#, fuzzy
+msgid "Popularity"
+msgstr "热门标签"
+
+#: ..\..\..\templates\toolbar.inc.php:11
+#, fuzzy
+msgid "Bookmarks"
+msgstr "%s 书签"
+
+#: ..\..\..\templates\toolbar.inc.php:16
+msgid "Log Out"
+msgstr "登出"
+
diff --git a/login.php b/login.php
new file mode 100644
index 0000000..4d212a9
--- /dev/null
+++ b/login.php
@@ -0,0 +1,53 @@
+<?php
+/***************************************************************************
+Copyright (C) 2004 - 2006 Scuttle project
+http://sourceforge.net/projects/scuttle/
+http://scuttle.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; 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
+***************************************************************************/
+
+require_once('header.inc.php');
+$userservice =& ServiceFactory::getServiceInstance('UserService');
+$templateservice =& ServiceFactory::getServiceInstance('TemplateService');
+
+$tplVars = array();
+
+$login = false;
+if (isset($_POST['submitted']) && isset($_POST['username']) && isset($_POST['password'])) {
+ $posteduser = trim(utf8_strtolower($_POST['username']));
+ $login = $userservice->login($posteduser, $_POST['password'], ($_POST['keeppass'] == "yes"));
+ if ($login) {
+ if ($_POST['query'])
+ header('Location: '. createURL('bookmarks', $posteduser .'?'. $_POST['query']));
+ else
+ header('Location: '. createURL('bookmarks', $posteduser));
+ } else {
+ $tplVars['error'] = T_('The details you have entered are incorrect. Please try again.');
+ }
+}
+if (!$login) {
+ if ($userservice->isLoggedOn()) {
+ $cUser = $userservice->getCurrentUser();
+ $cUsername = strtolower($cUser[$userservice->getFieldName('username')]);
+ header('Location: '. createURL('bookmarks', $cUsername));
+ }
+
+ $tplVars['subtitle'] = T_('Log In');
+ $tplVars['formaction'] = createURL('login');
+ $tplVars['querystring'] = filter($_SERVER['QUERY_STRING']);
+ $templateservice->loadTemplate('login.tpl', $tplVars);
+}
+?>
diff --git a/logo.png b/logo.png
new file mode 100644
index 0000000..4afe565
--- /dev/null
+++ b/logo.png
Binary files differ
diff --git a/logo_24.png b/logo_24.png
new file mode 100644
index 0000000..f450b78
--- /dev/null
+++ b/logo_24.png
Binary files differ
diff --git a/password.php b/password.php
new file mode 100644
index 0000000..b7daa70
--- /dev/null
+++ b/password.php
@@ -0,0 +1,72 @@
+<?
+/***************************************************************************
+Copyright (C) 2005 Scuttle project
+https://sourceforge.net/projects/scuttle/
+
+This program is free software; 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
+***************************************************************************/
+
+require_once('header.inc.php');
+$userservice =& ServiceFactory::getServiceInstance('UserService');
+$templateservice =& ServiceFactory::getServiceInstance('TemplateService');
+$tplVars = array();
+
+// IF SUBMITTED
+if ($_POST['submitted']) {
+
+ // NO USERNAME
+ if (!$_POST['username']) {
+ $tplVars['error'] = T_('You must enter your username.');
+
+ // NO E-MAIL
+ } elseif (!$_POST['email']) {
+ $tplVars['error'] = T_('You must enter your <abbr title="electronic mail">e-mail</abbr> address.');
+
+ // USERNAME AND E-MAIL
+ } else {
+
+ // NO MATCH
+ if (!($userinfo = $userservice->getUserByUsername($_POST['username']))) {
+ $tplVars['error'] = T_('No matches found for that username.');
+
+ } elseif ($_POST['email'] != $userinfo['email']) {
+ $tplVars['error'] = T_('No matches found for that combination of username and <abbr title="electronic mail">e-mail</abbr> address.');
+
+ // MATCH
+ } else {
+
+ // GENERATE AND STORE PASSWORD
+ $password = $userservice->generatePassword($userinfo['uId']);
+ if (!($password = $userservice->generatePassword($userinfo['uId']))) {
+ $tplVars['error'] = T_('There was an error while generating your new password. Please try again.');
+
+ } else {
+ // SEND E-MAIL
+ $message = T_('Your new password is:') ."\n". $password ."\n\n". T_('To keep your bookmarks secure, you should change this password in your profile the next time you log in.');
+ $message = wordwrap($message, 70);
+ $headers = 'From: '. $adminemail;
+ $mail = mail($_POST['email'], sprintf(T_('%s Account Information'), $sitename), $message);
+
+ $tplVars['msg'] = sprintf(T_('New password generated and sent to %s'), $_POST['email']);
+ }
+ }
+ }
+}
+
+$templatename = 'password.tpl';
+$tplVars['subtitle'] = T_('Forgotten Password');
+$tplVars['formaction'] = createURL('password');
+$templateservice->loadTemplate($templatename, $tplVars);
+?>
diff --git a/populartags.php b/populartags.php
new file mode 100644
index 0000000..daef205
--- /dev/null
+++ b/populartags.php
@@ -0,0 +1,86 @@
+<?php
+/***************************************************************************
+Copyright (C) 2004 - 2006 Scuttle project
+http://sourceforge.net/projects/scuttle/
+http://scuttle.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; 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
+***************************************************************************/
+
+require_once('header.inc.php');
+$templateservice =& ServiceFactory::getServiceInstance('TemplateService');
+$tagservice =& ServiceFactory::getServiceInstance('TagService');
+$userservice =& ServiceFactory::getServiceInstance('UserService');
+$cacheservice =& ServiceFactory::getServiceInstance('CacheService');
+
+list($url, $user) = explode('/', $_SERVER['PATH_INFO']);
+
+if ($usecache) {
+ // Generate hash for caching on
+ $hashtext = $_SERVER['REQUEST_URI'];
+ if ($userservice->isLoggedOn()) {
+ $hashtext .= $userservice->getCurrentUserID();
+ $currentUser = $userservice->getCurrentUser();
+ $currentUsername = $currentUser[$userservice->getFieldName('username')];
+ if ($currentUsername == $user) {
+ $hashtext .= $user;
+ }
+ }
+ $hash = md5($hashtext);
+
+ // Cache for an hour
+ $cacheservice->Start($hash, 3600);
+}
+
+// Header variables
+$tplvars = array();
+$pagetitle = T_('Popular Tags');
+
+if (isset($user) && $user != '') {
+ if (is_int($user)) {
+ $userid = intval($user);
+ } else {
+ if ($userinfo = $userservice->getUserByUsername($user)) {
+ $userid =& $userinfo[$userservice->getFieldName('primary')];
+ } else {
+ $tplVars['error'] = sprintf(T_('User with username %s was not found'), $user);
+ $templateservice->loadTemplate('error.404.tpl', $tplVars);
+ //throw a 404 error
+ exit();
+ }
+ }
+ $pagetitle .= ': '. ucfirst($user);
+} else {
+ $userid = NULL;
+}
+
+$tags = $tagservice->getPopularTags($userid, 150, $logged_on_userid);
+$tplVars['tags'] =& $tagservice->tagCloud($tags, 5, 90, 225, getSortOrder('alphabet_asc'));
+$tplVars['user'] = $user;
+
+if (isset($userid)) {
+ $tplVars['cat_url'] = createURL('bookmarks', '%s/%s');
+} else {
+ $tplVars['cat_url'] = createURL('tags', '%2$s');
+}
+
+$tplVars['subtitle'] = $pagetitle;
+$templateservice->loadTemplate('tags.tpl', $tplVars);
+
+if ($usecache) {
+ // Cache output if existing copy has expired
+ $cacheservice->End($hash);
+}
+?>
diff --git a/profile.php b/profile.php
new file mode 100644
index 0000000..d834144
--- /dev/null
+++ b/profile.php
@@ -0,0 +1,107 @@
+<?php
+/***************************************************************************
+Copyright (C) 2004 - 2006 Scuttle project
+http://sourceforge.net/projects/scuttle/
+http://scuttle.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; 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
+***************************************************************************/
+
+require_once('header.inc.php');
+$templateservice =& ServiceFactory::getServiceInstance('TemplateService');
+$userservice =& ServiceFactory::getServiceInstance('UserService');
+
+$tplVars = array();
+
+@list($url, $user) = isset($_SERVER['PATH_INFO']) ? explode('/', $_SERVER['PATH_INFO']) : NULL;
+
+$loggedon = false;
+if ($userservice->isLoggedOn()) {
+ $loggedon = true;
+ $currentUser = $userservice->getCurrentUser();
+ $currentUserID = $userservice->getCurrentUserId();
+ $currentUsername = $currentUser[$userservice->getFieldName('username')];
+}
+
+if ($user) {
+ if (is_int($user)) {
+ $userid = intval($user);
+ } else {
+ $user = urldecode($user);
+ if (!($userinfo = $userservice->getUserByUsername($user))) {
+ $tplVars['error'] = sprintf(T_('User with username %s was not found'), $user);
+ $templateservice->loadTemplate('error.404.tpl', $tplVars);
+ exit();
+ } else {
+ $userid =& $userinfo['uId'];
+ }
+ }
+} else {
+ $tplVars['error'] = T_('Username was not specified');
+ $templateservice->loadTemplate('error.404.tpl', $tplVars);
+ exit();
+}
+
+if ($user == $currentUsername) {
+ $title = T_('My Profile');
+} else {
+ $title = T_('Profile') .': '. $user;
+}
+$tplVars['pagetitle'] = $title;
+$tplVars['subtitle'] = $title;
+
+$tplVars['user'] = $user;
+$tplVars['userid'] = $userid;
+
+if (isset($_POST['submitted'])) {
+ $error = false;
+ $detPass = trim($_POST['pPass']);
+ $detPassConf = trim($_POST['pPassConf']);
+ $detName = trim($_POST['pName']);
+ $detMail = trim($_POST['pMail']);
+ $detPage = trim($_POST['pPage']);
+ $detDesc = filter($_POST['pDesc']);
+ if ($detPass != $detPassConf) {
+ $error = true;
+ $tplVars['error'] = T_('Password and confirmation do not match.');
+ }
+ if ($detPass != "" && strlen($detPass) < 6) {
+ $error = true;
+ $tplVars['error'] = T_('Password must be at least 6 characters long.');
+ }
+ if (!$userservice->isValidEmail($detMail)) {
+ $error = true;
+ $tplVars['error'] = T_('E-mail address is not valid.');
+ }
+ if (!$error) {
+ if (!$userservice->updateUser($userid, $detPass, $detName, $detMail, $detPage, $detDesc)) {
+ $tplvars['error'] = T_('An error occurred while saving your changes.');
+ } else {
+ $tplVars['msg'] = T_('Changes saved.');
+ }
+ }
+ $userinfo = $userservice->getUserByUsername($user);
+}
+
+if ($currentUserID != $userid) {
+ $templatename = 'profile.tpl.php';
+} else {
+ $templatename = 'editprofile.tpl.php';
+ $tplVars['formaction'] = createURL('profile', $user);
+}
+
+$tplVars['row'] = $userinfo;
+$templateservice->loadTemplate($templatename, $tplVars);
+?>
diff --git a/readme.txt b/readme.txt
new file mode 100644
index 0000000..636893f
--- /dev/null
+++ b/readme.txt
@@ -0,0 +1,86 @@
+Scuttle 0.7.2
+http://sourceforge.net/projects/scuttle/
+http://scuttle.org/
+
+Copyright (C) 2004 - 2006 Scuttle project
+Available under the GNU General Public License
+
+============
+INSTALLATION
+============
+
+* Use the SQL contained in tables.sql to create the necessary database tables. This file was written specifically for MySQL, so may need rewritten if you intend to use a different database system.
+
+* Edit config.inc.php.example and save the changes as a new config.inc.php file in the same directory.
+
+* Set the CHMOD permissions on the /cache/ subdirectory to 777
+
+[ See also: http://scuttle.org/wiki/doku.php?id=installation ]
+
+=========
+UPGRADING
+=========
+
+Instructions on how to upgrade from the last stable release of Scuttle are detailed on our Wiki:
+
+http://scuttle.org/wiki/doku.php?id=upgrading
+
+===
+API
+===
+
+Scuttle supports most of the del.icio.us API [ http://del.icio.us/doc/api ]. Almost all of the neat tools made for that system can be modified to work with your installation instead. If you find a tool that won't let you change the API address, ask the creator to add this setting. You never know, they might just do it.
+
+[ See also: http://scuttle.org/wiki/doku.php?id=scuttle_api ]
+
+============
+TRANSLATIONS
+============
+
+Scuttle is available in many languages. If you know gettext and can provide additional translations, your help would be greatly appreciated.
+
+-------------------
+Available languages
+-------------------
+English en-GB 100% (Default)
+Chinese zh-CN 86%
+Danish dk-DK 100%
+Dutch nl-NL 68%
+French fr-FR 100%
+German de-DE 100%
+Hindi hi-IN 100%
+Italian it-IT 89%
+Japanese ja-JP 100%
+Lithuanian lt-LT 100%
+Portuguese pt-BR 100%
+Spanish es-ES 94%
+
+[ See also: http://scuttle.org/wiki/doku.php?id=translations ]
+
+=============
+PROJECT LINKS
+=============
+
+Scuttle Project:
+http://sourceforge.net/projects/scuttle/
+
+Scuttle.org:
+http://scuttle.org/
+
+Scuttle Wiki:
+http://scuttle.org/wiki/
+
+Help forum:
+https://sourceforge.net/forum/forum.php?forum_id=455068
+
+Bug reports:
+https://sourceforge.net/tracker/?atid=729860&group_id=134378&func=browse
+
+Feature requests:
+https://sourceforge.net/tracker/?atid=729863&group_id=134378&func=browse
+
+User-submitted patches:
+https://sourceforge.net/tracker/?atid=729862&group_id=134378&func=browse
+
+Discussion forum:
+https://sourceforge.net/forum/forum.php?forum_id=455067
diff --git a/register.php b/register.php
new file mode 100644
index 0000000..8549d05
--- /dev/null
+++ b/register.php
@@ -0,0 +1,64 @@
+<?php
+/***************************************************************************
+Copyright (C) 2004 - 2006 Marcus Campbell
+http://sourceforge.net/projects/scuttle/
+http://scuttle.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; 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
+***************************************************************************/
+
+require_once('header.inc.php');
+$userservice =& ServiceFactory::getServiceInstance('UserService');
+$templateservice =& ServiceFactory::getServiceInstance('TemplateService');
+
+$tplVars = array();
+
+if ($_POST['submitted']) {
+ $posteduser = trim(utf8_strtolower($_POST['username']));
+
+ // Check if form is incomplete
+ if (!($posteduser) || !($_POST['password']) || !($_POST['email'])) {
+ $tplVars['error'] = T_('You <em>must</em> enter a username, password and e-mail address.');
+
+ // Check if username is reserved
+ } elseif ($userservice->isReserved($posteduser)) {
+ $tplVars['error'] = T_('This username has been reserved, please make another choice.');
+
+ // Check if username already exists
+ } elseif ($userservice->getUserByUsername($posteduser)) {
+ $tplVars['error'] = T_('This username already exists, please make another choice.');
+
+ // Check if e-mail address is valid
+ } elseif (!$userservice->isValidEmail($_POST['email'])) {
+ $tplVars['error'] = T_('E-mail address is not valid. Please try again.');
+
+ // Register details
+ } elseif ($userservice->addUser($posteduser, $_POST['password'], $_POST['email'])) {
+ // Log in with new username
+ $login = $userservice->login($posteduser, $_POST['password']);
+ if ($login) {
+ header('Location: '. createURL('bookmarks', $posteduser));
+ }
+ $tplVars['msg'] = T_('You have successfully registered. Enjoy!');
+ } else {
+ $tplVars['error'] = T_('Registration failed. Please try again.');
+ }
+}
+
+$tplVars['loadjs'] = true;
+$tplVars['subtitle'] = T_('Register');
+$tplVars['formaction'] = createURL('register');
+$templateservice->loadTemplate('register.tpl', $tplVars);
+?>
diff --git a/rss.gif b/rss.gif
new file mode 100644
index 0000000..094ba10
--- /dev/null
+++ b/rss.gif
Binary files differ
diff --git a/rss.php b/rss.php
new file mode 100644
index 0000000..fc35e40
--- /dev/null
+++ b/rss.php
@@ -0,0 +1,115 @@
+<?php
+/***************************************************************************
+Copyright (C) 2004 - 2006 Scuttle project
+http://sourceforge.net/projects/scuttle/
+http://scuttle.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; 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
+***************************************************************************/
+
+require_once('header.inc.php');
+$bookmarkservice =& ServiceFactory::getServiceInstance('BookmarkService');
+$cacheservice =& ServiceFactory::getServiceInstance('CacheService');
+$templateservice =& ServiceFactory::getServiceInstance('TemplateService');
+$userservice =& ServiceFactory::getServiceInstance('UserService');
+
+$tplVars = array();
+header('Content-Type: application/xml');
+list($url, $user, $cat) = explode('/', $_SERVER['PATH_INFO']);
+
+if ($usecache) {
+ // Generate hash for caching on
+ $hashtext = $_SERVER['REQUEST_URI'];
+ if ($userservice->isLoggedOn()) {
+ $hashtext .= $userservice->getCurrentUserID();
+ $currentUser = $userservice->getCurrentUser();
+ $currentUsername = $currentUser[$userservice->getFieldName('username')];
+ if ($currentUsername == $user) {
+ $hashtext .= $user;
+ }
+ }
+ $hash = md5($hashtext);
+
+ // Cache for an hour
+ $cacheservice->Start($hash, 3600);
+}
+
+$watchlist = null;
+if ($user && $user != 'all') {
+ if ($user == 'watchlist') {
+ $user = $cat;
+ $cat = null;
+ $watchlist = true;
+ }
+ if (is_int($user)) {
+ $userid = intval($user);
+ } else {
+ if ($userinfo = $userservice->getUserByUsername($user)) {
+ $userid =& $userinfo[$userservice->getFieldName('primary')];
+ } else {
+ $tplVars['error'] = sprintf(T_('User with username %s was not found'), $user);
+ $templateservice->loadTemplate('error.404.tpl', $tplVars);
+ //throw a 404 error
+ exit();
+ }
+ }
+ $pagetitle .= ": ". $user;
+} else {
+ $userid = NULL;
+}
+
+if ($cat) {
+ $pagetitle .= ": ". str_replace('+', ' + ', $cat);
+}
+
+$tplVars['feedtitle'] = filter($GLOBALS['sitename'] . (isset($pagetitle) ? $pagetitle : ''));
+$tplVars['feedlink'] = $GLOBALS['root'];
+$tplVars['feeddescription'] = sprintf(T_('Recent bookmarks posted to %s'), $GLOBALS['sitename']);
+
+$bookmarks =& $bookmarkservice->getBookmarks(0, 15, $userid, $cat, NULL, getSortOrder(), $watchlist);
+$bookmarks_tmp =& filter($bookmarks['bookmarks']);
+
+$bookmarks_tpl = array();
+foreach(array_keys($bookmarks_tmp) as $key) {
+ $row =& $bookmarks_tmp[$key];
+
+ $_link = $row['bAddress'];
+ // Redirection option
+ if ($GLOBALS['useredir']) {
+ $_link = $GLOBALS['url_redir'] . $_link;
+ }
+ $_pubdate = gmdate("r", strtotime($row['bDatetime']));
+ // array_walk($row['tags'], 'filter');
+
+ $bookmarks_tpl[] = array(
+ 'title' => $row['bTitle'],
+ 'link' => $_link,
+ 'description' => $row['bDescription'],
+ 'creator' => $row['username'],
+ 'pubdate' => $_pubdate,
+ 'tags' => $row['tags']
+ );
+}
+unset($bookmarks_tmp);
+unset($bookmarks);
+$tplVars['bookmarks'] =& $bookmarks_tpl;
+
+$templateservice->loadTemplate('rss.tpl', $tplVars);
+
+if ($usecache) {
+ // Cache output if existing copy has expired
+ $cacheservice->End($hash);
+}
+?>
diff --git a/scuttle.css b/scuttle.css
new file mode 100644
index 0000000..0d7ab2b
--- /dev/null
+++ b/scuttle.css
@@ -0,0 +1,436 @@
+/* BASE */
+
+* {
+ font-family: "trebuchet ms", tahoma, sans-serif;
+}
+a {
+ color: #47A;
+ text-decoration: none;
+}
+a:hover {
+ color: #258;
+ text-decoration: underline;
+}
+a img {
+ border: 0;
+}
+body {
+ margin: 0;
+ padding: 0;
+}
+input[type=text],
+input[type=password],
+select,
+textarea {
+ border: 1px solid #AAA;
+ padding: 0.1em;
+}
+input[type=text],
+input[type=password],
+textarea {
+ padding: 0.2em;
+}
+input[type=text]:focus,
+input[type=password]:focus,
+select:focus,
+textarea:focus {
+ border-color: #666;
+}
+p.error,
+p.success {
+ border: 1px solid;
+ font-size: small;
+ margin: 0.5em;
+ padding: 0.5em;
+ width: 70%;
+}
+p.error {
+ background: #FCC;
+ border-color: #966;
+ color: #633;
+}
+p.success {
+ background: #CFC;
+ border-color: #696;
+ color: #363;
+}
+td#availability {
+ color: #285;
+ font-weight: bold;
+}
+td#availability.not-available {
+ color: #F00;
+}
+textarea {
+ font-size: small;
+ padding: 0.2em;
+}
+th {
+ padding-right: 1em;
+ text-align: right;
+}
+
+/* HEADER */
+
+div#header {
+ background: #FFF url('bg_header.png') bottom repeat-x;
+ border-bottom: 3px solid #9CD;
+ clear: both;
+}
+div#header:after {
+ content: ".";
+ display: block;
+ height: 0;
+ clear: both;
+ visibility: hidden;
+}
+* html div#header {
+ height: 1%;
+}
+h1 {
+ float: left;
+ font-size: x-large;
+ font-weight: bold;
+ letter-spacing: 0.25em;
+ margin: 0;
+ padding: 1em;
+ text-transform: lowercase;
+}
+html > body h1 {
+ background: url('logo.png') no-repeat 10px;
+ padding-left: 75px;
+}
+html > body div#header.popup h1 {
+ background: url('logo_24.png') no-repeat 10px;
+ padding: 0.5em 0.5em 0.5em 50px;
+}
+h1 a {
+ color: #000;
+}
+h1 a:hover {
+ color: #000;
+}
+h2 {
+ background: #666 url('bg_bar.png') center center repeat-x;
+ border-bottom: 3px solid #DDD;
+ clear: both;
+ color: #DDD;
+ font-size: medium;
+ letter-spacing: 0.1em;
+ margin: 0 0 1em 0;
+ padding: 0.5em 1em;
+ text-transform: lowercase;
+}
+
+/* NAVIGATION */
+
+ul#navigation {
+ list-style-type: none;
+ margin: 0;
+ padding: 1.75em 1em;
+ text-transform: lowercase;
+ width: auto;
+}
+ul#navigation a {
+ font-size: medium;
+ font-weight: bold;
+ padding: 0.2em 0.5em;
+}
+ul#navigation a:hover {
+ background: #7AD;
+ color: #FFF;
+}
+ul#navigation li {
+ float: left;
+}
+ul#navigation li.access {
+ float: right;
+}
+
+/* BOOKMARKS */
+
+ol#bookmarks {
+ list-style-type: none;
+ margin: 0;
+ padding: 0 1em;
+ width: 70%;
+}
+html > body ol#bookmarks {
+ margin: 0 1em;
+ padding: 0;
+}
+div.link a {
+ color: blue;
+ font-size: medium;
+}
+div.link a:visited {
+ color: purple;
+}
+div.meta {
+ color: #285;
+}
+div.meta span {
+ color: #F00;
+}
+li.xfolkentry {
+ border-bottom: 1px solid #DDD;
+ margin-bottom: 0;
+ padding: 1em 0.5em;
+}
+html > body li.xfolkentry {
+ border-bottom: 1px dotted #AAA;
+}
+li.xfolkentry div {
+ padding: 0.1em;
+}
+li.xfolkentry.deleted {
+ opacity: 0.5;
+}
+li.xfolkentry.private {
+ border-left: 3px solid #F00;
+}
+li.xfolkentry.shared {
+ border-left: 3px solid #FA0;
+}
+
+/* SIDEBAR */
+
+div#sidebar {
+ font-size: small;
+ position: absolute;
+ right: 1em;
+ top: 10em;
+ width: 25%;
+}
+div#sidebar a {
+ color: #995;
+}
+div#sidebar a:hover {
+ color: #773;
+}
+div#sidebar div {
+ background: #FFF url('bg_sidebar.png') bottom repeat-x;
+ border: 1px solid #CC8;
+ color: #555;
+ margin-bottom: 1em;
+}
+div#sidebar h2 {
+ background: transparent;
+ border: 0;
+ color: #995;
+ letter-spacing: 0;
+ margin: 0;
+ padding: 0.5em 0;
+}
+div#sidebar hr {
+ display: none;
+}
+div#sidebar p {
+ margin: 1em;
+}
+div#sidebar p.tags a {
+ margin: 0;
+}
+div#sidebar table {
+ margin: 0.5em 0.5em 0 0.5em;
+}
+div#sidebar table td {
+ padding-bottom: 0.25em;
+ padding-right: 0.5em;
+}
+div#sidebar ul {
+ list-style-type: none;
+ margin: 0;
+ padding: 0.5em;
+}
+div#sidebar ul li {
+ margin: 0.5em 0;
+}
+
+/* TAGS */
+
+p.tags {
+ line-height: 2.25em;
+ margin: 2em 10%;
+ text-align: justify;
+ vertical-align: middle;
+}
+p.tags a,
+p.tags span {
+ color: #47A;
+ margin-right: 0.5em;
+}
+p.tags span:hover {
+ cursor: pointer;
+ text-decoration: underline;
+}
+p.tags span.selected {
+ background: #CEC;
+}
+
+/* PROFILE */
+
+table.profile th {
+ width: 10em;
+}
+
+/* OTHER GUFF */
+
+dd {
+ background: #CEC;
+ border-right: 4px solid #ACA;
+ color: #464;
+ padding: 6px;
+}
+dd a {
+ color: #464;
+}
+dd a:hover {
+ color: #000 !important;
+ text-decoration: underline !important;
+}
+
+dl {
+ font-size: small;
+ margin: 1em;
+ width: 70%;
+}
+dl#profile dd {
+ background: #CDE;
+ border-color: #ABC;
+ color: #247;
+}
+dl#profile dt {
+ background: #BCE;
+ border-color: #9AC;
+ color: #245;
+ display: block;
+ font-weight: bold;
+ padding: 6px;
+}
+dl#profile a {
+ color: #446;
+}
+dl#profile a:hover {
+ color: #000 !important;
+ text-decoration: underline !important;
+}
+dl#meta dd {
+ line-height: 1.5em;
+}
+dl#meta dt {
+ background: #BDB;
+ color: #353;
+ display: block;
+ font-weight: bold;
+ padding: 6px;
+}
+dt {
+ border-right: 4px solid #9B9;
+}
+dt a {
+ background: #BDB;
+ color: #353;
+ display: block;
+ font-weight: bold;
+ padding: 6px;
+}
+dt a:hover {
+ background: #ACA;
+ border: 0;
+}
+form {
+ margin: 0;
+}
+form#search {
+ background: #FFF;
+ color: #555;
+ font-size: small;
+ margin-bottom: 1em;
+}
+form label,
+form td,
+form th {
+ font-size: small;
+}
+form table {
+ margin: 0 1em;
+}
+h3 {
+ background: #DDD;
+ color: #555;
+ font-size: small;
+ letter-spacing: 0.2em;
+ margin: 2em 1em 1em 1em;
+ padding: 0.25em 0.75em;
+}
+li {
+ font-size: small;
+ margin-bottom: 0.5em;
+}
+p {
+ font-size: small;
+ margin: 1em;
+}
+p#sort {
+ color: #CCC;
+ font-size: small;
+ float: right;
+ margin: 0;
+ position: absolute;
+ right: 0;
+ top: 7em;
+}
+html > body p#sort {
+ margin-right: 0.75em;
+}
+p#sort a {
+ background: #AAA;
+ color: #555;
+ font-weight: normal;
+ margin-right: 0.5em;
+ padding: 0 1em;
+}
+html > body p#sort a {
+ margin-right: 0;
+}
+p#sort a:hover {
+ background: #CCC;
+ text-decoration: none !important;
+}
+p#sort span {
+ display: none;
+}
+p.paging {
+ font-size: small;
+ margin-left: 1em;
+}
+p.paging a,
+p.paging span.disable {
+ background: #888;
+ color: #FFF;
+ display: inline;
+ margin-right: 0.5em;
+ padding: 0.25em 1em;
+}
+p.paging a:hover {
+ background: #666;
+}
+p.paging span {
+ display: none;
+}
+p.paging span.disable {
+ background: #DDD;
+ color: #AAA;
+}
+div.collapsible p.tags {
+ line-height: 2.25em;
+ margin: 1em 2em;
+}
+th label {
+ padding-right: 1em;
+}
+ul {
+ margin-right: 1em;
+ width: 75%;
+}
diff --git a/search.inc.php b/search.inc.php
new file mode 100644
index 0000000..1c2cbc3
--- /dev/null
+++ b/search.inc.php
@@ -0,0 +1,44 @@
+<form id="search" action="<?php echo createURL('search'); ?>" method="post">
+ <table>
+ <tr>
+ <?php
+ $logged_on = false;
+ if ($userservice->isLoggedOn()) {
+ $currentUser = $userservice->getCurrentUser();
+ $currentUsername = $currentUser[$userservice->getFieldName('username')];
+ $logged_on = true;
+ }
+ if ($logged_on || isset($user)) {
+ ?>
+ <td><?php echo T_('Search' /* Search ... for */); ?></td>
+ <td>
+ <select name="range">
+ <?php
+ if (!in_array($range, array($currentUsername, 'all', 'watchlist'))) {
+ ?>
+ <option value="<?php echo $user ?>"<?php echo $selectUser; ?>><?php echo T_("this user's bookmarks"); ?></option>
+ <?php
+ }
+ if ($logged_on) {
+ ?>
+ <option value="<?php echo $currentUsername; ?>"<?php echo $selectMy; ?>><?php echo T_('my bookmarks'); ?></option>
+ <option value="watchlist"<?php echo $select_watchlist; ?>><?php echo T_('my watchlist'); ?></option>
+ <?php
+ }
+ ?>
+ <option value="all"<?php echo $select_all; ?>><?php echo T_('all bookmarks'); ?></option>
+ </select>
+ </td>
+ <td><?php echo T_('for' /* Search ... for */); ?></td>
+ <?php
+ } else {
+ ?>
+ <td><input type="hidden" name="range" value="all" /></td>
+ <?php
+ }
+ ?>
+ <td><input type="text" name="terms" size="50" value="<?php echo filter($terms); ?>" /></td>
+ <td><input type="submit" value="<?php echo T_('Search' /* Submit button */); ?>" /></td>
+ </tr>
+ </table>
+</form>
diff --git a/search.php b/search.php
new file mode 100644
index 0000000..2c88f91
--- /dev/null
+++ b/search.php
@@ -0,0 +1,113 @@
+<?php
+/***************************************************************************
+Copyright (C) 2005 - 2006 Scuttle project
+http://sourceforge.net/projects/scuttle/
+http://scuttle.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; 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
+***************************************************************************/
+
+require_once('header.inc.php');
+
+// POST
+if (isset($_POST['terms'])) {
+ // Redirect to GET
+ header('Location: '. createURL('search', $_POST['range'] .'/'. filter($_POST['terms'], 'url')));
+
+// GET
+} else {
+ $bookmarkservice =& ServiceFactory::getServiceInstance('BookmarkService');
+ $templateservice =& ServiceFactory::getServiceInstance('TemplateService');
+ $userservice =& ServiceFactory::getServiceInstance('UserService');
+
+ $logged_on_userid = $userservice->getCurrentUserId();
+ list($url, $range, $terms, $page) = explode('/', $_SERVER['PATH_INFO']);
+
+ $tplvars = array();
+ $tplVars['loadjs'] = true;
+
+ // Pagination
+ $perpage = getPerPageCount();
+ if (isset($_GET['page']) && intval($_GET['page']) > 1) {
+ $page = $_GET['page'];
+ $start = ($page - 1) * $perpage;
+ } else {
+ $page = 0;
+ $start = 0;
+ }
+
+ $s_user = NULL;
+ $s_start = NULL;
+ $s_end = NULL;
+ $s_watchlist = NULL;
+
+ // No search terms
+ if (is_null($terms)) {
+ $tplVars['subtitle'] = T_('Search Bookmarks');
+ $s_start = date('Y-m-d H:i:s', strtotime($dtend .' -'. $defaultRecentDays .' days'));
+ $s_end = date('Y-m-d H:i:s', strtotime('tomorrow'));
+
+ // Search terms
+ } else {
+ $tplVars['subtitle'] = T_('Search Results');
+ $selected = ' selected="selected"';
+
+ switch ($range) {
+ case 'all':
+ $tplVars['select_all'] = $selected;
+ $s_user = NULL;
+ break;
+ case 'watchlist':
+ $tplVars['select_watchlist'] = $selected;
+ $s_user = $logged_on_userid;
+ $s_watchlist = true;
+ break;
+ default:
+ $s_user = $range;
+ break;
+ }
+
+ if (isset($s_user)) {
+ if (is_numeric($s_user)) {
+ $s_user = intval($s_user);
+ } else {
+ if (!($userinfo = $userservice->getUserByUsername($s_user) ) ) {
+ $tplVars['error'] = sprintf(T_('User with username %s was not found'), $s_user);
+ $templateservice->loadTemplate('error.404.tpl', $tplVars);
+ exit();
+ } else {
+ $s_user =& $userinfo[$userservice->getFieldName('primary')];
+ }
+ }
+ }
+ }
+ $bookmarks =& $bookmarkservice->getBookmarks($start, $perpage, $s_user, NULL, $terms, getSortOrder(), $s_watchlist, $s_start, $s_end);
+
+ $tplVars['page'] = $page;
+ $tplVars['start'] = $start;
+ $tplVars['popCount'] = 25;
+ $tplVars['sidebar_blocks'] = array('recent');
+ $tplVars['range'] = $range;
+ $tplVars['terms'] = $terms;
+ $tplVars['pagetitle'] = T_('Search Bookmarks');
+ $tplVars['bookmarkCount'] = $start + 1;
+ $tplVars['total'] = $bookmarks['total'];
+ $tplVars['bookmarks'] =& $bookmarks['bookmarks'];
+ $tplVars['cat_url'] = createURL('tags', '%2$s');
+ $tplVars['nav_url'] = createURL('search', $range .'/'. $terms .'/%3$s');
+
+ $templateservice->loadTemplate('bookmarks.tpl', $tplVars);
+}
+?>
diff --git a/services/bookmarkservice.php b/services/bookmarkservice.php
new file mode 100644
index 0000000..afc7179
--- /dev/null
+++ b/services/bookmarkservice.php
@@ -0,0 +1,416 @@
+<?php
+class BookmarkService {
+ var $db;
+
+ function & getInstance(& $db) {
+ static $instance;
+ if (!isset ($instance))
+ $instance = & new BookmarkService($db);
+ return $instance;
+ }
+
+ function BookmarkService(& $db) {
+ $this->db = & $db;
+ }
+
+ function _getbookmark($fieldname, $value, $all = false) {
+ if (!$all) {
+ $userservice = & ServiceFactory :: getServiceInstance('UserService');
+ $sId = $userservice->getCurrentUserId();
+ $range = ' AND uId = '. $sId;
+ }
+
+ $query = 'SELECT * FROM '. $GLOBALS['tableprefix'] .'bookmarks WHERE '. $fieldname .' = "'. $this->db->sql_escape($value) .'"'. $range;
+
+ if (!($dbresult = & $this->db->sql_query_limit($query, 1, 0))) {
+ message_die(GENERAL_ERROR, 'Could not get bookmark', '', __LINE__, __FILE__, $query, $this->db);
+ return false;
+ }
+
+ if ($row =& $this->db->sql_fetchrow($dbresult)) {
+ return $row;
+ } else {
+ return false;
+ }
+ }
+
+ function & getBookmark($bid, $include_tags = false) {
+ if (!is_numeric($bid))
+ return;
+
+ $sql = 'SELECT * FROM '. $GLOBALS['tableprefix'] .'bookmarks WHERE bId = '. $this->db->sql_escape($bid);
+
+ if (!($dbresult = & $this->db->sql_query($sql)))
+ message_die(GENERAL_ERROR, 'Could not get vars', '', __LINE__, __FILE__, $sql, $this->db);
+
+ if ($row = & $this->db->sql_fetchrow($dbresult)) {
+ if ($include_tags) {
+ $tagservice = & ServiceFactory :: getServiceInstance('TagService');
+ $row['tags'] = $tagservice->getTagsForBookmark($bid);
+ }
+ return $row;
+ } else {
+ return false;
+ }
+ }
+
+ function getBookmarkByAddress($address) {
+ $hash = md5($address);
+ return $this->getBookmarkByHash($hash);
+ }
+
+ function getBookmarkByHash($hash) {
+ return $this->_getbookmark('bHash', $hash, true);
+ }
+
+ function editAllowed($bookmark) {
+ if (!is_numeric($bookmark) && (!is_array($bookmark) || !is_numeric($bookmark['bId'])))
+ return false;
+
+ if (!is_array($bookmark))
+ if (!($bookmark = $this->getBookmark($bookmark)))
+ return false;
+
+ $userservice = & ServiceFactory :: getServiceInstance('UserService');
+ $userid = $userservice->getCurrentUserId();
+ if ($userservice->isAdmin($userid))
+ return true;
+ else
+ return ($bookmark['uId'] == $userid);
+ }
+
+ function bookmarkExists($address = false, $uid = NULL) {
+ if (!$address) {
+ return;
+ }
+
+ // If address doesn't contain ":", add "http://" as the default protocol
+ if (strpos($address, ':') === false) {
+ $address = 'http://'. $address;
+ }
+
+ $crit = array ('bHash' => md5($address));
+ if (isset ($uid)) {
+ $crit['uId'] = $uid;
+ }
+
+ $sql = 'SELECT COUNT(*) FROM '. $GLOBALS['tableprefix'] .'bookmarks WHERE '. $this->db->sql_build_array('SELECT', $crit);
+ if (!($dbresult = & $this->db->sql_query($sql))) {
+ message_die(GENERAL_ERROR, 'Could not get vars', '', __LINE__, __FILE__, $sql, $this->db);
+ }
+ return ($this->db->sql_fetchfield(0, 0) > 0);
+ }
+
+ // Adds a bookmark to the database.
+ // Note that date is expected to be a string that's interpretable by strtotime().
+ function addBookmark($address, $title, $description, $status, $categories, $date = NULL, $fromApi = false, $fromImport = false) {
+ $userservice = & ServiceFactory :: getServiceInstance('UserService');
+ $sId = $userservice->getCurrentUserId();
+
+ // If bookmark address doesn't contain ":", add "http://" to the start as a default protocol
+ if (strpos($address, ':') === false) {
+ $address = 'http://'. $address;
+ }
+
+ // Get the client's IP address and the date; note that the date is in GMT.
+ if (getenv('HTTP_CLIENT_IP'))
+ $ip = getenv('HTTP_CLIENT_IP');
+ else
+ if (getenv('REMOTE_ADDR'))
+ $ip = getenv('REMOTE_ADDR');
+ else
+ $ip = getenv('HTTP_X_FORWARDED_FOR');
+
+ // Note that if date is NULL, then it's added with a date and time of now, and if it's present,
+ // it's expected to be a string that's interpretable by strtotime().
+ if (is_null($date))
+ $time = time();
+ else
+ $time = strtotime($date);
+ $datetime = gmdate('Y-m-d H:i:s', $time);
+
+ // Set up the SQL insert statement and execute it.
+ $values = array('uId' => intval($sId), 'bIp' => $ip, 'bDatetime' => $datetime, 'bModified' => $datetime, 'bTitle' => $title, 'bAddress' => $address, 'bDescription' => $description, 'bStatus' => intval($status), 'bHash' => md5($address));
+ $sql = 'INSERT INTO '. $GLOBALS['tableprefix'] .'bookmarks '. $this->db->sql_build_array('INSERT', $values);
+ $this->db->sql_transaction('begin');
+ if (!($dbresult = & $this->db->sql_query($sql))) {
+ $this->db->sql_transaction('rollback');
+ message_die(GENERAL_ERROR, 'Could not insert bookmark', '', __LINE__, __FILE__, $sql, $this->db);
+ return false;
+ }
+ // Get the resultant row ID for the bookmark.
+ $bId = $this->db->sql_nextid($dbresult);
+ if (!isset($bId) || !is_int($bId)) {
+ $this->db->sql_transaction('rollback');
+ message_die(GENERAL_ERROR, 'Could not insert bookmark', '', __LINE__, __FILE__, $sql, $this->db);
+ return false;
+ }
+
+ $uriparts = explode('.', $address);
+ $extension = end($uriparts);
+ unset($uriparts);
+
+ $tagservice = & ServiceFactory :: getServiceInstance('TagService');
+ if (!$tagservice->attachTags($bId, $categories, $fromApi, $extension, false, $fromImport)) {
+ $this->db->sql_transaction('rollback');
+ message_die(GENERAL_ERROR, 'Could not insert bookmark', '', __LINE__, __FILE__, $sql, $this->db);
+ return false;
+ }
+ $this->db->sql_transaction('commit');
+ // Everything worked out, so return the new bookmark's bId.
+ return $bId;
+ }
+
+ function updateBookmark($bId, $address, $title, $description, $status, $categories, $date = NULL, $fromApi = false) {
+ if (!is_numeric($bId))
+ return false;
+
+ // Get the client's IP address and the date; note that the date is in GMT.
+ if (getenv('HTTP_CLIENT_IP'))
+ $ip = getenv('HTTP_CLIENT_IP');
+ else
+ if (getenv('REMOTE_ADDR'))
+ $ip = getenv('REMOTE_ADDR');
+ else
+ $ip = getenv('HTTP_X_FORWARDED_FOR');
+
+ $moddatetime = gmdate('Y-m-d H:i:s', time());
+
+ // Set up the SQL update statement and execute it.
+ $updates = array('bModified' => $moddatetime, 'bTitle' => $title, 'bAddress' => $address, 'bDescription' => $description, 'bStatus' => $status, 'bHash' => md5($address));
+
+ if (!is_null($date)) {
+ $datetime = gmdate('Y-m-d H:i:s', strtotime($date));
+ $updates[] = array('bDateTime' => $datetime);
+ }
+
+ $sql = 'UPDATE '. $GLOBALS['tableprefix'] .'bookmarks SET '. $this->db->sql_build_array('UPDATE', $updates) .' WHERE bId = '. intval($bId);
+ $this->db->sql_transaction('begin');
+
+ if (!($dbresult = & $this->db->sql_query($sql))) {
+ $this->db->sql_transaction('rollback');
+ message_die(GENERAL_ERROR, 'Could not update bookmark', '', __LINE__, __FILE__, $sql, $this->db);
+ return false;
+ }
+
+ $uriparts = explode('.', $address);
+ $extension = end($uriparts);
+ unset($uriparts);
+
+ $tagservice = & ServiceFactory :: getServiceInstance('TagService');
+ if (!$tagservice->attachTags($bId, $categories, $fromApi, $extension)) {
+ $this->db->sql_transaction('rollback');
+ message_die(GENERAL_ERROR, 'Could not update bookmark', '', __LINE__, __FILE__, $sql, $this->db);
+ return false;
+ }
+
+ $this->db->sql_transaction('commit');
+ // Everything worked out, so return true.
+ return true;
+ }
+
+ function & getBookmarks($start = 0, $perpage = NULL, $user = NULL, $tags = NULL, $terms = NULL, $sortOrder = NULL, $watched = NULL, $startdate = NULL, $enddate = NULL, $hash = NULL) {
+ // Only get the bookmarks that are visible to the current user. Our rules:
+ // - if the $user is NULL, that means get bookmarks from ALL users, so we need to make
+ // sure to check the logged-in user's watchlist and get the contacts-only bookmarks from
+ // those users. If the user isn't logged-in, just get the public bookmarks.
+ // - if the $user is set and isn't the logged-in user, then get that user's bookmarks, and
+ // if that user is on the logged-in user's watchlist, get the public AND contacts-only
+ // bookmarks; otherwise, just get the public bookmarks.
+ // - if the $user is set and IS the logged-in user, then get all bookmarks.
+ $userservice =& ServiceFactory::getServiceInstance('UserService');
+ $tagservice =& ServiceFactory::getServiceInstance('TagService');
+ $sId = $userservice->getCurrentUserId();
+
+ if ($userservice->isLoggedOn()) {
+ // All public bookmarks, user's own bookmarks and any shared with user
+ $privacy = ' AND ((B.bStatus = 0) OR (B.uId = '. $sId .')';
+ $watchnames = $userservice->getWatchNames($sId, true);
+ foreach($watchnames as $watchuser) {
+ $privacy .= ' OR (U.username = "'. $watchuser .'" AND B.bStatus = 1)';
+ }
+ $privacy .= ')';
+ } else {
+ // Just public bookmarks
+ $privacy = ' AND B.bStatus = 0';
+ }
+
+ // Set up the tags, if need be.
+ if (!is_array($tags) && !is_null($tags)) {
+ $tags = explode('+', trim($tags));
+ }
+
+ $tagcount = count($tags);
+ for ($i = 0; $i < $tagcount; $i ++) {
+ $tags[$i] = trim($tags[$i]);
+ }
+
+ // Set up the SQL query.
+ $query_1 = 'SELECT DISTINCT ';
+ if (SQL_LAYER == 'mysql4') {
+ $query_1 .= 'SQL_CALC_FOUND_ROWS ';
+ }
+ $query_1 .= 'B.*, U.'. $userservice->getFieldName('username');
+
+ $query_2 = ' FROM '. $userservice->getTableName() .' AS U, '. $GLOBALS['tableprefix'] .'bookmarks AS B';
+
+ $query_3 = ' WHERE B.uId = U.'. $userservice->getFieldName('primary') . $privacy;
+ if (is_null($watched)) {
+ if (!is_null($user)) {
+ $query_3 .= ' AND B.uId = '. $user;
+ }
+ } else {
+ $arrWatch = $userservice->getWatchlist($user);
+ if (count($arrWatch) > 0) {
+ foreach($arrWatch as $row) {
+ $query_3_1 .= 'B.uId = '. intval($row) .' OR ';
+ }
+ $query_3_1 = substr($query_3_1, 0, -3);
+ } else {
+ $query_3_1 = 'B.uId = -1';
+ }
+ $query_3 .= ' AND ('. $query_3_1 .') AND B.bStatus IN (0, 1)';
+ }
+
+ switch($sortOrder) {
+ case 'date_asc':
+ $query_5 = ' ORDER BY B.bDatetime ASC ';
+ break;
+ case 'title_desc':
+ $query_5 = ' ORDER BY B.bTitle DESC ';
+ break;
+ case 'title_asc':
+ $query_5 = ' ORDER BY B.bTitle ASC ';
+ break;
+ case 'url_desc':
+ $query_5 = ' ORDER BY B.bAddress DESC ';
+ break;
+ case 'url_asc':
+ $query_5 = ' ORDER BY B.bAddress ASC ';
+ break;
+ default:
+ $query_5 = ' ORDER BY B.bDatetime DESC ';
+ }
+
+ // Handle the parts of the query that depend on any tags that are present.
+ $query_4 = '';
+ for ($i = 0; $i < $tagcount; $i ++) {
+ $query_2 .= ', '. $GLOBALS['tableprefix'] .'tags AS T'. $i;
+ $query_4 .= ' AND T'. $i .'.tag = "'. $this->db->sql_escape($tags[$i]) .'" AND T'. $i .'.bId = B.bId';
+ }
+
+ // Search terms
+ if ($terms) {
+ // Multiple search terms okay
+ $aTerms = explode(' ', $terms);
+ $aTerms = array_map('trim', $aTerms);
+
+ // Search terms in tags as well when none given
+ if (!count($tags)) {
+ $query_2 .= ' LEFT JOIN '. $GLOBALS['tableprefix'] .'tags AS T ON B.bId = T.bId';
+ $dotags = true;
+ } else {
+ $dotags = false;
+ }
+
+ $query_4 = '';
+ for ($i = 0; $i < count($aTerms); $i++) {
+ $query_4 .= ' AND (B.bTitle LIKE "%'. $this->db->sql_escape($aTerms[$i]) .'%"';
+ $query_4 .= ' OR B.bDescription LIKE "%'. $this->db->sql_escape($aTerms[$i]) .'%"';
+ if ($dotags) {
+ $query_4 .= ' OR T.tag = "'. $this->db->sql_escape($aTerms[$i]) .'"';
+ }
+ $query_4 .= ')';
+ }
+ }
+
+ // Start and end dates
+ if ($startdate) {
+ $query_4 .= ' AND B.bDatetime > "'. $startdate .'"';
+ }
+ if ($enddate) {
+ $query_4 .= ' AND B.bDatetime < "'. $enddate .'"';
+ }
+
+ // Hash
+ if ($hash) {
+ $query_4 .= ' AND B.bHash = "'. $hash .'"';
+ }
+
+ $query = $query_1 . $query_2 . $query_3 . $query_4 . $query_5;
+ if (!($dbresult = & $this->db->sql_query_limit($query, intval($perpage), intval($start)))) {
+ message_die(GENERAL_ERROR, 'Could not get bookmarks', '', __LINE__, __FILE__, $query, $this->db);
+ return false;
+ }
+
+ if (SQL_LAYER == 'mysql4') {
+ $totalquery = 'SELECT FOUND_ROWS() AS total';
+ } else {
+ $totalquery = 'SELECT COUNT(*) AS total'. $query_2 . $query_3 . $query_4;
+ }
+
+ if (!($totalresult = & $this->db->sql_query($totalquery)) || (!($row = & $this->db->sql_fetchrow($totalresult)))) {
+ message_die(GENERAL_ERROR, 'Could not get total bookmarks', '', __LINE__, __FILE__, $totalquery, $this->db);
+ return false;
+ }
+
+ $total = $row['total'];
+
+ $bookmarks = array();
+ while ($row = & $this->db->sql_fetchrow($dbresult)) {
+ $row['tags'] = $tagservice->getTagsForBookmark(intval($row['bId']));
+ $bookmarks[] = $row;
+ }
+ return array ('bookmarks' => $bookmarks, 'total' => $total);
+ }
+
+ function deleteBookmark($bookmarkid) {
+ $query = 'DELETE FROM '. $GLOBALS['tableprefix'] .'bookmarks WHERE bId = '. intval($bookmarkid);
+ $this->db->sql_transaction('begin');
+ if (!($dbresult = & $this->db->sql_query($query))) {
+ $this->db->sql_transaction('rollback');
+ message_die(GENERAL_ERROR, 'Could not delete bookmarks', '', __LINE__, __FILE__, $query, $this->db);
+ return false;
+ }
+
+ $query = 'DELETE FROM '. $GLOBALS['tableprefix'] .'tags WHERE bId = '. intval($bookmarkid);
+ $this->db->sql_transaction('begin');
+ if (!($dbresult = & $this->db->sql_query($query))) {
+ $this->db->sql_transaction('rollback');
+ message_die(GENERAL_ERROR, 'Could not delete bookmarks', '', __LINE__, __FILE__, $query, $this->db);
+ return false;
+ }
+
+ $this->db->sql_transaction('commit');
+ return true;
+ }
+
+ function countOthers($address) {
+ if (!$address) {
+ return false;
+ }
+
+ $userservice = & ServiceFactory :: getServiceInstance('UserService');
+ $sId = $userservice->getCurrentUserId();
+
+ if ($userservice->isLoggedOn()) {
+ // All public bookmarks, user's own bookmarks and any shared with user
+ $privacy = ' AND ((B.bStatus = 0) OR (B.uId = '. $sId .')';
+ $watchnames = $userservice->getWatchNames($sId, true);
+ foreach($watchnames as $watchuser) {
+ $privacy .= ' OR (U.username = "'. $watchuser .'" AND B.bStatus = 1)';
+ }
+ $privacy .= ')';
+ } else {
+ // Just public bookmarks
+ $privacy = ' AND B.bStatus = 0';
+ }
+
+ $sql = 'SELECT COUNT(*) FROM '. $userservice->getTableName() .' AS U, '. $GLOBALS['tableprefix'] .'bookmarks AS B WHERE U.'. $userservice->getFieldName('primary') .' = B.uId AND B.bHash = "'. md5($address) .'"'. $privacy;
+ if (!($dbresult = & $this->db->sql_query($sql))) {
+ message_die(GENERAL_ERROR, 'Could not get vars', '', __LINE__, __FILE__, $sql, $this->db);
+ }
+ return $this->db->sql_fetchfield(0, 0) - 1;
+ }
+}
+?>
diff --git a/services/cacheservice.php b/services/cacheservice.php
new file mode 100644
index 0000000..fe66d38
--- /dev/null
+++ b/services/cacheservice.php
@@ -0,0 +1,38 @@
+<?php
+class CacheService {
+ var $basedir;
+ var $fileextension = '.cache';
+
+ function &getInstance() {
+ static $instance;
+
+ if (!isset($instance))
+ $instance =& new CacheService();
+
+ return $instance;
+ }
+
+ function CacheService() {
+ $this->basedir = $GLOBALS['dir_cache'];
+ }
+
+ function Start($hash, $time = 300) {
+ $cachefile = $this->basedir .'/'. $hash . $this->fileextension;
+ if (file_exists($cachefile) && time() < filemtime($cachefile) + $time) {
+ @readfile($cachefile);
+ echo "\n<!-- Cached: ". date('r', filemtime($cachefile)) ." -->\n";
+ unset($cachefile);
+ exit;
+ }
+ ob_start("ob_gzhandler");
+ }
+
+ function End($hash) {
+ $cachefile = $this->basedir .'/'. $hash . $this->fileextension;
+ $handle = fopen($cachefile, 'w');
+ fwrite($handle, ob_get_contents());
+ fclose($handle);
+ ob_flush();
+ }
+}
+?> \ No newline at end of file
diff --git a/services/servicefactory.php b/services/servicefactory.php
new file mode 100644
index 0000000..ba2d6d7
--- /dev/null
+++ b/services/servicefactory.php
@@ -0,0 +1,33 @@
+<?php
+class ServiceFactory {
+ function ServiceFactory(&$db, $serviceoverrules = array()) {
+ }
+
+ function &getServiceInstance($name, $servicedir = NULL) {
+ global $dbhost, $dbuser, $dbpass, $dbname, $dbport, $dbpersist, $dbtype;
+ static $instances = array();
+ static $db;
+ if (!isset($db)) {
+ require_once(dirname(__FILE__) .'/../includes/db/'. $dbtype .'.php');
+ $db = new sql_db();
+ $db->sql_connect($dbhost, $dbuser, $dbpass, $dbname, $dbport, $dbpersist);
+ if(!$db->db_connect_id) {
+ message_die(CRITICAL_ERROR, "Could not connect to the database", $db);
+ }
+ }
+ if (!isset($instances[$name])) {
+ if (isset($serviceoverrules[$name])) {
+ $name = $serviceoverrules[$name];
+ }
+ if (!class_exists($name)) {
+ if (!isset($servicedir)) {
+ $servicedir = dirname(__FILE__) .'/';
+ }
+ require_once($servicedir . strtolower($name) . '.php');
+ }
+ $instances[$name] = call_user_func(array($name, 'getInstance'), $db);
+ }
+ return $instances[$name];
+ }
+}
+?> \ No newline at end of file
diff --git a/services/tagservice.php b/services/tagservice.php
new file mode 100644
index 0000000..6bfbf15
--- /dev/null
+++ b/services/tagservice.php
@@ -0,0 +1,363 @@
+<?php
+class TagService {
+ var $db;
+ var $tablename;
+
+ function &getInstance(&$db) {
+ static $instance;
+ if (!isset($instance))
+ $instance =& new TagService($db);
+ return $instance;
+ }
+
+ function TagService(&$db) {
+ $this->db =& $db;
+ $this->tablename = $GLOBALS['tableprefix'] .'tags';
+ }
+
+ function isNotSystemTag($var) {
+ if (utf8_substr($var, 0, 7) == 'system:')
+ return false;
+ else
+ return true;
+ }
+
+ function attachTags($bookmarkid, $tags, $fromApi = false, $extension = NULL, $replace = true, $fromImport = false) {
+ // Make sure that categories is an array of trimmed strings, and that if the categories are
+ // coming in from an API call to add a bookmark, that underscores are converted into strings.
+ if (!is_array($tags)) {
+ $tags = trim($tags);
+ if ($tags != '') {
+ if (substr($tags, -1) == ',') {
+ $tags = substr($tags, 0, -1);
+ }
+ if ($fromApi) {
+ $tags = explode(' ', $tags);
+ } else {
+ $tags = explode(',', $tags);
+ }
+ } else {
+ $tags = null;
+ }
+ }
+
+ $tags_count = count($tags);
+ for ($i = 0; $i < $tags_count; $i++) {
+ $tags[$i] = trim(strtolower($tags[$i]));
+ if ($fromApi) {
+ include_once(dirname(__FILE__) .'/../functions.inc.php');
+ $tags[$i] = convertTag($tags[$i], 'in');
+ }
+ }
+
+ if ($tags_count > 0) {
+ // Remove system tags
+ $tags = array_filter($tags, array($this, "isNotSystemTag"));
+
+ // Eliminate any duplicate categories
+ $temp = array_unique($tags);
+ $tags = array_values($temp);
+ } else {
+ // Unfiled
+ $tags[] = 'system:unfiled';
+ }
+
+ // Media and file types
+ if (!is_null($extension)) {
+ include_once(dirname(__FILE__) .'/../functions.inc.php');
+ if ($keys = multi_array_search($extension, $GLOBALS['filetypes'])) {
+ $tags[] = 'system:filetype:'. $extension;
+ $tags[] = 'system:media:'. array_shift($keys);
+ }
+ }
+
+ // Imported
+ if ($fromImport) {
+ $tags[] = 'system:imported';
+ }
+
+ $this->db->sql_transaction('begin');
+
+ if ($replace) {
+ if (!$this->deleteTagsForBookmark($bookmarkid)){
+ $this->db->sql_transaction('rollback');
+ message_die(GENERAL_ERROR, 'Could not attach tags (deleting old ones failed)', '', __LINE__, __FILE__, $sql, $this->db);
+ return false;
+ }
+ }
+
+ // Add the categories to the DB.
+ for ($i = 0; $i < count($tags); $i++) {
+ if ($tags[$i] != '') {
+ $values = array(
+ 'bId' => intval($bookmarkid),
+ 'tag' => $tags[$i]
+ );
+
+ if (!$this->hasTag($bookmarkid, $tags[$i])) {
+ $sql = 'INSERT INTO '. $this->getTableName() .' '. $this->db->sql_build_array('INSERT', $values);
+ if (!($dbresult =& $this->db->sql_query($sql))) {
+ $this->db->sql_transaction('rollback');
+ message_die(GENERAL_ERROR, 'Could not attach tags', '', __LINE__, __FILE__, $sql, $this->db);
+ return false;
+ }
+ }
+ }
+ }
+ $this->db->sql_transaction('commit');
+ return true;
+ }
+
+ function deleteTag($tag) {
+ $userservice =& ServiceFactory::getServiceInstance('UserService');
+ $logged_on_user = $userservice->getCurrentUserId();
+
+ $query = 'DELETE FROM '. $this->getTableName() .' USING '. $GLOBALS['tableprefix'] .'tags, '. $GLOBALS['tableprefix'] .'bookmarks WHERE '. $GLOBALS['tableprefix'] .'tags.bId = '. $GLOBALS['tableprefix'] .'bookmarks.bId AND '. $GLOBALS['tableprefix'] .'bookmarks.uId = '. $logged_on_user .' AND '. $GLOBALS['tableprefix'] .'tags.tag = "'. $this->db->sql_escape($tag) .'"';
+
+ if (!($dbresult =& $this->db->sql_query($query))) {
+ message_die(GENERAL_ERROR, 'Could not delete tags', '', __LINE__, __FILE__, $query, $this->db);
+ return false;
+ }
+
+ return true;
+ }
+
+ function deleteTagsForBookmark($bookmarkid) {
+ if (!is_int($bookmarkid)) {
+ message_die(GENERAL_ERROR, 'Could not delete tags (invalid bookmarkid)', '', __LINE__, __FILE__, $query);
+ return false;
+ }
+
+ $query = 'DELETE FROM '. $this->getTableName() .' WHERE bId = '. intval($bookmarkid);
+
+ if (!($dbresult =& $this->db->sql_query($query))) {
+ message_die(GENERAL_ERROR, 'Could not delete tags', '', __LINE__, __FILE__, $query, $this->db);
+ return false;
+ }
+
+ return true;
+ }
+
+ function &getTagsForBookmark($bookmarkid) {
+ if (!is_int($bookmarkid)) {
+ message_die(GENERAL_ERROR, 'Could not get tags (invalid bookmarkid)', '', __LINE__, __FILE__, $query);
+ return false;
+ }
+
+ $query = 'SELECT tag FROM '. $this->getTableName() .' WHERE bId = '. intval($bookmarkid) .' AND LEFT(tag, 7) <> "system:" ORDER BY tag';
+
+ if (!($dbresult =& $this->db->sql_query($query))) {
+ message_die(GENERAL_ERROR, 'Could not get tags', '', __LINE__, __FILE__, $query, $this->db);
+ return false;
+ }
+
+ $tags = array();
+ while ($row =& $this->db->sql_fetchrow($dbresult)) {
+ $tags[] = $row['tag'];
+ }
+
+ return $tags;
+ }
+
+ function &getTags($userid = NULL) {
+ $userservice =& ServiceFactory::getServiceInstance('UserService');
+ $logged_on_user = $userservice->getCurrentUserId();
+
+ $query = 'SELECT T.tag, COUNT(B.bId) AS bCount FROM '. $GLOBALS['tableprefix'] .'bookmarks AS B INNER JOIN '. $userservice->getTableName() .' AS U ON B.uId = U.'. $userservice->getFieldName('primary') .' INNER JOIN '. $GLOBALS['tableprefix'] .'tags AS T ON B.bId = T.bId';
+
+ $conditions = array();
+ if (!is_null($userid)) {
+ $conditions['U.'. $userservice->getFieldName('primary')] = intval($userid);
+ if ($logged_on_user != $userid)
+ $conditions['B.bStatus'] = 0;
+ } else {
+ $conditions['B.bStatus'] = 0;
+ }
+
+ $query .= ' WHERE '. $this->db->sql_build_array('SELECT', $conditions) .' AND LEFT(T.tag, 7) <> "system:" GROUP BY T.tag ORDER BY bCount DESC, tag';
+
+ if (!($dbresult =& $this->db->sql_query($query))) {
+ message_die(GENERAL_ERROR, 'Could not get tags', '', __LINE__, __FILE__, $query, $this->db);
+ return false;
+ }
+ return $this->db->sql_fetchrowset($dbresult);
+ }
+
+
+ // Returns the tags related to the specified tags; i.e. attached to the same bookmarks
+ function &getRelatedTags($tags, $for_user = NULL, $logged_on_user = NULL, $limit = 10) {
+ $conditions = array();
+ // Only count the tags that are visible to the current user.
+ if ($for_user != $logged_on_user || is_null($for_user))
+ $conditions['B.bStatus'] = 0;
+
+ if (!is_null($for_user))
+ $conditions['B.uId'] = $for_user;
+
+ // Set up the tags, if need be.
+ if (is_numeric($tags))
+ $tags = NULL;
+ if (!is_array($tags) and !is_null($tags))
+ $tags = explode('+', trim($tags));
+
+ $tagcount = count($tags);
+ for ($i = 0; $i < $tagcount; $i++) {
+ $tags[$i] = trim($tags[$i]);
+ }
+
+ // Set up the SQL query.
+ $query_1 = 'SELECT DISTINCTROW T0.tag, COUNT(B.bId) AS bCount FROM '. $GLOBALS['tableprefix'] .'bookmarks AS B, '. $this->getTableName() .' AS T0';
+ $query_2 = '';
+ $query_3 = ' WHERE B.bId = T0.bId ';
+ if (count($conditions) > 0)
+ $query_4 = ' AND '. $this->db->sql_build_array('SELECT', $conditions);
+ else
+ $query_4 = '';
+ // Handle the parts of the query that depend on any tags that are present.
+ for ($i = 1; $i <= $tagcount; $i++) {
+ $query_2 .= ', '. $this->getTableName() .' AS T'. $i;
+ $query_4 .= ' AND T'. $i .'.bId = B.bId AND T'. $i .'.tag = "'. $this->db->sql_escape($tags[$i - 1]) .'" AND T0.tag <> "'. $this->db->sql_escape($tags[$i - 1]) .'"';
+ }
+ $query_5 = ' AND LEFT(T0.tag, 7) <> "system:" GROUP BY T0.tag ORDER BY bCount DESC, T0.tag';
+ $query = $query_1 . $query_2 . $query_3 . $query_4 . $query_5;
+
+ if (! ($dbresult =& $this->db->sql_query_limit($query, $limit)) ){
+ message_die(GENERAL_ERROR, 'Could not get related tags', '', __LINE__, __FILE__, $query, $this->db);
+ return false;
+ }
+ return $this->db->sql_fetchrowset($dbresult);
+ }
+
+ // Returns the most popular tags used for a particular bookmark hash
+ function &getRelatedTagsByHash($hash, $limit = 20) {
+ $userservice = & ServiceFactory :: getServiceInstance('UserService');
+ $sId = $userservice->getCurrentUserId();
+ // Logged in
+ if ($userservice->isLoggedOn()) {
+ $arrWatch = $userservice->getWatchList($sId);
+ // From public bookmarks or user's own
+ $privacy = ' AND ((B.bStatus = 0) OR (B.uId = '. $sId .')';
+ // From shared bookmarks in watchlist
+ foreach ($arrWatch as $w) {
+ $privacy .= ' OR (B.uId = '. $w .' AND B.bStatus = 1)';
+ }
+ $privacy .= ') ';
+ // Not logged in
+ } else {
+ $privacy = ' AND B.bStatus = 0 ';
+ }
+
+ $query = 'SELECT T.tag, COUNT(T.tag) AS bCount FROM sc_bookmarks AS B LEFT JOIN sc_tags AS T ON B.bId = T.bId WHERE B.bHash = "'. $hash .'" '. $privacy .'AND LEFT(T.tag, 7) <> "system:" GROUP BY T.tag ORDER BY bCount DESC';
+
+ if (!($dbresult =& $this->db->sql_query_limit($query, $limit))) {
+ message_die(GENERAL_ERROR, 'Could not get related tags for this hash', '', __LINE__, __FILE__, $query, $this->db);
+ return false;
+ }
+ return $this->db->sql_fetchrowset($dbresult);
+ }
+
+ function &getPopularTags($user = NULL, $limit = 30, $logged_on_user = NULL, $days = NULL) {
+ // Only count the tags that are visible to the current user.
+ if (($user != $logged_on_user) || is_null($user) || ($user === false))
+ $privacy = ' AND B.bStatus = 0';
+ else
+ $privacy = '';
+
+ if (is_null($days) || !is_int($days))
+ $span = '';
+ else
+ $span = ' AND B.bDatetime > "'. date('Y-m-d H:i:s', time() - (86400 * $days)) .'"';
+
+ $query = 'SELECT T.tag, COUNT(T.bId) AS bCount FROM '. $this->getTableName() .' AS T, '. $GLOBALS['tableprefix'] .'bookmarks AS B WHERE ';
+ if (is_null($user) || ($user === false)) {
+ $query .= 'B.bId = T.bId AND B.bStatus = 0';
+ } else {
+ $query .= 'B.uId = '. $this->db->sql_escape($user) .' AND B.bId = T.bId'. $privacy;
+ }
+ $query .= $span .' AND LEFT(T.tag, 7) <> "system:" GROUP BY T.tag ORDER BY bCount DESC, tag';
+
+ if (!($dbresult =& $this->db->sql_query_limit($query, $limit))) {
+ message_die(GENERAL_ERROR, 'Could not get popular tags', '', __LINE__, __FILE__, $query, $this->db);
+ return false;
+ }
+
+ return $this->db->sql_fetchrowset($dbresult);
+ }
+
+ function hasTag($bookmarkid, $tag) {
+ $query = 'SELECT COUNT(*) AS tCount FROM '. $this->getTableName() .' WHERE bId = '. intval($bookmarkid) .' AND tag ="'. $this->db->sql_escape($tag) .'"';
+
+ if (! ($dbresult =& $this->db->sql_query($query)) ) {
+ message_die(GENERAL_ERROR, 'Could not find tag', '', __LINE__, __FILE__, $query, $this->db);
+ return false;
+ }
+
+ if ($row =& $this->db->sql_fetchrow($dbresult)) {
+ if ($row['tCount'] > 0) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ function renameTag($userid, $old, $new, $fromApi = false) {
+ $bookmarkservice =& ServiceFactory::getServiceInstance('BookmarkService');
+
+ if (is_null($userid) || is_null($old) || is_null($new))
+ return false;
+
+ // Find bookmarks with old tag
+ $bookmarksInfo =& $bookmarkservice->getBookmarks(0, NULL, $userid, $old);
+ $bookmarks =& $bookmarksInfo['bookmarks'];
+
+ // Delete old tag
+ $this->deleteTag($old);
+
+ // Attach new tags
+ foreach(array_keys($bookmarks) as $key) {
+ $row =& $bookmarks[$key];
+ $this->attachTags($row['bId'], $new, $fromApi, NULL, false);
+ }
+
+ return true;
+ }
+
+ function &tagCloud($tags = NULL, $steps = 5, $sizemin = 90, $sizemax = 225, $sortOrder = NULL) {
+
+ if (is_null($tags) || count($tags) < 1) {
+ return false;
+ }
+
+ $min = $tags[count($tags) - 1]['bCount'];
+ $max = $tags[0]['bCount'];
+
+ for ($i = 1; $i <= $steps; $i++) {
+ $delta = ($max - $min) / (2 * $steps - $i);
+ $limit[$i] = $i * $delta + $min;
+ }
+ $sizestep = ($sizemax - $sizemin) / $steps;
+ foreach ($tags as $row) {
+ $next = false;
+ for ($i = 1; $i <= $steps; $i++) {
+ if (!$next && $row['bCount'] <= $limit[$i]) {
+ $size = $sizestep * ($i - 1) + $sizemin;
+ $next = true;
+ }
+ }
+ $tempArray = array('size' => $size .'%');
+ $row = array_merge($row, $tempArray);
+ $output[] = $row;
+ }
+
+ if ($sortOrder == 'alphabet_asc') {
+ usort($output, create_function('$a,$b','return strcasecmp(utf8_deaccent($a["tag"]), utf8_deaccent($b["tag"]));'));
+ }
+
+ return $output;
+ }
+
+ // Properties
+ function getTableName() { return $this->tablename; }
+ function setTableName($value) { $this->tablename = $value; }
+}
+?> \ No newline at end of file
diff --git a/services/templateservice.php b/services/templateservice.php
new file mode 100644
index 0000000..191ab8d
--- /dev/null
+++ b/services/templateservice.php
@@ -0,0 +1,46 @@
+<?php
+class TemplateService {
+ var $basedir;
+
+ function &getInstance() {
+ static $instance;
+ if (!isset($instance))
+ $instance =& new TemplateService();
+ return $instance;
+ }
+
+ function TemplateService() {
+ $this->basedir = $GLOBALS['TEMPLATES_DIR'];
+ }
+
+ function loadTemplate($template, $vars = NULL) {
+ if (substr($template, -4) != '.php')
+ $template .= '.php';
+ $tpl =& new Template($this->basedir .'/'. $template, $vars, $this);
+ $tpl->parse();
+ return $tpl;
+ }
+}
+
+class Template {
+ var $vars = array();
+ var $file = '';
+ var $templateservice;
+
+ function Template($file, $vars = NULL, &$templateservice) {
+ $this->vars = $vars;
+ $this->file = $file;
+ $this->templateservice = $templateservice;
+ }
+
+ function parse() {
+ if (isset($this->vars))
+ extract($this->vars);
+ include($this->file);
+ }
+
+ function includeTemplate($name) {
+ return $this->templateservice->loadTemplate($name, $this->vars);
+ }
+}
+?> \ No newline at end of file
diff --git a/services/userservice.php b/services/userservice.php
new file mode 100644
index 0000000..1e7ed46
--- /dev/null
+++ b/services/userservice.php
@@ -0,0 +1,362 @@
+<?php
+class UserService {
+ var $db;
+
+ function &getInstance(&$db) {
+ static $instance;
+ if (!isset($instance))
+ $instance =& new UserService($db);
+ return $instance;
+ }
+
+ var $fields = array(
+ 'primary' => 'uId',
+ 'username' => 'username',
+ 'password' => 'password'
+ );
+ var $profileurl;
+ var $tablename;
+ var $sessionkey;
+ var $cookiekey;
+ var $cookietime = 1209600; // 2 weeks
+
+ function UserService(&$db) {
+ $this->db =& $db;
+ $this->tablename = $GLOBALS['tableprefix'] .'users';
+ $this->sessionkey = $GLOBALS['cookieprefix'] .'-currentuserid';
+ $this->cookiekey = $GLOBALS['cookieprefix'] .'-login';
+ $this->profileurl = createURL('profile', '%2$s');
+ }
+
+ function _checkdns($host) {
+ if (function_exists('checkdnsrr')) {
+ return checkdnsrr($host);
+ } else {
+ return $this->_checkdnsrr($host);
+ }
+ }
+
+ function _checkdnsrr($host, $type = "MX") {
+ if(!empty($host)) {
+ @exec("nslookup -type=$type $host", $output);
+ while(list($k, $line) = each($output)) {
+ if(eregi("^$host", $line)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ function _getuser($fieldname, $value) {
+ $query = 'SELECT * FROM '. $this->getTableName() .' WHERE '. $fieldname .' = "'. $this->db->sql_escape($value) .'"';
+
+ if (! ($dbresult =& $this->db->sql_query($query)) ) {
+ message_die(GENERAL_ERROR, 'Could not get user', '', __LINE__, __FILE__, $query, $this->db);
+ return false;
+ }
+
+ if ($row =& $this->db->sql_fetchrow($dbresult))
+ return $row;
+ else
+ return false;
+ }
+
+ function _randompassword() {
+ $seed = (integer) md5(microtime());
+ mt_srand($seed);
+ $password = mt_rand(1, 99999999);
+ $password = substr(md5($password), mt_rand(0, 19), mt_rand(6, 12));
+ return $password;
+ }
+
+ function _updateuser($uId, $fieldname, $value) {
+ $updates = array ($fieldname => $value);
+ $sql = 'UPDATE '. $this->getTableName() .' SET '. $this->db->sql_build_array('UPDATE', $updates) .' WHERE '. $this->getFieldName('primary') .'='. intval($uId);
+
+ // Execute the statement.
+ $this->db->sql_transaction('begin');
+ if (!($dbresult = & $this->db->sql_query($sql))) {
+ $this->db->sql_transaction('rollback');
+ message_die(GENERAL_ERROR, 'Could not update user', '', __LINE__, __FILE__, $sql, $this->db);
+ return false;
+ }
+ $this->db->sql_transaction('commit');
+
+ // Everything worked out, so return true.
+ return true;
+ }
+
+ function getProfileUrl($id, $username) {
+ return sprintf($this->profileurl, urlencode($id), urlencode($username));
+ }
+
+ function getUserByUsername($username) {
+ return $this->_getuser($this->getFieldName('username'), $username);
+ }
+
+ function getUser($id) {
+ return $this->_getuser($this->getFieldName('primary'), $id);
+ }
+
+ function isLoggedOn() {
+ return ($this->getCurrentUserId() !== false);
+ }
+
+ function &getCurrentUser($refresh = FALSE, $newval = NULL) {
+ static $currentuser;
+ if (!is_null($newval)) //internal use only: reset currentuser
+ $currentuser = $newval;
+ else if ($refresh || !isset($currentuser)) {
+ if ($id = $this->getCurrentUserId())
+ $currentuser = $this->getUser($id);
+ else
+ return;
+ }
+ return $currentuser;
+ }
+
+ function isAdmin($userid) {
+ return false; //not implemented yet
+ }
+
+ function getCurrentUserId() {
+ if (isset($_SESSION[$this->getSessionKey()])) {
+ return $_SESSION[$this->getSessionKey()];
+ } else if (isset($_COOKIE[$this->getCookieKey()])) {
+ $cook = split(':', $_COOKIE[$this->getCookieKey()]);
+ //cookie looks like this: 'id:md5(username+password)'
+ $query = 'SELECT * FROM '. $this->getTableName() .
+ ' WHERE MD5(CONCAT('.$this->getFieldName('username') .
+ ', '.$this->getFieldName('password') .
+ ')) = \''.$this->db->sql_escape($cook[1]).'\' AND '.
+ $this->getFieldName('primary'). ' = '. $this->db->sql_escape($cook[0]);
+
+ if (! ($dbresult =& $this->db->sql_query($query)) ) {
+ message_die(GENERAL_ERROR, 'Could not get user', '', __LINE__, __FILE__, $query, $this->db);
+ return false;
+ }
+
+ if ($row = $this->db->sql_fetchrow($dbresult)) {
+ $_SESSION[$this->getSessionKey()] = $row[$this->getFieldName('primary')];
+ return $_SESSION[$this->getSessionKey()];
+ }
+ }
+ return false;
+ }
+
+ function login($username, $password, $remember = FALSE) {
+ $password = $this->sanitisePassword($password);
+ $query = 'SELECT '. $this->getFieldName('primary') .' FROM '. $this->getTableName() .' WHERE '. $this->getFieldName('username') .' = "'. $this->db->sql_escape($username) .'" AND '. $this->getFieldName('password') .' = "'. $this->db->sql_escape($password) .'"';
+
+ if (! ($dbresult =& $this->db->sql_query($query)) ) {
+ message_die(GENERAL_ERROR, 'Could not get user', '', __LINE__, __FILE__, $query, $this->db);
+ return false;
+ }
+
+ if ($row =& $this->db->sql_fetchrow($dbresult)) {
+ $id = $_SESSION[$this->getSessionKey()] = $row[$this->getFieldName('primary')];
+ if ($remember) {
+ $cookie = $id .':'. md5($username.$password);
+ setcookie($this->cookiekey, $cookie, time() + $this->cookietime);
+ }
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ function logout() {
+ @setcookie($this->cookiekey, NULL, time() - 1);
+ unset($_COOKIE[$this->cookiekey]);
+ session_unset();
+ $this->getCurrentUser(TRUE, false);
+ }
+
+ function getWatchlist($uId) {
+ // Gets the list of user IDs being watched by the given user.
+ $query = 'SELECT watched FROM '. $GLOBALS['tableprefix'] .'watched WHERE uId = '. intval($uId);
+
+ if (! ($dbresult =& $this->db->sql_query($query)) ) {
+ message_die(GENERAL_ERROR, 'Could not get watchlist', '', __LINE__, __FILE__, $query, $this->db);
+ return false;
+ }
+
+ $arrWatch = array();
+ if ($this->db->sql_numrows($dbresult) == 0)
+ return $arrWatch;
+ while ($row =& $this->db->sql_fetchrow($dbresult))
+ $arrWatch[] = $row['watched'];
+ return $arrWatch;
+ }
+
+ function getWatchNames($uId, $watchedby = false) {
+ // Gets the list of user names being watched by the given user.
+ // - If $watchedby is false get the list of users that $uId watches
+ // - If $watchedby is true get the list of users that watch $uId
+ if ($watchedby) {
+ $table1 = 'b';
+ $table2 = 'a';
+ } else {
+ $table1 = 'a';
+ $table2 = 'b';
+ }
+ $query = 'SELECT '. $table1 .'.'. $this->getFieldName('username') .' FROM '. $GLOBALS['tableprefix'] .'watched AS W, '. $this->getTableName() .' AS a, '. $this->getTableName() .' AS b WHERE W.watched = a.'. $this->getFieldName('primary') .' AND W.uId = b.'. $this->getFieldName('primary') .' AND '. $table2 .'.'. $this->getFieldName('primary') .' = '. intval($uId) .' ORDER BY '. $table1 .'.'. $this->getFieldName('username');
+
+ if (!($dbresult =& $this->db->sql_query($query))) {
+ message_die(GENERAL_ERROR, 'Could not get watchlist', '', __LINE__, __FILE__, $query, $this->db);
+ return false;
+ }
+
+ $arrWatch = array();
+ if ($this->db->sql_numrows($dbresult) == 0) {
+ return $arrWatch;
+ }
+ while ($row =& $this->db->sql_fetchrow($dbresult)) {
+ $arrWatch[] = $row[$this->getFieldName('username')];
+ }
+ return $arrWatch;
+ }
+
+ function getWatchStatus($watcheduser, $currentuser) {
+ // Returns true if the current user is watching the given user, and false otherwise.
+ $query = 'SELECT watched FROM '. $GLOBALS['tableprefix'] .'watched AS W INNER JOIN '. $this->getTableName() .' AS U ON U.'. $this->getFieldName('primary') .' = W.watched WHERE U.'. $this->getFieldName('primary') .' = '. intval($watcheduser) .' AND W.uId = '. intval($currentuser);
+
+ if (! ($dbresult =& $this->db->sql_query($query)) ) {
+ message_die(GENERAL_ERROR, 'Could not get watchstatus', '', __LINE__, __FILE__, $query, $this->db);
+ return false;
+ }
+
+ $arrWatch = array();
+ if ($this->db->sql_numrows($dbresult) == 0)
+ return false;
+ else
+ return true;
+ }
+
+ function setWatchStatus($subjectUserID) {
+ if (!is_numeric($subjectUserID))
+ return false;
+
+ $currentUserID = $this->getCurrentUserId();
+ $watched = $this->getWatchStatus($subjectUserID, $currentUserID);
+
+ if ($watched) {
+ $sql = 'DELETE FROM '. $GLOBALS['tableprefix'] .'watched WHERE uId = '. intval($currentUserID) .' AND watched = '. intval($subjectUserID);
+ if (!($dbresult =& $this->db->sql_query($sql))) {
+ $this->db->sql_transaction('rollback');
+ message_die(GENERAL_ERROR, 'Could not add user to watch list', '', __LINE__, __FILE__, $sql, $this->db);
+ return false;
+ }
+ } else {
+ $values = array(
+ 'uId' => intval($currentUserID),
+ 'watched' => intval($subjectUserID)
+ );
+ $sql = 'INSERT INTO '. $GLOBALS['tableprefix'] .'watched '. $this->db->sql_build_array('INSERT', $values);
+ if (!($dbresult =& $this->db->sql_query($sql))) {
+ $this->db->sql_transaction('rollback');
+ message_die(GENERAL_ERROR, 'Could not add user to watch list', '', __LINE__, __FILE__, $sql, $this->db);
+ return false;
+ }
+ }
+
+ $this->db->sql_transaction('commit');
+ return true;
+ }
+
+ function addUser($username, $password, $email) {
+ // Set up the SQL UPDATE statement.
+ $datetime = gmdate('Y-m-d H:i:s', time());
+ $password = $this->sanitisePassword($password);
+ $values = array('username' => $username, 'password' => $password, 'email' => $email, 'uDatetime' => $datetime, 'uModified' => $datetime);
+ $sql = 'INSERT INTO '. $this->getTableName() .' '. $this->db->sql_build_array('INSERT', $values);
+
+ // Execute the statement.
+ $this->db->sql_transaction('begin');
+ if (!($dbresult = & $this->db->sql_query($sql))) {
+ $this->db->sql_transaction('rollback');
+ message_die(GENERAL_ERROR, 'Could not insert user', '', __LINE__, __FILE__, $sql, $this->db);
+ return false;
+ }
+ $this->db->sql_transaction('commit');
+
+ // Everything worked out, so return true.
+ return true;
+ }
+
+ function updateUser($uId, $password, $name, $email, $homepage, $uContent) {
+ if (!is_numeric($uId))
+ return false;
+
+ // Set up the SQL UPDATE statement.
+ $moddatetime = gmdate('Y-m-d H:i:s', time());
+ if ($password == '')
+ $updates = array ('uModified' => $moddatetime, 'name' => $name, 'email' => $email, 'homepage' => $homepage, 'uContent' => $uContent);
+ else
+ $updates = array ('uModified' => $moddatetime, 'password' => $this->sanitisePassword($password), 'name' => $name, 'email' => $email, 'homepage' => $homepage, 'uContent' => $uContent);
+ $sql = 'UPDATE '. $this->getTableName() .' SET '. $this->db->sql_build_array('UPDATE', $updates) .' WHERE '. $this->getFieldName('primary') .'='. intval($uId);
+
+ // Execute the statement.
+ $this->db->sql_transaction('begin');
+ if (!($dbresult = & $this->db->sql_query($sql))) {
+ $this->db->sql_transaction('rollback');
+ message_die(GENERAL_ERROR, 'Could not update user', '', __LINE__, __FILE__, $sql, $this->db);
+ return false;
+ }
+ $this->db->sql_transaction('commit');
+
+ // Everything worked out, so return true.
+ return true;
+ }
+
+ function sanitisePassword($password) {
+ return sha1(trim($password));
+ }
+
+ function generatePassword($uId) {
+ if (!is_numeric($uId))
+ return false;
+
+ $password = $this->_randompassword();
+
+ if ($this->_updateuser($uId, $this->getFieldName('password'), $this->sanitisePassword($password)))
+ return $password;
+ else
+ return false;
+ }
+
+ function isReserved($username) {
+ if (in_array($username, $GLOBALS['reservedusers'])) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ function isValidEmail($email) {
+ if (eregi("^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,6})$", $email)) {
+ list($emailUser, $emailDomain) = split("@", $email);
+
+ // Check if the email domain has a DNS record
+ if ($this->_checkdns($emailDomain)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // Properties
+ function getTableName() { return $this->tablename; }
+ function setTableName($value) { $this->tablename = $value; }
+
+ function getFieldName($field) { return $this->fields[$field]; }
+ function setFieldName($field, $value) { $this->fields[$field] = $value; }
+
+ function getSessionKey() { return $this->sessionkey; }
+ function setSessionKey($value) { $this->sessionkey = $value; }
+
+ function getCookieKey() { return $this->cookiekey; }
+ function setCookieKey($value) { $this->cookiekey = $value; }
+}
+?>
diff --git a/tables.sql b/tables.sql
new file mode 100644
index 0000000..578fa06
--- /dev/null
+++ b/tables.sql
@@ -0,0 +1,68 @@
+--
+-- Table structure for table `sc_bookmarks`
+--
+
+CREATE TABLE `sc_bookmarks` (
+ `bId` int(11) NOT NULL auto_increment,
+ `uId` int(11) NOT NULL default '0',
+ `bIp` varchar(40) default NULL,
+ `bStatus` tinyint(1) NOT NULL default '0',
+ `bDatetime` datetime NOT NULL default '0000-00-00 00:00:00',
+ `bModified` datetime NOT NULL default '0000-00-00 00:00:00',
+ `bTitle` varchar(255) NOT NULL default '',
+ `bAddress` text NOT NULL,
+ `bDescription` varchar(255) default NULL,
+ `bHash` varchar(32) NOT NULL default '',
+ PRIMARY KEY (`bId`),
+ KEY `sc_bookmarks_usd` (`uId`,`bStatus`,`bDatetime`),
+ KEY `sc_bookmarks_hui` (`bHash`,`uId`,`bId`),
+ KEY `sc_bookmarks_du` (`bDatetime`,`uId`)
+);
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `sc_tags`
+--
+
+CREATE TABLE `sc_tags` (
+ `id` int(11) NOT NULL auto_increment,
+ `bId` int(11) NOT NULL default '0',
+ `tag` varchar(32) NOT NULL default '',
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `sc_tags_tag_bId` (`tag`,`bId`),
+ KEY `sc_tags_bId` (`bId`)
+);
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `scUsers`
+--
+
+CREATE TABLE `sc_users` (
+ `uId` int(11) NOT NULL auto_increment,
+ `username` varchar(25) NOT NULL default '',
+ `password` varchar(40) NOT NULL default '',
+ `uDatetime` datetime NOT NULL default '0000-00-00 00:00:00',
+ `uModified` datetime NOT NULL default '0000-00-00 00:00:00',
+ `name` varchar(50) default NULL,
+ `email` varchar(50) NOT NULL default '',
+ `homepage` varchar(255) default NULL,
+ `uContent` text,
+ PRIMARY KEY (`uId`)
+);
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `sc_watched`
+--
+
+CREATE TABLE `sc_watched` (
+ `wId` int(11) NOT NULL auto_increment,
+ `uId` int(11) NOT NULL default '0',
+ `watched` int(11) NOT NULL default '0',
+ PRIMARY KEY (`wId`),
+ KEY `sc_watched_uId` (`uId`)
+); \ No newline at end of file
diff --git a/tagdelete.php b/tagdelete.php
new file mode 100644
index 0000000..9f11bdd
--- /dev/null
+++ b/tagdelete.php
@@ -0,0 +1,48 @@
+<?php
+/***************************************************************************
+Copyright (C) 2006 Scuttle project
+http://sourceforge.net/projects/scuttle/
+http://scuttle.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; 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
+***************************************************************************/
+
+require_once('header.inc.php');
+$tagservice = & ServiceFactory :: getServiceInstance('TagService');
+$templateservice = & ServiceFactory :: getServiceInstance('TemplateService');
+$userservice = & ServiceFactory :: getServiceInstance('UserService');
+
+list ($url, $tag) = explode('/', $_SERVER['PATH_INFO']);
+
+if ($_POST['confirm']) {
+ if ($tagservice->deleteTag($tag)) {
+ $tplVars['msg'] = T_('Tag deleted');
+ $logged_on_user = $userservice->getCurrentUser();
+ header('Location: '. createURL('bookmarks', $logged_on_user[$userservice->getFieldName('username')]));
+ } else {
+ $tplVars['error'] = T_('Failed to delete the tag');
+ $templateservice->loadTemplate('error.500.tpl', $tplVars);
+ exit();
+ }
+} elseif ($_POST['cancel']) {
+ $logged_on_user = $userservice->getCurrentUser();
+ header('Location: '. createURL('bookmarks', $logged_on_user[$userservice->getFieldName('username')] .'/'. $tags));
+}
+
+$tplVars['subtitle'] = T_('Delete Tag') .': '. $tag;
+$tplVars['formaction'] = $_SERVER['SCRIPT_NAME'] .'/'. $tag;
+$tplVars['referrer'] = $_SERVER['HTTP_REFERER'];
+$templateservice->loadTemplate('tagdelete.tpl', $tplVars);
+?> \ No newline at end of file
diff --git a/tagrename.php b/tagrename.php
new file mode 100644
index 0000000..2d611a7
--- /dev/null
+++ b/tagrename.php
@@ -0,0 +1,63 @@
+<?php
+/***************************************************************************
+Copyright (C) 2006 - 2007 Scuttle project
+http://sourceforge.net/projects/scuttle/
+http://scuttle.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; 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
+***************************************************************************/
+
+require_once('header.inc.php');
+$tagservice = & ServiceFactory :: getServiceInstance('TagService');
+$templateservice = & ServiceFactory :: getServiceInstance('TemplateService');
+$userservice = & ServiceFactory :: getServiceInstance('UserService');
+
+$tag = isset($_GET['query']) ? $_GET['query'] : NULL;
+$template = 'tagrename.tpl';
+
+if ($_POST['confirm']) {
+ if (isset($_POST['old']) && trim($_POST['old']) != '')
+ $old = trim($_REQUEST['old']);
+ else
+ $old = NULL;
+
+ if (isset($_POST['new']) && trim($_POST['new']) != '')
+ $new = trim($_POST['new']);
+ else
+ $new = NULL;
+
+ if (
+ !is_null($old) &&
+ !is_null($new) &&
+ $tagservice->renameTag($userservice->getCurrentUserId(), $old, $new)
+ ) {
+ $tplVars['msg'] = T_('Tag renamed');
+ $logged_on_user = $userservice->getCurrentUser();
+ header('Location: '. createURL('bookmarks', $logged_on_user[$userservice->getFieldName('username')]));
+ } else {
+ $tplVars['error'] = T_('Failed to rename the tag');
+ $template = 'error.500.tpl';
+ }
+} elseif ($_POST['cancel']) {
+ $logged_on_user = $userservice->getCurrentUser();
+ header('Location: '. createURL('bookmarks', $logged_on_user[$userservice->getFieldName('username')] .'/'. $tags));
+} else {
+ $tplVars['subtitle'] = T_('Rename Tag') .': '. $tag;
+ $tplVars['formaction'] = $_SERVER['SCRIPT_NAME'] .'/'. $tag;
+ $tplVars['referrer'] = $_SERVER['HTTP_REFERER'];
+ $tplVars['old'] = $tag;
+}
+$templateservice->loadTemplate($template, $tplVars);
+?> \ No newline at end of file
diff --git a/tags.php b/tags.php
new file mode 100644
index 0000000..ff46881
--- /dev/null
+++ b/tags.php
@@ -0,0 +1,88 @@
+<?php
+/***************************************************************************
+Copyright (C) 2004 - 2006 Scuttle project
+http://sourceforge.net/projects/scuttle/
+http://scuttle.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; 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
+***************************************************************************/
+
+require_once('header.inc.php');
+
+$bookmarkservice =& ServiceFactory::getServiceInstance('BookmarkService');
+$templateservice =& ServiceFactory::getServiceInstance('TemplateService');
+$userservice =& ServiceFactory::getServiceInstance('UserService');
+$cacheservice =& ServiceFactory::getServiceInstance('CacheService');
+
+$tplVars = array();
+
+list($url, $cat) = explode('/', $_SERVER['PATH_INFO']);
+if (!$cat) {
+ header('Location: '. createURL('populartags'));
+ exit;
+} else {
+ $cattitle = str_replace('+', ' + ', $cat);
+}
+$pagetitle = T_('Tags') .': '. $cattitle;
+
+if ($usecache) {
+ // Generate hash for caching on
+ if ($userservice->isLoggedOn()) {
+ $hash = md5($_SERVER['REQUEST_URI'] . $userservice->getCurrentUserID());
+ } else {
+ $hash = md5($_SERVER['REQUEST_URI']);
+ }
+
+ // Cache for 30 minutes
+ $cacheservice->Start($hash, 1800);
+}
+
+// Header variables
+$tplVars['pagetitle'] = $pagetitle;
+$tplVars['loadjs'] = true;
+$tplVars['rsschannels'] = array(
+ array(filter($sitename .': '. $pagetitle), createURL('rss', 'all/'. filter($cat, 'url')))
+);
+
+// Pagination
+$perpage = getPerPageCount();
+if (isset($_GET['page']) && intval($_GET['page']) > 1) {
+ $page = $_GET['page'];
+ $start = ($page - 1) * $perpage;
+} else {
+ $page = 0;
+ $start = 0;
+}
+
+$tplVars['page'] = $page;
+$tplVars['start'] = $start;
+$tplVars['popCount'] = 25;
+$tplVars['currenttag'] = $cat;
+$tplVars['sidebar_blocks'] = array('related', 'popular');
+$tplVars['subtitle'] = filter($pagetitle);
+$tplVars['bookmarkCount'] = $start + 1;
+$bookmarks =& $bookmarkservice->getBookmarks($start, $perpage, NULL, $cat, NULL, getSortOrder());
+$tplVars['total'] = $bookmarks['total'];
+$tplVars['bookmarks'] =& $bookmarks['bookmarks'];
+$tplVars['cat_url'] = createURL('tags', '%2$s');
+$tplVars['nav_url'] = createURL('tags', '%2$s%3$s');
+
+$templateservice->loadTemplate('bookmarks.tpl', $tplVars);
+
+if ($usecache) {
+ // Cache output if existing copy has expired
+ $cacheservice->End($hash);
+}
+?>
diff --git a/templates/about.tpl.php b/templates/about.tpl.php
new file mode 100644
index 0000000..494a2e3
--- /dev/null
+++ b/templates/about.tpl.php
@@ -0,0 +1,20 @@
+<?php
+$this->includeTemplate($GLOBALS['top_include']);
+?>
+
+<ul>
+<li><?php echo T_('<strong>Store</strong> all your favourite links in one place, accessible from anywhere.'); ?></li>
+<li><?php echo T_('<strong>Share</strong> your bookmarks with everyone, with friends on your watchlist or just keep them private.') ;?></li>
+<li><?php echo T_('<strong>Tag</strong> your bookmarks with as many labels as you want, instead of wrestling with folders.'); ?></li>
+<li><?php echo sprintf(T_('<strong><a href="register.php">Register now</a></strong> to start using %s!'), $GLOBALS['sitename']); ?></li>
+</ul>
+
+<h3><?php echo T_('Geek Stuff'); ?></h3>
+<ul>
+<li><?php echo sprintf(T_('%s is based on <a href="http://sourceforge.net/projects/scuttle/">an open-source project</a> licensed under the <a href="http://www.gnu.org/copyleft/gpl.html"><acronym title="GNU\'s Not Unix">GNU</acronym> General Public License</a>. This means you can host it on your own web server for free, whether it is on the Internet, a private network or just your own computer.'), $GLOBALS['sitename']); ?></li>
+<li><?php echo sprintf(T_('%1$s supports most of the <a href="http://del.icio.us/doc/api">del.icio.us <abbr title="Application Programming Interface">API</abbr></a>. Almost all of the neat tools made for that system can be modified to work with %1$s instead. If you find a tool that won\'t let you change the API address, ask the creator to add this setting. You never know, they might just do it.'), $GLOBALS['sitename']); ?></li>
+</ul>
+
+<?php
+$this->includeTemplate($GLOBALS['bottom_include']);
+?> \ No newline at end of file
diff --git a/templates/bookmarks.tpl.php b/templates/bookmarks.tpl.php
new file mode 100644
index 0000000..368ec8b
--- /dev/null
+++ b/templates/bookmarks.tpl.php
@@ -0,0 +1,166 @@
+<?php
+$userservice =& ServiceFactory::getServiceInstance('UserService');
+$bookmarkservice =& ServiceFactory::getServiceInstance('BookmarkService');
+
+$logged_on_userid = $userservice->getCurrentUserId();
+$this->includeTemplate($GLOBALS['top_include']);
+
+include('search.inc.php');
+if (count($bookmarks) > 0) {
+?>
+
+<script type="text/javascript">
+window.onload = playerLoad;
+</script>
+
+<p id="sort">
+ <?php echo T_("Sort by:"); ?>
+ <a href="?sort=date_desc"><?php echo T_("Date"); ?></a><span> / </span>
+ <a href="?sort=title_asc"><?php echo T_("Title"); ?></a><span> / </span>
+ <?php
+ if (!isset($hash)) {
+ ?>
+ <a href="?sort=url_asc"><?php echo T_("URL"); ?></a>
+ <?php
+ }
+ ?>
+</p>
+
+<ol<?php echo ($start > 0 ? ' start="'. ++$start .'"' : ''); ?> id="bookmarks">
+
+ <?php
+ foreach(array_keys($bookmarks) as $key) {
+ $row =& $bookmarks[$key];
+ switch ($row['bStatus']) {
+ case 0:
+ $access = '';
+ break;
+ case 1:
+ $access = ' shared';
+ break;
+ case 2:
+ $access = ' private';
+ break;
+ }
+
+ $cats = '';
+ $tags = $row['tags'];
+ foreach(array_keys($tags) as $key) {
+ $tag =& $tags[$key];
+ $cats .= '<a href="'. sprintf($cat_url, filter($user, 'url'), filter($tag, 'url')) .'" rel="tag">'. filter($tag) .'</a>, ';
+ }
+ $cats = substr($cats, 0, -2);
+ if ($cats != '') {
+ $cats = ' to '. $cats;
+ }
+
+ // Edit and delete links
+ $edit = '';
+ if ($bookmarkservice->editAllowed($row['bId'])) {
+ $edit = ' - <a href="'. createURL('edit', $row['bId']) .'">'. T_('Edit') .'</a><script type="text/javascript">document.write(" - <a href=\"#\" onclick=\"deleteBookmark(this, '. $row['bId'] .'); return false;\">'. T_('Delete') .'<\/a>");</script>';
+ }
+
+ // User attribution
+ $copy = '';
+ if (!isset($user) || isset($watched)) {
+ $copy = ' '. T_('by') .' <a href="'. createURL('bookmarks', $row['username']) .'">'. $row['username'] .'</a>';
+ }
+
+ // Udders!
+ if (!isset($hash)) {
+ $others = $bookmarkservice->countOthers($row['bAddress']);
+ $ostart = '<a href="'. createURL('history', $row['bHash']) .'">';
+ $oend = '</a>';
+ switch ($others) {
+ case 0:
+ break;
+ case 1:
+ $copy .= sprintf(T_(' and %s1 other%s'), $ostart, $oend);
+ break;
+ default:
+ $copy .= sprintf(T_(' and %2$s%1$s others%3$s'), $others, $ostart, $oend);
+ }
+ }
+
+ // Copy link
+ if ($userservice->isLoggedOn() && ($logged_on_userid != $row['uId'])) {
+ // Get the username of the current user
+ $currentUser = $userservice->getCurrentUser();
+ $currentUsername = $currentUser[$userservice->getFieldName('username')];
+ $copy .= ' - <a href="'. createURL('bookmarks', $currentUsername .'?action=add&amp;address='. urlencode($row['bAddress']) .'&amp;title='. urlencode($row['bTitle'])) .'">'. T_('Copy') .'</a>';
+ }
+
+ // Nofollow option
+ $rel = '';
+ if ($GLOBALS['nofollow']) {
+ $rel = ' rel="nofollow"';
+ }
+
+ $address = filter($row['bAddress']);
+
+ // Redirection option
+ if ($GLOBALS['useredir']) {
+ $address = $GLOBALS['url_redir'] . $address;
+ }
+
+ // Output
+ echo '<li class="xfolkentry'. $access .'">'."\n";
+ echo '<div class="link"><a href="'. $address .'"'. $rel .' class="taggedlink">'. filter($row['bTitle']) ."</a></div>\n";
+ if ($row['bDescription'] != '') {
+ echo '<div class="description">'. filter($row['bDescription']) ."</div>\n";
+ }
+ echo '<div class="meta">'. date($GLOBALS['shortdate'], strtotime($row['bDatetime'])) . $cats . $copy . $edit ."</div>\n";
+ echo "</li>\n";
+ }
+ ?>
+
+</ol>
+
+ <?php
+ // PAGINATION
+
+ // Ordering
+ $sortOrder = '';
+ if (isset($_GET['sort'])) {
+ $sortOrder = 'sort='. $_GET['sort'];
+ }
+
+ $sortAmp = (($sortOrder) ? '&amp;'. $sortOrder : '');
+ $sortQue = (($sortOrder) ? '?'. $sortOrder : '');
+
+ // Previous
+ $perpage = getPerPageCount();
+ if (!$page || $page < 2) {
+ $page = 1;
+ $start = 0;
+ $bfirst = '<span class="disable">'. T_('First') .'</span>';
+ $bprev = '<span class="disable">'. T_('Previous') .'</span>';
+ } else {
+ $prev = $page - 1;
+ $prev = 'page='. $prev;
+ $start = ($page - 1) * $perpage;
+ $bfirst= '<a href="'. sprintf($nav_url, $user, $currenttag, '') . $sortQue .'">'. T_('First') .'</a>';
+ $bprev = '<a href="'. sprintf($nav_url, $user, $currenttag, '?') . $prev . $sortAmp .'">'. T_('Previous') .'</a>';
+ }
+
+ // Next
+ $next = $page + 1;
+ $totalpages = ceil($total / $perpage);
+ if (count($bookmarks) < $perpage || $perpage * $page == $total) {
+ $bnext = '<span class="disable">'. T_('Next') .'</span>';
+ $blast = '<span class="disable">'. T_('Last') .'</span>';
+ } else {
+ $bnext = '<a href="'. sprintf($nav_url, $user, $currenttag, '?page=') . $next . $sortAmp .'">'. T_('Next') .'</a>';
+ $blast = '<a href="'. sprintf($nav_url, $user, $currenttag, '?page=') . $totalpages . $sortAmp .'">'. T_('Last') .'</a>';
+ }
+ echo '<p class="paging">'. $bfirst .'<span> / </span>'. $bprev .'<span> / </span>'. $bnext .'<span> / </span>'. $blast .'<span> / </span>'. sprintf(T_('Page %d of %d'), $page, $totalpages) .'</p>';
+} else {
+?>
+
+ <p class="error"><?php echo T_('No bookmarks available'); ?>.</p>
+
+<?php
+}
+$this->includeTemplate('sidebar.tpl');
+$this->includeTemplate($GLOBALS['bottom_include']);
+?>
diff --git a/templates/bottom.inc.php b/templates/bottom.inc.php
new file mode 100644
index 0000000..691287b
--- /dev/null
+++ b/templates/bottom.inc.php
@@ -0,0 +1,2 @@
+</body>
+</html> \ No newline at end of file
diff --git a/templates/dynamictags.inc.php b/templates/dynamictags.inc.php
new file mode 100644
index 0000000..5a85143
--- /dev/null
+++ b/templates/dynamictags.inc.php
@@ -0,0 +1,120 @@
+<?php
+/***************************************************************************
+Copyright (C) 2005 - 2006 Scuttle project
+http://sourceforge.net/projects/scuttle/
+http://scuttle.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; 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
+***************************************************************************/
+
+$tagservice = & ServiceFactory :: getServiceInstance('TagService');
+$userservice = & ServiceFactory :: getServiceInstance('UserService');
+
+$logged_on_userid = $userservice->getCurrentUserId();
+
+$userPopularTags =& $tagservice->getPopularTags($logged_on_userid, 25, $logged_on_userid);
+$userPopularTagsCloud =& $tagservice->tagCloud($userPopularTags, 5, 90, 175);
+$userPopularTagsCount = count($userPopularTags);
+
+if ($userPopularTagsCount > 0) {
+?>
+
+<script type="text/javascript">
+Array.prototype.contains = function (ele) {
+ for (var i = 0; i < this.length; i++) {
+ if (this[i] == ele) {
+ return true;
+ }
+ }
+ return false;
+};
+
+Array.prototype.remove = function (ele) {
+ var arr = new Array();
+ var count = 0;
+ for (var i = 0; i < this.length; i++) {
+ if (this[i] != ele) {
+ arr[count] = this[i];
+ count++;
+ }
+ }
+ return arr;
+};
+
+function addonload(addition) {
+ var existing = window.onload;
+ window.onload = function () {
+ existing();
+ addition();
+ }
+}
+
+addonload(
+ function () {
+ var taglist = document.getElementById('tags');
+ var tags = taglist.value.split(', ');
+
+ var populartags = document.getElementById('popularTags').getElementsByTagName('span');
+
+ for (var i = 0; i < populartags.length; i++) {
+ if (tags.contains(populartags[i].innerHTML)) {
+ populartags[i].className = 'selected';
+ }
+ }
+ }
+);
+
+function addTag(ele) {
+ var thisTag = ele.innerHTML;
+ var taglist = document.getElementById('tags');
+ var tags = taglist.value.split(', ');
+
+ // If tag is already listed, remove it
+ if (tags.contains(thisTag)) {
+ tags = tags.remove(thisTag);
+ ele.className = 'unselected';
+
+ // Otherwise add it
+ } else {
+ tags.splice(0, 0, thisTag);
+ ele.className = 'selected';
+ }
+
+ taglist.value = tags.join(', ');
+
+ document.getElementById('tags').focus();
+}
+
+document.write('<div class="collapsible">');
+document.write('<h3><?php echo T_('Popular Tags'); ?><\/h3>');
+document.write('<p id="popularTags" class="tags">');
+
+<?php
+$taglist = '';
+foreach(array_keys($userPopularTagsCloud) as $key) {
+ $row =& $userPopularTagsCloud[$key];
+ $entries = T_ngettext('bookmark', 'bookmarks', $row['bCount']);
+ $taglist .= '<span title="'. $row['bCount'] .' '. $entries .'" style="font-size:'. $row['size'] .'" onclick="addTag(this)">'. filter($row['tag']) .'<\/span> ';
+}
+?>
+
+document.write('<?php echo $taglist ?>');
+document.write('<\/p>');
+document.write('<\/div>');
+</script>
+
+<?php
+}
+?> \ No newline at end of file
diff --git a/templates/editbookmark.tpl.php b/templates/editbookmark.tpl.php
new file mode 100644
index 0000000..a590d81
--- /dev/null
+++ b/templates/editbookmark.tpl.php
@@ -0,0 +1,120 @@
+<?php
+$this->includeTemplate($GLOBALS['top_include']);
+
+$accessPublic = '';
+$accessShared = '';
+$accessPrivate = '';
+switch ($row['bStatus']) {
+ case 0 :
+ $accessPublic = ' selected="selected"';
+ break;
+ case 1 :
+ $accessShared = ' selected="selected"';
+ break;
+ case 2 :
+ $accessPrivate = ' selected="selected"';
+ break;
+}
+?>
+
+<script type="text/javascript">
+window.onload = function() {
+ document.getElementById("address").focus();
+}
+</script>
+
+<form action="<?php echo $formaction; ?>" method="post">
+<table>
+<tr>
+ <th align="left"><?php echo T_('Address'); ?></th>
+ <td><input type="text" id="address" name="address" size="75" maxlength="65535" value="<?php echo filter($row['bAddress'], 'xml'); ?>" onblur="useAddress(this)" /></td>
+ <td>&larr; <?php echo T_('Required'); ?></td>
+</tr>
+<tr>
+ <th align="left"><?php echo T_('Title'); ?></th>
+ <td><input type="text" id="titleField" name="title" size="75" maxlength="255" value="<?php echo filter($row['bTitle'], 'xml'); ?>" onkeypress="this.style.backgroundImage = 'none';" /></td>
+ <td>&larr; <?php echo T_('Required'); ?></td>
+</tr>
+<tr>
+ <th align="left"><?php echo T_('Description'); ?></th>
+ <td><input type="text" name="description" size="75" maxlength="255" value="<?php echo filter($row['bDescription'], 'xml'); ?>" /></td>
+ <td></td>
+</tr>
+<tr>
+ <th align="left"><?php echo T_('Tags'); ?></th>
+ <td><input type="text" id="tags" name="tags" size="75" value="<?php echo filter(implode(', ', $row['tags']), 'xml'); ?>" /></td>
+ <td>&larr; <?php echo T_('Comma-separated'); ?></td>
+</tr>
+<tr>
+ <th align="left"><?php echo T_('Privacy'); ?></th>
+ <td>
+ <select name="status">
+ <option value="0"<?php echo $accessPublic ?>><?php echo T_('Public'); ?></option>
+ <option value="1"<?php echo $accessShared ?>><?php echo T_('Shared with Watch List'); ?></option>
+ <option value="2"<?php echo $accessPrivate ?>><?php echo T_('Private'); ?></option>
+ </select>
+ </td>
+ <td></td>
+</tr>
+<tr>
+ <td></td>
+ <td>
+ <input type="submit" name="submitted" value="<?php echo $btnsubmit; ?>" />
+ <?php
+ if ($showdelete) {
+ ?>
+ <input type="submit" name="delete" value="<?php echo T_('Delete Bookmark'); ?>" />
+ <?php
+ }
+ if ($popup) {
+ ?>
+ <input type="hidden" name="popup" value="1" />
+ <?php
+ } elseif ($referrer) {
+ ?>
+ <input type="hidden" name="referrer" value="<?php echo $referrer; ?>" />
+ <?php
+ }
+ ?>
+ </td>
+ <td></td>
+</tr>
+</table>
+</form>
+
+<?php
+// Dynamic tag selection
+$this->includeTemplate('dynamictags.inc');
+
+// Bookmarklets and import links
+if (empty($_REQUEST['popup']) && !$showdelete) {
+?>
+
+<h3><?php echo T_('Bookmarklet'); ?></h3>
+<p><?php echo sprintf(T_("Drag one of the following bookmarklets to your browser's bookmarks and click it whenever you want to add the page you are on to %s"), $GLOBALS['sitename']); ?>:</p>
+
+<script type="text/javascript">
+var selection = '';
+if (window.getSelection) {
+ selection = 'window.getSelection()';
+} else if (document.getSelection) {
+ selection = 'document.getSelection()';
+} else if (document.selection) {
+ selection = 'document.selection.createRange().text';
+}
+document.write('<ul>');
+document.write('<li><a href="javascript:x=document;a=encodeURIComponent(x.location.href);t=encodeURIComponent(x.title);d=encodeURIComponent('+selection+');location.href=\'<?php echo createURL('bookmarks', $GLOBALS['user']); ?>?action=add&amp;address=\'+a+\'&amp;title=\'+t+\'&amp;description=\'+d;void 0;"><?php echo sprintf(T_('Post to %s'), $GLOBALS['sitename']); ?><\/a><\/li>');
+document.write('<li><a href="javascript:x=document;a=encodeURIComponent(x.location.href);t=encodeURIComponent(x.title);d=encodeURIComponent('+selection+');open(\'<?php echo createURL('bookmarks', $GLOBALS['user']); ?>?action=add&amp;popup=1&amp;address=\'+a+\'&amp;title=\'+t+\'&amp;description=\'+d,\'<?php echo $GLOBALS['sitename']; ?>\',\'modal=1,status=0,scrollbars=1,toolbar=0,resizable=1,width=730,height=465,left=\'+(screen.width-730)/2+\',top=\'+(screen.height-425)/2);void 0;"><?php echo sprintf(T_('Post to %s (Pop-up)'), $GLOBALS['sitename']); ?><\/a><\/li>');
+document.write('<\/ul>');
+</script>
+
+<h3><?php echo T_('Import'); ?></h3>
+<ul>
+ <li><a href="<?php echo createURL('importNetscape'); ?>"><?php echo T_('Import bookmarks from bookmark file'); ?></a> (<?php echo T_('Internet Explorer, Mozilla Firefox and Netscape'); ?>)</li>
+ <li><a href="<?php echo createURL('import'); ?>"><?php echo T_('Import bookmarks from del.icio.us'); ?></a></li>
+</ul>
+
+<?php
+}
+$this->includeTemplate($GLOBALS['bottom_include']);
+?> \ No newline at end of file
diff --git a/templates/editprofile.tpl.php b/templates/editprofile.tpl.php
new file mode 100644
index 0000000..ebfc972
--- /dev/null
+++ b/templates/editprofile.tpl.php
@@ -0,0 +1,56 @@
+<?php
+$this->includeTemplate($GLOBALS['top_include']);
+?>
+
+<form action="<?php echo $formaction; ?>" method="post">
+
+<h3><?php echo T_('Account Details'); ?></h3>
+
+<table class="profile">
+<tr>
+ <th align="left"><?php echo T_('Username'); ?></th>
+ <td><?php echo $user; ?></td>
+ <td></td>
+</tr>
+<tr>
+ <th align="left"><?php echo T_('New Password'); ?></th>
+ <td><input type="password" name="pPass" size="20" /></td>
+ <td></td>
+</tr>
+<tr>
+ <th align="left"><?php echo T_('Confirm Password'); ?></th>
+ <td><input type="password" name="pPassConf" size="20" /></td>
+ <td></td>
+</tr>
+<tr>
+ <th align="left"><?php echo T_('E-mail'); ?></th>
+ <td><input type="text" name="pMail" size="75" value="<?php echo filter($row['email'], 'xml'); ?>" /></td>
+ <td>&larr; <?php echo T_('Required'); ?></td>
+</tr>
+</table>
+
+<h3><?php echo T_('Personal Details'); ?></h3>
+
+<table class="profile">
+<tr>
+ <th align="left"><?php echo T_('Name'); ?></th>
+ <td><input type="text" name="pName" size="75" value="<?php echo filter($row['name'], 'xml'); ?>" /></td>
+</tr>
+<tr>
+ <th align="left"><?php echo T_('Homepage'); ?></th>
+ <td><input type="text" name="pPage" size="75" value="<?php echo filter($row['homepage'], 'xml'); ?>" /></td>
+</tr>
+<tr>
+ <th align="left"><?php echo T_('Description'); ?></th>
+ <td><textarea name="pDesc" cols="75" rows="10"><?php echo $row['uContent']; ?></textarea></td>
+</tr>
+<tr>
+ <th></th>
+ <td><input type="submit" name="submitted" value="<?php echo T_('Save Changes'); ?>" /></td>
+</tr>
+</table>
+</form>
+
+<?php
+$this->includeTemplate($GLOBALS['bottom_include']);
+?> \ No newline at end of file
diff --git a/templates/error.404.tpl.php b/templates/error.404.tpl.php
new file mode 100644
index 0000000..fe9401d
--- /dev/null
+++ b/templates/error.404.tpl.php
@@ -0,0 +1,9 @@
+<?php
+header('HTTP/1.x 404 Not Found');
+$this->includeTemplate($GLOBALS['top_include']);
+if (!$error) {
+ echo '<h1>'. T_('Not Found') .'</h1>';
+ echo '<p>'. T_('The requested URL was not found on this server') .'</p>';
+}
+$this->includeTemplate($GLOBALS['bottom_include']);
+?> \ No newline at end of file
diff --git a/templates/error.500.tpl.php b/templates/error.500.tpl.php
new file mode 100644
index 0000000..1d7f7ae
--- /dev/null
+++ b/templates/error.500.tpl.php
@@ -0,0 +1,9 @@
+<?php
+header('HTTP/1.x 500 Server error');
+$this->includeTemplate($GLOBALS['top_include']);
+if (!$error) {
+ echo '<h1>'. T_('General server error') .'</h1>';
+ echo '<p>'. T_('The requested URL could not be processed') .'</p>';
+}
+$this->includeTemplate($GLOBALS['bottom_include']);
+?>
diff --git a/templates/importDelicious.tpl.php b/templates/importDelicious.tpl.php
new file mode 100644
index 0000000..bc4d892
--- /dev/null
+++ b/templates/importDelicious.tpl.php
@@ -0,0 +1,42 @@
+<?php
+$this->includeTemplate($GLOBALS['top_include']);
+?>
+
+<form id="import" enctype="multipart/form-data" action="<?php echo $formaction; ?>" method="post">
+<table>
+<tr valign="top">
+ <th align="left"><?php echo T_('File'); ?></th>
+ <td>
+ <input type="hidden" name="MAX_FILE_SIZE" value="1024000" />
+ <input type="file" name="userfile" size="50" />
+ </td>
+</tr>
+<tr valign="top">
+ <th align="left"><?php echo T_('Privacy'); ?></th>
+ <td>
+ <select name="status">
+ <option value="0"><?php echo T_('Public'); ?></option>
+ <option value="1"><?php echo T_('Shared with Watchlist'); ?></option>
+ <option value="2"><?php echo T_('Private'); ?></option>
+ </select>
+ </td>
+</tr>
+<tr>
+ <td />
+ <td><input type="submit" value="<?php echo T_('Import'); ?>" /></td>
+</tr>
+</table>
+</form>
+
+<h3><?php echo T_('Instructions'); ?></h3>
+<ol>
+ <li><?php echo T_('Log in to the <a href="http://del.icio.us/api/posts/all">export page at del.icio.us</a>'); ?>.</li>
+ <li><?php echo T_('Save the resulting <abbr title="Extensible Markup Language">XML</abbr> file to your computer'); ?>.</li>
+ <li><?php echo T_('Click <kbd>Browse...</kbd> to find this file on your computer. The maximum size the file can be is 1MB'); ?>.</li>
+ <li><?php echo T_('Select the default privacy setting for your imported bookmarks'); ?>.</li>
+ <li><?php echo T_('Click <kbd>Import</kbd> to start importing the bookmarks; it may take a minute'); ?>.</li>
+</ol>
+
+<?php
+$this->includeTemplate($GLOBALS['bottom_include']);
+?> \ No newline at end of file
diff --git a/templates/importNetscape.tpl.php b/templates/importNetscape.tpl.php
new file mode 100644
index 0000000..627a5af
--- /dev/null
+++ b/templates/importNetscape.tpl.php
@@ -0,0 +1,50 @@
+<?php
+$this->includeTemplate($GLOBALS['top_include']);
+?>
+
+<div id="bookmarks">
+ <form id="import" enctype="multipart/form-data" action="<?php echo $formaction; ?>" method="post">
+ <table>
+ <tr valign="top">
+ <th align="left"><?php echo T_('File'); ?></th>
+ <td>
+ <input type="hidden" name="MAX_FILE_SIZE" value="1024000" />
+ <input type="file" name="userfile" size="50" />
+ </td>
+ </tr>
+ <tr valign="top">
+ <th align="left"><?php echo T_('Privacy'); ?></th>
+ <td>
+ <select name="status">
+ <option value="0"><?php echo T_('Public'); ?></option>
+ <option value="1"><?php echo T_('Shared with Watchlist'); ?></option>
+ <option value="2"><?php echo T_('Private'); ?></option>
+ </select>
+ </td>
+ </tr>
+ <tr>
+ <td />
+ <td><input type="submit" value="<?php echo T_('Import'); ?>" /></td>
+ </tr>
+ </table>
+ </form>
+
+ <h3><?php echo T_('Instructions'); ?></h3>
+ <ol>
+ <li>
+ <p><?php echo T_('Export your bookmarks from your browser to a file'); ?>:</p>
+ <ul>
+ <li><?php echo T_('Internet Explorer: <kbd>File &gt; Import and Export... &gt; Export Favorites'); ?></kbd></li>
+ <li><?php echo T_('Mozilla Firefox: <kbd>Bookmarks &gt; Manage Bookmarks... &gt; File &gt; Export...'); ?></kbd></li>
+ <li><?php echo T_('Netscape: <kbd>Bookmarks &gt; Manage Bookmarks... &gt; Tools &gt; Export...'); ?></kbd></li>
+ </ul>
+ </li>
+ <li><?php echo T_('Click <kbd>Browse...</kbd> to find the saved bookmark file on your computer. The maximum size the file can be is 1MB'); ?>.</li>
+ <li><?php echo T_('Select the default privacy setting for your imported bookmarks'); ?>.</li>
+ <li><?php echo T_('Click <kbd>Import</kbd> to start importing the bookmarks; it may take a minute'); ?>.</li>
+ </ol>
+</div>
+
+<?php
+$this->includeTemplate($GLOBALS['bottom_include']);
+?> \ No newline at end of file
diff --git a/templates/login.tpl.php b/templates/login.tpl.php
new file mode 100644
index 0000000..6137dc0
--- /dev/null
+++ b/templates/login.tpl.php
@@ -0,0 +1,35 @@
+<?php
+$this->includeTemplate($GLOBALS['top_include']);
+?>
+
+<script type="text/javascript">
+window.onload = function() {
+ document.getElementById("username").focus();
+}
+</script>
+
+<form action="<?php echo $formaction; ?>" method="post">
+ <div><input type="hidden" name="query" value="<?php echo $querystring; ?>" /></div>
+ <table>
+ <tr>
+ <th align="left"><label for="username"><?php echo T_('Username'); ?></label></th>
+ <td><input type="text" id="username" name="username" size="20" /></td>
+ <td></td>
+ </tr>
+ <tr>
+ <th align="left"><label for="password"><?php echo T_('Password'); ?></label></th>
+ <td><input type="password" id="password" name="password" size="20" /></td>
+ <td><input type="checkbox" name="keeppass" value="yes" /> <?php echo T_("Don't ask for my password for 2 weeks"); ?>.</td>
+ </tr>
+ <tr>
+ <td></td>
+ <td><input type="submit" name="submitted" value="<?php echo T_('Log In'); ?>" /></td>
+ <td></td>
+ </tr>
+ </table>
+ <p>&raquo; <a href="<?php echo $GLOBALS['root'] ?>password.php"><?php echo T_('Forgotten your password?') ?></p>
+</form>
+
+<?php
+$this->includeTemplate($GLOBALS['bottom_include']);
+?> \ No newline at end of file
diff --git a/templates/password.tpl.php b/templates/password.tpl.php
new file mode 100644
index 0000000..55dbed6
--- /dev/null
+++ b/templates/password.tpl.php
@@ -0,0 +1,26 @@
+<?php
+$this->includeTemplate($GLOBALS['top_include']);
+?>
+
+<p><?php echo sprintf(T_('If you have forgotten your password, %s can generate a new one. Enter the username and e-mail address of your account into the form below and we will e-mail your new password to you.'), $GLOBALS['sitename']); ?></p>
+
+<form action="<?php echo $formaction; ?>" method="post">
+ <table>
+ <tr>
+ <th align="left"><label for="username"><?php echo T_('Username'); ?></label></th>
+ <td><input type="text" id="username" name="username" size="20" class="required" /></td>
+ </tr>
+ <tr>
+ <th align="left"><label for="email"><?php echo T_('E-mail'); ?></label></th>
+ <td><input type="text" id="email" name="email" size="40" class="required" /></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td><input type="submit" name="submitted" value="<?php echo T_('Generate Password'); ?>" /></td>
+ </tr>
+ </table>
+</form>
+
+<?php
+$this->includeTemplate($GLOBALS['bottom_include']);
+?> \ No newline at end of file
diff --git a/templates/profile.tpl.php b/templates/profile.tpl.php
new file mode 100644
index 0000000..e9ff91b
--- /dev/null
+++ b/templates/profile.tpl.php
@@ -0,0 +1,67 @@
+<?php
+$userservice =& ServiceFactory::getServiceInstance('UserService');
+$this->includeTemplate($GLOBALS['top_include']);
+?>
+
+<dl id="profile">
+<dt><?php echo T_('Username'); ?></dt>
+ <dd><?php echo $user; ?></dd>
+<?php
+if ($row['name'] != "") {
+?>
+<dt><?php echo T_('Name'); ?></dt>
+ <dd><?php echo $row['name']; ?></dd>
+<?php
+}
+if ($row['homepage'] != "") {
+?>
+<dt><?php echo T_('Homepage'); ?></dt>
+ <dd><a href="<?php echo $row['homepage']; ?>"><?php echo $row['homepage']; ?></a></dd>
+<?php
+}
+?>
+<dt><?php echo T_('Member Since'); ?></dt>
+ <dd><?php echo date($GLOBALS['longdate'], strtotime($row['uDatetime'])); ?></dd>
+<?php
+if ($row['uContent'] != "") {
+?>
+<dt><?php echo T_('Description'); ?></dt>
+ <dd><?php echo $row['uContent']; ?></dd>
+<?php
+}
+$watching = $userservice->getWatchNames($userid);
+if ($watching) {
+?>
+ <dt><?php echo T_('Watching'); ?></dt>
+ <dd>
+ <?php
+ $list = '';
+ foreach($watching as $watchuser) {
+ $list .= '<a href="'. createURL('bookmarks', $watchuser) .'">'. $watchuser .'</a>, ';
+ }
+ echo substr($list, 0, -2);
+ ?>
+ </dd>
+<?php
+}
+$watchnames = $userservice->getWatchNames($userid, true);
+if ($watchnames) {
+?>
+ <dt><?php echo T_('Watched By'); ?></dt>
+ <dd>
+ <?php
+ $list = '';
+ foreach($watchnames as $watchuser) {
+ $list .= '<a href="'. createURL('bookmarks', $watchuser) .'">'. $watchuser .'</a>, ';
+ }
+ echo substr($list, 0, -2);
+ ?>
+ </dd>
+<?php
+}
+?>
+</dl>
+
+<?php
+$this->includeTemplate($GLOBALS['bottom_include']);
+?> \ No newline at end of file
diff --git a/templates/register.tpl.php b/templates/register.tpl.php
new file mode 100644
index 0000000..7160535
--- /dev/null
+++ b/templates/register.tpl.php
@@ -0,0 +1,40 @@
+<?php
+$this->includeTemplate($GLOBALS['top_include']);
+?>
+
+<script type="text/javascript">
+window.onload = function() {
+ document.getElementById("username").focus();
+}
+</script>
+
+<p><?php echo sprintf(T_('Sign up here to create a free %s account. All the information requested below is required'), $GLOBALS['sitename']); ?>.</p>
+
+<form action="<?php echo $formaction; ?>" method="post">
+<table>
+<tr>
+ <th align="left"><label for="username"><?php echo T_('Username'); ?></label></th>
+ <td><input type="text" id="username" name="username" size="20" class="required" onkeyup="isAvailable(this, '')" /></td>
+ <td id="availability"></td>
+</tr>
+<tr>
+ <th align="left"><label for="password"><?php echo T_('Password'); ?></label></th>
+ <td><input type="password" id="password" name="password" size="20" class="required" /></td>
+ <td></td>
+</tr>
+<tr>
+ <th align="left"><label for="email"><?php echo T_('E-mail'); ?></label></th>
+ <td><input type="text" id="email" name="email" size="40" class="required" /></td>
+ <td></td>
+</tr>
+<tr>
+ <td></td>
+ <td><input type="submit" name="submitted" value="<?php echo T_('Register'); ?>" /></td>
+ <td></td>
+</tr>
+</table>
+</form>
+
+<?php
+$this->includeTemplate($GLOBALS['bottom_include']);
+?> \ No newline at end of file
diff --git a/templates/rss.tpl.php b/templates/rss.tpl.php
new file mode 100644
index 0000000..0f03c06
--- /dev/null
+++ b/templates/rss.tpl.php
@@ -0,0 +1,28 @@
+<?php
+echo '<?xml version="1.0" encoding="UTF-8" ?'.">\n";
+?>
+
+<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
+<channel>
+ <title><?php echo $feedtitle; ?></title>
+ <link><?php echo $feedlink; ?></link>
+ <description><?php echo $feeddescription; ?></description>
+ <ttl>60</ttl>
+
+<?php foreach($bookmarks as $bookmark): ?>
+ <item>
+ <title><?php echo $bookmark['title']; ?></title>
+ <link><?php echo $bookmark['link']; ?></link>
+ <description><?php echo $bookmark['description']; ?></description>
+ <dc:creator><?php echo $bookmark['creator']; ?></dc:creator>
+ <pubDate><?php echo $bookmark['pubdate']; ?></pubDate>
+
+ <?php foreach($bookmark['tags'] as $tag): ?>
+ <category><?php echo $tag; ?></category>
+ <?php endforeach; ?>
+
+ </item>
+<?php endforeach; ?>
+
+</channel>
+</rss> \ No newline at end of file
diff --git a/templates/sidebar.block.common.php b/templates/sidebar.block.common.php
new file mode 100644
index 0000000..205ca1e
--- /dev/null
+++ b/templates/sidebar.block.common.php
@@ -0,0 +1,25 @@
+<?php
+$tagservice =& ServiceFactory::getServiceInstance('TagService');
+$commonTags =& $tagservice->getRelatedTagsByHash($hash);
+$commonTags =& $tagservice->tagCloud($commonTags, 5, 90, 225, 'alphabet_asc');
+
+if ($commonTags && count($commonTags) > 0) {
+?>
+
+<h2><?php echo T_('Popular Tags'); ?></h2>
+<div id="common">
+ <p class="tags">
+ <?php
+ $contents = '';
+ foreach ($commonTags as $row) {
+ $entries = T_ngettext('bookmark', 'bookmarks', $row['bCount']);
+ $contents .= '<a href="'. sprintf($cat_url, $user, filter($row['tag'], 'url')) .'" title="'. $row['bCount'] .' '. $entries .'" rel="tag" style="font-size:'. $row['size'] .'">'. filter($row['tag']) .'</a> ';
+ }
+ echo $contents ."\n";
+ ?>
+ </p>
+</div>
+
+<?php
+}
+?> \ No newline at end of file
diff --git a/templates/sidebar.block.popular.php b/templates/sidebar.block.popular.php
new file mode 100644
index 0000000..fc9703d
--- /dev/null
+++ b/templates/sidebar.block.popular.php
@@ -0,0 +1,31 @@
+<?php
+$tagservice =& ServiceFactory::getServiceInstance('TagService');
+$userservice =& ServiceFactory::getServiceInstance('UserService');
+
+$logged_on_userid = $userservice->getCurrentUserId();
+if ($logged_on_userid === false) {
+ $logged_on_userid = NULL;
+}
+$popularTags =& $tagservice->getPopularTags($userid, $popCount, $logged_on_userid);
+$popularTags =& $tagservice->tagCloud($popularTags, 5, 90, 225, 'alphabet_asc');
+
+if ($popularTags && count($popularTags) > 0) {
+?>
+
+<h2><?php echo T_('Popular Tags'); ?></h2>
+<div id="popular">
+ <p class="tags">
+ <?php
+ $contents = '';
+ foreach ($popularTags as $row) {
+ $entries = T_ngettext('bookmark', 'bookmarks', $row['bCount']);
+ $contents .= '<a href="'. sprintf($cat_url, $user, filter($row['tag'], 'url')) .'" title="'. $row['bCount'] .' '. $entries .'" rel="tag" style="font-size:'. $row['size'] .'">'. filter($row['tag']) .'</a> ';
+ }
+ echo $contents ."\n";
+ ?>
+ </p>
+</div>
+
+<?php
+}
+?> \ No newline at end of file
diff --git a/templates/sidebar.block.profile.php b/templates/sidebar.block.profile.php
new file mode 100644
index 0000000..1b8e915
--- /dev/null
+++ b/templates/sidebar.block.profile.php
@@ -0,0 +1,16 @@
+<?php
+$userservice =& ServiceFactory::getServiceInstance('UserService');
+if (utf8_strlen($userinfo['name']) > 0) {
+ $name = $userinfo['name'];
+} else {
+ $name = $userinfo['username'];
+}
+?>
+<h2><?php echo $name; ?></h2>
+<div id="profile">
+ <ul>
+ <li><a href="<?php echo $userservice->getProfileUrl($userid, $user); ?>"><?php echo T_('Profile'); ?></a> &rarr;</li>
+ <li><a href="<?php echo createURL('alltags', $user); ?>"><?php echo T_('Tags'); ?></a> &rarr;</li>
+ <li><a href="<?php echo createURL('watchlist', $user); ?>"><?php echo T_('Watchlist'); ?></a> &rarr;</li>
+ </ul>
+</div>
diff --git a/templates/sidebar.block.recent.php b/templates/sidebar.block.recent.php
new file mode 100644
index 0000000..f489e49
--- /dev/null
+++ b/templates/sidebar.block.recent.php
@@ -0,0 +1,30 @@
+<?php
+$tagservice =& ServiceFactory::getServiceInstance('TagService');
+$userservice =& ServiceFactory::getServiceInstance('UserService');
+
+$logged_on_userid = $userservice->getCurrentUserId();
+if ($logged_on_userid === false) {
+ $logged_on_userid = NULL;
+}
+$recentTags = $tagservice->getPopularTags($userid, $popCount, $logged_on_userid, $GLOBALS['defaultRecentDays']);
+$recentTags =& $tagservice->tagCloud($recentTags, 5, 90, 225, 'alphabet_asc');
+
+if ($recentTags && count($recentTags) > 0) {
+?>
+
+<h2><?php echo T_('Recent Tags'); ?></h2>
+<div id="recent">
+ <?php
+ $contents = '<p class="tags">';
+ foreach ($recentTags as $row) {
+ $entries = T_ngettext('bookmark', 'bookmarks', $row['bCount']);
+ $contents .= '<a href="'. sprintf($cat_url, $user, filter($row['tag'], 'url')) .'" title="'. $row['bCount'] .' '. $entries .'" rel="tag" style="font-size:'. $row['size'] .'">'. filter($row['tag']) .'</a> ';
+ }
+ echo $contents ."</p>\n";
+ ?>
+ <p><a href="<?php echo createURL('populartags'); ?>"><?php echo T_('Popular Tags'); ?></a> &rarr;</p>
+</div>
+
+<?php
+}
+?> \ No newline at end of file
diff --git a/templates/sidebar.block.related.php b/templates/sidebar.block.related.php
new file mode 100644
index 0000000..3a37718
--- /dev/null
+++ b/templates/sidebar.block.related.php
@@ -0,0 +1,29 @@
+<?php
+$tagservice =& ServiceFactory::getServiceInstance('TagService');
+$userservice =& ServiceFactory::getServiceInstance('UserService');
+
+$logged_on_userid = $userservice->getCurrentUserId();
+if ($logged_on_userid === false) {
+ $logged_on_userid = NULL;
+}
+if ($currenttag) {
+ $relatedTags = $tagservice->getRelatedTags($currenttag, $userid, $logged_on_userid);
+ if (sizeof($relatedTags) > 0) {
+?>
+
+<h2><?php echo T_('Related Tags'); ?></h2>
+<div id="related">
+ <table>
+ <?php foreach($relatedTags as $row): ?>
+ <tr>
+ <td><a href="<?php echo sprintf($cat_url, filter($user, 'url'), filter($currenttag, 'url') .'+'. filter($row['tag'], 'url')); ?>">+</a></td>
+ <td><a href="<?php echo sprintf($cat_url, filter($user, 'url'), filter($row['tag'], 'url')); ?>" rel="tag"><?php echo filter($row['tag']); ?></a></td>
+ </tr>
+ <?php endforeach; ?>
+ </table>
+</div>
+
+<?php
+ }
+}
+?> \ No newline at end of file
diff --git a/templates/sidebar.block.tagactions.php b/templates/sidebar.block.tagactions.php
new file mode 100644
index 0000000..836c40c
--- /dev/null
+++ b/templates/sidebar.block.tagactions.php
@@ -0,0 +1,27 @@
+<?php
+$userservice =& ServiceFactory::getServiceInstance('UserService');
+if ($userservice->isLoggedOn()) {
+ $currentUser = $userservice->getCurrentUser();
+ $currentUsername = $currentUser[$userservice->getFieldName('username')];
+
+ if ($currentUsername == $user) {
+ $tags = explode('+', $currenttag);
+ $renametext = T_ngettext('Rename Tag', 'Rename Tags', count($tags));
+ $renamelink = createURL('tagrename', $currenttag);
+ $deletelink = createURL('tagdelete', $currenttag);
+?>
+
+<h2><?php echo T_('Actions'); ?></h2>
+<div id="tagactions">
+ <ul>
+ <li><a href="<?php echo $renamelink; ?>"><?php echo $renametext ?></a></li>
+ <?php if (count($tags) == 1): ?>
+ <li><a href="<?php echo $deletelink; ?>"><?php echo T_('Delete Tag') ?></a></li>
+ <?php endif; ?>
+ </ul>
+</div>
+
+<?php
+ }
+}
+?> \ No newline at end of file
diff --git a/templates/sidebar.block.watchlist.php b/templates/sidebar.block.watchlist.php
new file mode 100644
index 0000000..e35fa76
--- /dev/null
+++ b/templates/sidebar.block.watchlist.php
@@ -0,0 +1,19 @@
+<?php
+$userservice =& ServiceFactory::getServiceInstance('UserService');
+
+$watching = $userservice->getWatchNames($userid);
+if ($watching) {
+?>
+
+<h2><?php echo T_('Watching'); ?></h2>
+<div id="watching">
+ <ul>
+ <?php foreach($watching as $watchuser): ?>
+ <li><a href="<?php echo createURL('bookmarks', $watchuser); ?>"><?php echo $watchuser; ?></a> &rarr;</li>
+ <?php endforeach; ?>
+ </ul>
+</div>
+
+<?php
+}
+?> \ No newline at end of file
diff --git a/templates/sidebar.block.watchstatus.php b/templates/sidebar.block.watchstatus.php
new file mode 100644
index 0000000..d912846
--- /dev/null
+++ b/templates/sidebar.block.watchstatus.php
@@ -0,0 +1,27 @@
+<?php
+$userservice =& ServiceFactory::getServiceInstance('UserService');
+if ($userservice->isLoggedOn()) {
+ $currentUser = $userservice->getCurrentUser();
+ $currentUsername = $currentUser[$userservice->getFieldName('username')];
+
+ if ($currentUsername != $user) {
+ $result = $userservice->getWatchStatus($userid, $userservice->getCurrentUserId());
+ if ($result) {
+ $linkText = T_('Remove from Watchlist');
+ } else {
+ $linkText = T_('Add to Watchlist');
+ }
+ $linkAddress = createURL('watch', $user);
+?>
+
+<h2><?php echo T_('Actions'); ?></h2>
+<div id="watchlist">
+ <ul>
+ <li><a href="<?php echo $linkAddress ?>"><?php echo $linkText ?></a></li>
+ </ul>
+</div>
+
+<?php
+ }
+}
+?> \ No newline at end of file
diff --git a/templates/sidebar.tpl.php b/templates/sidebar.tpl.php
new file mode 100644
index 0000000..5f399b5
--- /dev/null
+++ b/templates/sidebar.tpl.php
@@ -0,0 +1,13 @@
+<div id="sidebar">
+ <?php
+ $size = count($sidebar_blocks);
+ for ($i = 0; $i < $size; $i++) {
+ $this->includeTemplate('sidebar.block.'. $sidebar_blocks[$i]);
+ }
+
+ $size = count($rsschannels);
+ for ($i = 0; $i < $size; $i++) {
+ echo '<p><a href="'. $rsschannels[$i][1] .'" title="'. $rsschannels[$i][0] .'"><img src="'. $GLOBALS['root'] .'rss.gif" width="16" height="16" alt="'. $rsschannels[$i][0] .'" /></a></p>';
+ }
+ ?>
+</div>
diff --git a/templates/tagdelete.tpl.php b/templates/tagdelete.tpl.php
new file mode 100644
index 0000000..3e9744a
--- /dev/null
+++ b/templates/tagdelete.tpl.php
@@ -0,0 +1,20 @@
+<?php
+$this->includeTemplate($GLOBALS['top_include']);
+?>
+
+<form action="<?= $formaction ?>" method="post">
+<p><?php echo T_('Are you sure?'); ?></p>
+<p>
+ <input type="submit" name="confirm" value="<?php echo T_('Yes'); ?>" />
+ <input type="submit" name="cancel" value="<?php echo T_('No'); ?>" />
+</p>
+
+<?php if (isset($referrer)): ?>
+<div><input type="hidden" name="referrer" value="<?php echo $referrer; ?>" /></div>
+<?php endif; ?>
+
+</form>
+
+<?php
+$this->includeTemplate($GLOBALS['bottom_include']);
+?> \ No newline at end of file
diff --git a/templates/tagrename.tpl.php b/templates/tagrename.tpl.php
new file mode 100644
index 0000000..ea8b516
--- /dev/null
+++ b/templates/tagrename.tpl.php
@@ -0,0 +1,41 @@
+<?php
+$this->includeTemplate($GLOBALS['top_include']);
+?>
+<script type="text/javascript">
+window.onload = function() {
+ document.getElementById("new").focus();
+}
+</script>
+<form action="<?php echo $formaction; ?>" method="post">
+<table>
+<tr>
+ <th align="left"><?php echo T_('Old'); ?></th>
+ <td><input type="text" name="old" id="old" value="<?php echo $old; ?>" /></td>
+ <td>&larr; <?php echo T_('Required'); ?></td>
+</tr>
+<tr>
+ <th align="left"><?php echo T_('New'); ?></th>
+ <td><input type="text" name="new" id="new" value="" /></td>
+ <td>&larr; <?php echo T_('Required'); ?></td>
+</tr>
+<tr>
+ <td></td>
+ <td>
+ <input type="submit" name="confirm" value="<?php echo T_('Rename'); ?>" />
+ <input type="submit" name="cancel" value="<?php echo T_('Cancel'); ?>" />
+ </td>
+ <td></td>
+</tr>
+
+</table>
+</p>
+
+<?php if (isset($referrer)): ?>
+<div><input type="hidden" name="referrer" value="<?php echo $referrer; ?>" /></div>
+<?php endif; ?>
+
+</form>
+
+<?php
+$this->includeTemplate($GLOBALS['bottom_include']);
+?> \ No newline at end of file
diff --git a/templates/tags.tpl.php b/templates/tags.tpl.php
new file mode 100644
index 0000000..7266170
--- /dev/null
+++ b/templates/tags.tpl.php
@@ -0,0 +1,27 @@
+<?php
+$this->includeTemplate($GLOBALS['top_include']);
+if ($tags && count($tags) > 0) {
+?>
+
+<p id="sort">
+ <?php echo T_("Sort by:"); ?>
+ <a href="?sort=alphabet_asc"><?php echo T_("Alphabet"); ?></a><span> / </span>
+ <a href="?sort=popularity_asc"><?php echo T_("Popularity"); ?></a>
+</p>
+<p class="tags">
+
+<?php
+$contents = '';
+foreach ($tags as $row) {
+ $entries = T_ngettext('bookmark', 'bookmarks', $row['bCount']);
+ $contents .= '<a href="'. sprintf($cat_url, $user, filter($row['tag'], 'url')) .'" title="'. $row['bCount'] .' '. $entries .'" rel="tag" style="font-size:'. $row['size'] .'">'. filter($row['tag']) .'</a> ';
+}
+echo $contents ."\n";
+?>
+
+</p>
+
+<?php
+}
+$this->includeTemplate($GLOBALS['bottom_include']);
+?> \ No newline at end of file
diff --git a/templates/toolbar.inc.php b/templates/toolbar.inc.php
new file mode 100644
index 0000000..2eb56ac
--- /dev/null
+++ b/templates/toolbar.inc.php
@@ -0,0 +1,27 @@
+<?php
+$userservice =& ServiceFactory::getServiceInstance('UserService');
+if ($userservice->isLoggedOn()) {
+ $cUser = $userservice->getCurrentUser();
+ $cUsername = $cUser[$userservice->getFieldName('username')];
+?>
+
+ <ul id="navigation">
+ <li><a href="<?php echo createURL('bookmarks', $cUsername); ?>"><?php echo T_('Bookmarks'); ?></a></li>
+ <li><a href="<?php echo createURL('watchlist', $cUsername); ?>"><?php echo T_('Watchlist'); ?></a></li>
+ <li><a href="<?php echo createURL('bookmarks', $cUsername . '?action=add'); ?>"><?php echo T_('Add a Bookmark'); ?></a></li>
+ <li class="access"><a href="<?php echo $GLOBALS['root']; ?>?action=logout"><?php echo T_('Log Out'); ?></a></li>
+ </ul>
+
+<?php
+} else {
+?>
+
+ <ul id="navigation">
+ <li><a href="<?php echo createURL('about'); ?>"><?php echo T_('About'); ?></a></li>
+ <li class="access"><a href="<?php echo createURL('login'); ?>"><?php echo T_('Log In'); ?></a></li>
+ <li class="access"><a href="<?php echo createURL('register'); ?>"><?php echo T_('Register'); ?></a></li>
+ </ul>
+
+<?php
+}
+?>
diff --git a/templates/top.inc.php b/templates/top.inc.php
new file mode 100644
index 0000000..64213fd
--- /dev/null
+++ b/templates/top.inc.php
@@ -0,0 +1,47 @@
+<?php header('Content-Type: text/html; charset=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><?php echo filter($GLOBALS['sitename'] . (isset($pagetitle) ? ': ' . $pagetitle : '')); ?></title>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <link rel="icon" type="image/png" href="<?php echo $GLOBALS['root']; ?>icon.png" />
+ <link rel="stylesheet" type="text/css" href="<?php echo $GLOBALS['root']; ?>scuttle.css" />
+ <?php
+ $size = count($rsschannels);
+ for ($i = 0; $i < $size; $i++) {
+ echo '<link rel="alternate" type="application/rss+xml" title="'. $rsschannels[$i][0] .'" href="'. $rsschannels[$i][1] .'" />';
+ }
+ if ($loadjs) {
+ echo '<script type="text/javascript" src="'. $GLOBALS['root'] .'jsScuttle.php"></script>';
+ }
+ ?>
+</head>
+<body>
+
+<?php
+$headerstyle = '';
+if(isset($_GET['popup'])) {
+ $headerstyle = ' class="popup"';
+}
+?>
+
+<div id="header"<?php echo $headerstyle; ?>>
+ <h1><a href="<?php echo $GLOBALS['root']; ?>"><?php echo $GLOBALS['sitename']; ?></a></h1>
+ <?php
+ if(!isset($_GET['popup'])) {
+ $this->includeTemplate('toolbar.inc');
+ }
+ ?>
+</div>
+
+<?php
+if (isset($subtitle)) {
+ echo '<h2>'. $subtitle ."</h2>\n";
+}
+if (isset($error)) {
+ echo '<p class="error">'. $error ."</p>\n";
+}
+if (isset($msg)) {
+ echo '<p class="success">'. $msg ."</p>\n";
+}
+?>
diff --git a/watch.php b/watch.php
new file mode 100644
index 0000000..6a01e9a
--- /dev/null
+++ b/watch.php
@@ -0,0 +1,56 @@
+<?php
+/***************************************************************************
+Copyright (C) 2004 - 2006 Scuttle project
+http://sourceforge.net/projects/scuttle/
+http://scuttle.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; 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
+***************************************************************************/
+
+require_once('header.inc.php');
+$userservice =& ServiceFactory::getServiceInstance('UserService');
+
+@list($url, $user) = isset($_SERVER['PATH_INFO']) ? explode('/', $_SERVER['PATH_INFO']) : NULL;
+if ($userservice->isLoggedOn() && $user) {
+ $tplVars = array();
+ $pagetitle = '';
+
+ if (is_int($user)) {
+ $userid = intval($user);
+ } else {
+ if (!($userinfo = $userservice->getUserByUsername($user))) {
+ $tplVars['error'] = sprintf(T_('User with username %s was not found'), $user);
+ $templateservice->loadTemplate('error.404.tpl', $tplVars);
+ exit();
+ } else {
+ $userid =& $userinfo['uId'];
+ }
+ }
+
+ $watched = $userservice->getWatchStatus($userid, $userservice->getCurrentUserId());
+ $changed = $userservice->setWatchStatus($userid);
+
+ if ($watched) {
+ $tplVars['msg'] = T_('User removed from your watchlist');
+ } else {
+ $tplVars['msg'] = T_('User added to your watchlist');
+ }
+
+ $currentUser = $userservice->getCurrentUser();
+ $currentUsername = $currentUser[$userservice->getFieldName('username')];
+
+ header('Location: '. createURL('watchlist', $currentUsername));
+}
+?>
diff --git a/watchlist.php b/watchlist.php
new file mode 100644
index 0000000..973263c
--- /dev/null
+++ b/watchlist.php
@@ -0,0 +1,125 @@
+<?php
+/***************************************************************************
+Copyright (C) 2004 - 2006 Scuttle project
+http://sourceforge.net/projects/scuttle/
+http://scuttle.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; 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
+***************************************************************************/
+require_once('header.inc.php');
+
+$bookmarkservice =& ServiceFactory::getServiceInstance('BookmarkService');
+$templateservice =& ServiceFactory::getServiceInstance('TemplateService');
+$userservice =& ServiceFactory::getServiceInstance('UserService');
+$cacheservice =& ServiceFactory::getServiceInstance('CacheService');
+
+$tplVars = array();
+
+@list($url, $user, $page) = isset($_SERVER['PATH_INFO']) ? explode('/', $_SERVER['PATH_INFO']) : NULL;
+
+$loggedon = false;
+if ($userservice->isLoggedOn()) {
+ $loggedon = true;
+ $currentUser = $userservice->getCurrentUser();
+ $currentUsername = $currentUser[$userservice->getFieldName('username')];
+}
+
+if ($usecache) {
+ // Generate hash for caching on
+ if ($loggedon) {
+ if ($currentUsername != $user) {
+ $cachehash = md5($_SERVER['REQUEST_URI'] . $currentUsername);
+
+ // Cache for 5 minutes
+ $cacheservice->Start($cachehash);
+ }
+ } else {
+ // Cache for 30 minutes
+ $cachehash = md5($_SERVER['REQUEST_URI']);
+ $cacheservice->Start($cachehash, 1800);
+ }
+}
+
+if ($user) {
+ if (is_int($user)) {
+ $userid = intval($user);
+ } else {
+ if (!($userinfo = $userservice->getUserByUsername($user) ) ) {
+ // Throw a 404 error
+ $tplVars['error'] = sprintf(T_('User with username %s was not found'), $user);
+ $templateservice->loadTemplate('error.404.tpl', $tplVars);
+ exit();
+ } else {
+ $userid =& $userinfo['uId'];
+ }
+ }
+}
+
+// Header variables
+$tplVars['loadjs'] = true;
+
+if ($user) {
+ $tplVars['user'] = $user;
+ $tplVars['userid'] = $userid;
+ $tplVars['userinfo'] =& $userinfo;
+
+ // Pagination
+ $perpage = getPerPageCount();
+ if (isset($_GET['page']) && intval($_GET['page']) > 1) {
+ $page = $_GET['page'];
+ $start = ($page - 1) * $perpage;
+ } else {
+ $page = 0;
+ $start = 0;
+ }
+
+ // Set template vars
+ $tplVars['page'] = $page;
+ $tplVars['start'] = $start;
+ $tplVars['bookmarkCount'] = $start + 1;
+
+ $bookmarks =& $bookmarkservice->getBookmarks($start, $perpage, $userid, NULL, NULL, getSortOrder(), true);
+
+ $tplVars['sidebar_blocks'] = array('watchlist');
+ $tplVars['watched'] = true;
+ $tplVars['total'] = $bookmarks['total'];
+ $tplVars['bookmarks'] =& $bookmarks['bookmarks'];
+ $tplVars['cat_url'] = createURL('tags', '%2$s');
+ $tplVars['nav_url'] = createURL('watchlist', '%s/%s%s');
+
+ if ($user == $currentUsername) {
+ $title = T_('My Watchlist');
+ } else {
+ $title = T_('Watchlist') .': '. $user;
+ }
+ $tplVars['pagetitle'] = $title;
+ $tplVars['subtitle'] = $title;
+
+ $tplVars['rsschannels'] = array(
+ array(filter($sitename .': '. $title), createURL('rss', 'watchlist/'. filter($user, 'url')))
+ );
+
+ $templateservice->loadTemplate('bookmarks.tpl', $tplVars);
+} else {
+ $tplVars['error'] = T_('Username was not specified');
+ $templateservice->loadTemplate('error.404.tpl', $tplVars);
+ exit();
+}
+
+if ($usecache) {
+ // Cache output if existing copy has expired
+ $cacheservice->End($hash);
+}
+?>